diff --git a/README.md b/README.md index 78a7fe5..0173359 100644 --- a/README.md +++ b/README.md @@ -175,3 +175,8 @@ php artisan test --compact ## License MIT + +## Documentation Notes + +- Documentation screenshots are generated for all admin and user pages. +- cPanel Migration tabs (Domains, Databases, Mailboxes, Forwarders, SSL) only render after a backup is analyzed. Provide a sample cPanel backup to capture those tab screenshots. diff --git a/VERSION b/VERSION index a87052a..3cf2e50 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -VERSION=0.9-rc53 +VERSION=0.9-rc54 diff --git a/app/BackupSchedule.php b/app/BackupSchedule.php new file mode 100644 index 0000000..0dbafb9 --- /dev/null +++ b/app/BackupSchedule.php @@ -0,0 +1,235 @@ + 'boolean', + 'is_server_backup' => 'boolean', + 'include_files' => 'boolean', + 'include_databases' => 'boolean', + 'include_mailboxes' => 'boolean', + 'include_dns' => 'boolean', + 'domains' => 'array', + 'databases' => 'array', + 'mailboxes' => 'array', + 'users' => 'array', + 'metadata' => 'array', + 'retention_count' => 'integer', + 'day_of_week' => 'integer', + 'day_of_month' => 'integer', + 'last_run_at' => 'datetime', + 'next_run_at' => 'datetime', + ]; + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function destination(): BelongsTo + { + return $this->belongsTo(BackupDestination::class, 'destination_id'); + } + + public function backups(): HasMany + { + return $this->hasMany(Backup::class, 'schedule_id'); + } + + /** + * Check if the schedule should run now. + */ + public function shouldRun(): bool + { + if (! $this->is_active) { + return false; + } + + if (! $this->next_run_at) { + return true; + } + + return $this->next_run_at->isPast(); + } + + /** + * Calculate and set the next run time. + */ + public function calculateNextRun(): Carbon + { + $timezone = $this->getSystemTimezone(); + $now = Carbon::now($timezone); + $time = explode(':', $this->time); + $hour = (int) ($time[0] ?? 2); + $minute = (int) ($time[1] ?? 0); + + $next = $now->copy()->setTime($hour, $minute, 0); + + // If time already passed today, start from tomorrow + if ($next->isPast()) { + $next->addDay(); + } + + switch ($this->frequency) { + case 'hourly': + $next = $now->copy()->addHour()->startOfHour(); + break; + + case 'daily': + // Already set to next occurrence + break; + + case 'weekly': + $targetDay = $this->day_of_week ?? 0; // Default to Sunday + while ($next->dayOfWeek !== $targetDay) { + $next->addDay(); + } + break; + + case 'monthly': + $targetDay = $this->day_of_month ?? 1; + $next->day = min($targetDay, $next->daysInMonth); + if ($next->isPast()) { + $next->addMonth(); + $next->day = min($targetDay, $next->daysInMonth); + } + break; + } + + $nextUtc = $next->copy()->setTimezone('UTC'); + $this->attributes['next_run_at'] = $nextUtc->format($this->getDateFormat()); + + return $nextUtc; + } + + /** + * Get frequency label for UI. + */ + public function getFrequencyLabelAttribute(): string + { + $base = match ($this->frequency) { + 'hourly' => 'Every hour', + 'daily' => 'Daily at '.$this->time, + 'weekly' => 'Weekly on '.$this->getDayName().' at '.$this->time, + 'monthly' => 'Monthly on day '.($this->day_of_month ?? 1).' at '.$this->time, + default => ucfirst($this->frequency), + }; + + return $base; + } + + /** + * Get day name for weekly schedules. + */ + protected function getDayName(): string + { + $days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; + + return $days[$this->day_of_week ?? 0]; + } + + protected function getSystemTimezone(): string + { + static $timezone = null; + if ($timezone === null) { + $timezone = trim((string) @file_get_contents('/etc/timezone')); + if ($timezone === '') { + $timezone = trim((string) @shell_exec('timedatectl show -p Timezone --value 2>/dev/null')); + } + if ($timezone === '') { + $timezone = 'UTC'; + } + } + + return $timezone; + } + + /** + * Scope for active schedules. + */ + public function scopeActive($query) + { + return $query->where('is_active', true); + } + + /** + * Scope for due schedules. + */ + public function scopeDue($query) + { + return $query->active() + ->where(function ($q) { + $q->whereNull('next_run_at') + ->orWhere('next_run_at', '<=', now()); + }); + } + + /** + * Scope for user schedules. + */ + public function scopeForUser($query, int $userId) + { + return $query->where('user_id', $userId); + } + + /** + * Scope for server backup schedules. + */ + public function scopeServerBackups($query) + { + return $query->where('is_server_backup', true); + } + + /** + * Get last status color for UI. + */ + public function getLastStatusColorAttribute(): string + { + return match ($this->last_status) { + 'success' => 'success', + 'failed' => 'danger', + default => 'gray', + }; + } +} diff --git a/app/Backups.php b/app/Backups.php new file mode 100644 index 0000000..a77c36f --- /dev/null +++ b/app/Backups.php @@ -0,0 +1,1616 @@ +activeTab = $this->normalizeTabName($this->activeTab); + } + + protected function normalizeTabName(?string $tab): string + { + return match ($tab) { + 'destinations', 'schedules', 'backups' => $tab, + default => 'destinations', + }; + } + + public function setTab(string $tab): void + { + $this->activeTab = $this->normalizeTabName($tab); + $this->resetTable(); + } + + public function updatedActiveTab(): void + { + $this->activeTab = $this->normalizeTabName($this->activeTab); + $this->resetTable(); + } + + protected function getForms(): array + { + return [ + 'backupsForm', + ]; + } + + public function backupsForm(Schema $schema): Schema + { + return $schema + ->schema([ + Section::make(__('Recommendation')) + ->description(__('Use Incremental Backups for scheduled server backups. They only store changes since the last backup, significantly reducing storage space and backup time while maintaining full restore capability.')) + ->icon('heroicon-o-light-bulb') + ->iconColor('info') + ->collapsed(false) + ->collapsible(false), + Tabs::make(__('Backup Sections')) + ->contained() + ->livewireProperty('activeTab') + ->tabs([ + 'destinations' => Tab::make(__('Destinations')) + ->icon('heroicon-o-server-stack') + ->schema([ + View::make('filament.admin.pages.backups-tab-table'), + ]), + 'schedules' => Tab::make(__('Schedules')) + ->icon('heroicon-o-calendar-days') + ->schema([ + View::make('filament.admin.pages.backups-tab-table'), + ]), + 'backups' => Tab::make(__('Backups')) + ->icon('heroicon-o-archive-box') + ->schema([ + View::make('filament.admin.pages.backups-tab-table'), + ]), + ]), + ]); + } + + public function getAgent(): AgentClient + { + return $this->agent ??= new AgentClient; + } + + protected function supportsIncremental($destinationId): bool + { + if (empty($destinationId)) { + return false; + } + + $destination = BackupDestination::find($destinationId); + if (! $destination) { + return false; + } + + return in_array($destination->type, ['sftp', 'nfs']); + } + + public function table(Table $table): Table + { + return match ($this->activeTab) { + 'destinations' => $this->destinationsTable($table), + 'schedules' => $this->schedulesTable($table), + 'backups' => $this->backupsTable($table), + default => $this->destinationsTable($table), + }; + } + + protected function destinationsTable(Table $table): Table + { + return $table + ->query(BackupDestination::query()->where('is_server_backup', true)->orderBy('name')) + ->columns([ + TextColumn::make('name') + ->label(__('Name')) + ->weight('medium') + ->description(fn (BackupDestination $record): ?string => $record->is_default ? __('Default') : null) + ->searchable(), + TextColumn::make('type') + ->label(__('Type')) + ->badge() + ->formatStateUsing(fn (string $state): string => strtoupper($state)) + ->color(fn (string $state): string => match ($state) { + 'sftp' => 'info', + 'nfs' => 'warning', + 's3' => 'success', + default => 'gray', + }), + TextColumn::make('test_status') + ->label(__('Status')) + ->badge() + ->formatStateUsing(fn (?string $state): string => match ($state) { + 'success' => __('Connected'), + 'failed' => __('Failed'), + default => __('Not Tested'), + }) + ->color(fn (?string $state): string => match ($state) { + 'success' => 'success', + 'failed' => 'danger', + default => 'gray', + }), + TextColumn::make('last_tested_at') + ->label(__('Last Tested')) + ->since() + ->placeholder(__('Never')) + ->color('gray'), + ]) + ->recordActions([ + Action::make('test') + ->label(__('Test')) + ->icon('heroicon-o-check-circle') + ->color('success') + ->size('sm') + ->action(fn (BackupDestination $record) => $this->testDestination($record->id)), + Action::make('delete') + ->label(__('Delete')) + ->icon('heroicon-o-trash') + ->color('danger') + ->size('sm') + ->requiresConfirmation() + ->action(fn (BackupDestination $record) => $this->deleteDestination($record->id)), + ]) + ->emptyStateHeading(__('No remote destinations configured')) + ->emptyStateDescription(__('Click "Add Destination" to configure SFTP, NFS, or S3 storage')) + ->emptyStateIcon('heroicon-o-server-stack') + ->striped(); + } + + protected function schedulesTable(Table $table): Table + { + return $table + ->query(BackupSchedule::query()->where('is_server_backup', true)->with('destination')->orderBy('name')) + ->columns([ + TextColumn::make('name') + ->label(__('Name')) + ->weight('medium') + ->searchable(), + TextColumn::make('frequency_label') + ->label(__('Frequency')), + TextColumn::make('destination.name') + ->label(__('Destination')) + ->placeholder(__('Local')), + TextColumn::make('retention_count') + ->label(__('Retention')) + ->formatStateUsing(fn (int $state): string => $state.' '.__('backups')), + TextColumn::make('last_run_at') + ->label(__('Last Run')) + ->since() + ->dateTimeTooltip('M j, Y H:i T', timezone: $this->getSystemTimezone()) + ->placeholder(__('Never')) + ->color('gray'), + TextColumn::make('next_run_at') + ->label(__('Next Run')) + ->since() + ->dateTimeTooltip('M j, Y H:i T', timezone: $this->getSystemTimezone()) + ->placeholder(__('Not scheduled')) + ->color('gray'), + ViewColumn::make('status') + ->label(__('Status')) + ->view('filament.admin.columns.schedule-status'), + ]) + ->recordActions([ + Action::make('run') + ->label(__('Run')) + ->icon('heroicon-o-play') + ->color('gray') + ->size('sm') + ->visible(fn (BackupSchedule $record): bool => ! Backup::where('schedule_id', $record->id)->running()->exists()) + ->action(fn (BackupSchedule $record) => $this->runScheduleNow($record->id)), + Action::make('stop') + ->label(__('Stop')) + ->icon('heroicon-o-stop') + ->color('danger') + ->size('sm') + ->visible(fn (BackupSchedule $record): bool => Backup::where('schedule_id', $record->id)->running()->exists()) + ->requiresConfirmation() + ->action(fn (BackupSchedule $record) => $this->stopScheduleBackup($record->id)), + Action::make('edit') + ->label(__('Edit')) + ->icon('heroicon-o-pencil') + ->color('gray') + ->size('sm') + ->action(fn (BackupSchedule $record) => $this->mountAction('editSchedule', ['id' => $record->id])), + Action::make('toggle') + ->label(fn (BackupSchedule $record): string => $record->is_active ? __('Disable') : __('Enable')) + ->icon(fn (BackupSchedule $record): string => $record->is_active ? 'heroicon-o-pause' : 'heroicon-o-play') + ->color('gray') + ->size('sm') + ->action(fn (BackupSchedule $record) => $this->toggleSchedule($record->id)), + Action::make('delete') + ->label(__('Delete')) + ->icon('heroicon-o-trash') + ->color('danger') + ->size('sm') + ->requiresConfirmation() + ->action(fn (BackupSchedule $record) => $this->deleteSchedule($record->id)), + ]) + ->headerActions([ + $this->addScheduleAction(), + ]) + ->emptyStateHeading(__('No backup schedules configured')) + ->emptyStateDescription(__('Click "Add Schedule" to set up automatic backups')) + ->emptyStateIcon('heroicon-o-clock') + ->striped() + ->poll(fn () => Backup::running()->exists() ? '3s' : null); + } + + protected function backupsTable(Table $table): Table + { + return $table + ->query(Backup::query()->where('type', 'server')->with(['destination', 'user'])->orderByDesc('created_at')->limit(50)) + ->columns([ + TextColumn::make('name') + ->label(__('Name')) + ->weight('medium') + ->searchable() + ->limit(40), + ViewColumn::make('status') + ->label(__('Status')) + ->view('filament.admin.columns.backup-status'), + TextColumn::make('size_bytes') + ->label(__('Size')) + ->formatStateUsing(fn (Backup $record): string => $record->size_human), + TextColumn::make('destination.name') + ->label(__('Destination')) + ->placeholder(__('Local')), + TextColumn::make('created_at') + ->label(__('Created')) + ->dateTime('M j, Y H:i') + ->color('gray'), + TextColumn::make('duration') + ->label(__('Duration')) + ->placeholder('-') + ->color('gray'), + ]) + ->recordActions([ + Action::make('restore') + ->label(__('Restore')) + ->icon('heroicon-o-arrow-path') + ->color('warning') + ->size('sm') + ->visible(fn (Backup $record): bool => $record->status === 'completed' && ($record->local_path || $record->remote_path)) + ->modalHeading(__('Restore Backup')) + ->modalDescription(__('Select what you want to restore. Warning: Existing data may be overwritten.')) + ->modalWidth('xl') + ->form(function (Backup $record): array { + // Check if this is a remote backup (no local files) + $isRemoteBackup = ! $record->local_path || ! file_exists($record->local_path); + + $manifest = $this->getBackupManifest($record); + $users = $manifest['users'] ?? $record->users ?? []; + if (empty($users)) { + $users = [$manifest['username'] ?? '']; + } + $users = array_filter($users); + + $isServerBackup = ($manifest['type'] ?? $record->type) === 'server' && count($users) > 1; + + // For server backups, get data for first user by default + $selectedUser = $users[0] ?? ''; + if ($isServerBackup && ! empty($selectedUser) && ! $isRemoteBackup) { + $manifest = $this->getBackupManifest($record, $selectedUser); + } + + // For remote backups, use include_* flags from record + if ($isRemoteBackup) { + $hasFiles = $record->include_files ?? true; + $hasDatabases = $record->include_databases ?? true; + $hasMailboxes = $record->include_mailboxes ?? true; + $hasDns = $record->include_dns ?? true; + $hasSsl = true; // Assume SSL is included + $domains = []; + $databases = []; + $mailboxes = []; + } else { + $domains = $manifest['domains'] ?? []; + $databases = $manifest['databases'] ?? []; + $mailboxes = $manifest['mailboxes'] ?? []; + $hasFiles = ! empty($domains); + $hasDatabases = ! empty($databases); + $hasMailboxes = ! empty($mailboxes); + $hasDns = ! empty($manifest['dns_zones'] ?? []); + $hasSsl = ! empty($manifest['ssl_certificates'] ?? []); + } + + $schema = []; + + // Backup info section + $infoSchema = [ + TextInput::make('backup_name') + ->label(__('Backup')) + ->default($record->name) + ->disabled(), + ]; + + // Add user selector for server backups with multiple users + if ($isServerBackup || count($users) > 1) { + $userOptions = [ + '__all__' => __('All users'), + ]; + foreach ($users as $userOption) { + $userOptions[$userOption] = $userOption; + } + $infoSchema[] = Select::make('restore_username') + ->label(__('User to Restore')) + ->options($userOptions) + ->default($selectedUser) + ->required() + ->helperText(__('Backup contains :count user(s)', ['count' => count($users)])); + } else { + $infoSchema[] = TextInput::make('restore_username') + ->label(__('User')) + ->default($selectedUser) + ->disabled(); + } + + $schema[] = Section::make(__('Backup Information')) + ->schema([Grid::make(2)->schema($infoSchema)]); + + // Remote backup notice + if ($isRemoteBackup) { + $schema[] = Section::make(__('Remote Backup')) + ->description(__('This backup will be downloaded from the remote destination before restoring.')) + ->icon('heroicon-o-cloud-arrow-down') + ->iconColor('info'); + } + + // Restore options section + $restoreOptions = []; + + // Website Files + $filesLabel = __('Website Files'); + if (! $isRemoteBackup && ! empty($domains)) { + $filesLabel .= ' ('.count($domains).')'; + } + $restoreOptions[] = Toggle::make('restore_files') + ->label($filesLabel) + ->helperText($isRemoteBackup + ? __('Restore all domain files') + : (! empty($domains) ? implode(', ', array_slice($domains, 0, 3)).(count($domains) > 3 ? '...' : '') : __('No files'))) + ->default($hasFiles) + ->disabled(! $hasFiles && ! $isRemoteBackup); + + if (! $isRemoteBackup && count($domains) > 1) { + $restoreOptions[] = Select::make('selected_domains') + ->label(__('Specific Domains')) + ->multiple() + ->options(fn () => array_combine($domains, $domains)) + ->placeholder(__('All domains')) + ->visible(fn ($get) => $get('restore_files')); + } + + // Databases + $dbLabel = __('Databases'); + if (! $isRemoteBackup && ! empty($databases)) { + $dbLabel .= ' ('.count($databases).')'; + } + $restoreOptions[] = Toggle::make('restore_databases') + ->label($dbLabel) + ->helperText($isRemoteBackup + ? __('Restore all databases') + : (! empty($databases) ? implode(', ', array_slice($databases, 0, 3)).(count($databases) > 3 ? '...' : '') : __('No databases'))) + ->default($hasDatabases) + ->disabled(! $hasDatabases && ! $isRemoteBackup); + + if (! $isRemoteBackup && count($databases) > 1) { + $restoreOptions[] = Select::make('selected_databases') + ->label(__('Specific Databases')) + ->multiple() + ->options(fn () => array_combine($databases, $databases)) + ->placeholder(__('All databases')) + ->visible(fn ($get) => $get('restore_databases')); + } + + // MySQL Users + $restoreOptions[] = Toggle::make('restore_mysql_users') + ->label(__('MySQL Users')) + ->default($hasDatabases) + ->helperText(__('Restore MySQL users and their permissions')); + + // Mailboxes + $mailLabel = __('Mailboxes'); + if (! $isRemoteBackup && ! empty($mailboxes)) { + $mailLabel .= ' ('.count($mailboxes).')'; + } + $restoreOptions[] = Toggle::make('restore_mailboxes') + ->label($mailLabel) + ->helperText($isRemoteBackup + ? __('Restore all mailboxes') + : (! empty($mailboxes) ? implode(', ', array_slice($mailboxes, 0, 3)).(count($mailboxes) > 3 ? '...' : '') : __('No mailboxes'))) + ->default($hasMailboxes) + ->disabled(! $hasMailboxes && ! $isRemoteBackup); + + // SSL Certificates + $restoreOptions[] = Toggle::make('restore_ssl') + ->label(__('SSL Certificates')) + ->default(false) + ->helperText(__('Restore SSL certificates for domains')); + + // DNS Zones + $restoreOptions[] = Toggle::make('restore_dns') + ->label(__('DNS Zones')) + ->default($hasDns) + ->helperText(__('Restore DNS zone files')); + + $schema[] = Section::make(__('Restore Options')) + ->description(__('Toggle items you want to restore.')) + ->schema($restoreOptions); + + return $schema; + }) + ->action(function (array $data, Backup $record): void { + $this->executeRestore($record, $data); + }) + ->modalSubmitActionLabel(__('Restore')) + ->requiresConfirmation(), + Action::make('download') + ->label(__('Download')) + ->icon('heroicon-o-arrow-down-tray') + ->color('gray') + ->size('sm') + ->visible(fn (Backup $record): bool => $record->canDownload()) + ->url(fn (Backup $record): string => route('filament.admin.pages.backup-download', ['id' => $record->id])) + ->openUrlInNewTab(), + Action::make('delete') + ->label(__('Delete')) + ->icon('heroicon-o-trash') + ->color('danger') + ->size('sm') + ->requiresConfirmation() + ->action(fn (Backup $record) => $this->deleteBackup($record->id)), + ]) + ->emptyStateHeading(__('No server backups yet')) + ->emptyStateDescription(__('Click "Create Server Backup" to create your first backup')) + ->emptyStateIcon('heroicon-o-archive-box') + ->striped() + ->poll(fn () => Backup::whereIn('status', ['pending', 'running', 'uploading'])->exists() ? '3s' : null); + } + + public function getTableRecordKey(Model|array $record): string + { + return is_array($record) ? (string) $record['id'] : (string) $record->getKey(); + } + + protected function getHeaderActions(): array + { + return [ + Action::make('createServerBackup') + ->label(__('Create Server Backup')) + ->icon('heroicon-o-archive-box-arrow-down') + ->color('primary') + ->form([ + TextInput::make('name') + ->label(__('Backup Name')) + ->default(fn () => __('Server Backup').' '.now()->format('Y-m-d H:i')) + ->required(), + Select::make('destination_id') + ->label(__('Destination')) + ->options(fn () => BackupDestination::where('is_server_backup', true) + ->where('is_active', true) + ->pluck('name', 'id') + ->prepend(__('Local Storage'), '')) + ->default('') + ->live() + ->afterStateUpdated(fn ($set, $state) => $set('backup_type', $this->supportsIncremental($state) ? 'incremental' : 'full')), + Radio::make('backup_type') + ->label(__('Backup Type')) + ->options(fn ($get) => $this->supportsIncremental($get('destination_id')) + ? [ + 'incremental' => __('Incremental (rsync) - Space-efficient'), + 'full' => __('Full (tar.gz) - Complete archive'), + ] + : [ + 'full' => __('Full (tar.gz) - Complete archive'), + ]) + ->default('full') + ->required(), + TextInput::make('local_path') + ->label(__('Local Backup Folder')) + ->default('/var/backups/jabali') + ->visible(fn ($get) => empty($get('destination_id'))), + Section::make(__('Include')) + ->schema([ + Grid::make(2)->schema([ + Toggle::make('include_files')->label(__('Website Files'))->default(true), + Toggle::make('include_databases')->label(__('Databases'))->default(true), + Toggle::make('include_mailboxes')->label(__('Mailboxes'))->default(true), + Toggle::make('include_dns')->label(__('DNS Records'))->default(true), + ]), + ]), + Select::make('users') + ->label(__('Users to Backup')) + ->multiple() + ->options(fn () => User::where('is_admin', false) + ->where('is_active', true) + ->pluck('username', 'username')) + ->placeholder(__('All Users')), + ]) + ->action(function (array $data) { + $this->createServerBackup($data); + }), + + $this->createUserBackupAction(), + + Action::make('addDestination') + ->label(__('Add Destination')) + ->icon('heroicon-o-plus') + ->color('gray') + ->form($this->getDestinationForm()) + ->action(function (array $data) { + $this->saveDestination($data); + }), + ]; + } + + protected function getDestinationForm(): array + { + return [ + TextInput::make('name') + ->label(__('Destination Name')) + ->required(), + Select::make('type') + ->label(__('Type')) + ->options([ + 'sftp' => __('SFTP Server'), + 'nfs' => __('NFS Mount'), + 's3' => __('S3-Compatible Storage'), + ]) + ->required() + ->live(), + + Section::make(__('SFTP Settings')) + ->visible(fn ($get) => $get('type') === 'sftp') + ->schema([ + Grid::make(2)->schema([ + TextInput::make('host')->label(__('Host'))->required(), + TextInput::make('port')->label(__('Port'))->numeric()->default(22), + ]), + TextInput::make('username')->label(__('Username'))->required(), + TextInput::make('password')->label(__('Password'))->password(), + Textarea::make('private_key')->label(__('Private Key (SSH)'))->rows(4), + TextInput::make('path')->label(__('Remote Path'))->default('/backups'), + ]), + + Section::make(__('NFS Settings')) + ->visible(fn ($get) => $get('type') === 'nfs') + ->schema([ + TextInput::make('server')->label(__('NFS Server'))->required(), + TextInput::make('share')->label(__('Share Path'))->required(), + TextInput::make('path')->label(__('Sub-directory'))->default(''), + ]), + + Section::make(__('S3-Compatible Settings')) + ->visible(fn ($get) => $get('type') === 's3') + ->schema([ + TextInput::make('endpoint')->label(__('Endpoint URL')), + TextInput::make('bucket')->label(__('Bucket Name'))->required(), + Grid::make(2)->schema([ + TextInput::make('access_key')->label(__('Access Key ID'))->required(), + TextInput::make('secret_key')->label(__('Secret Access Key'))->password()->required(), + ]), + TextInput::make('region')->label(__('Region'))->default('us-east-1'), + TextInput::make('path')->label(__('Path Prefix'))->default('backups'), + ]), + + Toggle::make('is_default')->label(__('Set as Default Destination')), + + FormActions::make([ + Action::make('testConnection') + ->label(__('Test Connection')) + ->icon('heroicon-o-signal') + ->color('gray') + ->action(function ($get, $livewire) { + $type = $get('type'); + if (empty($type)) { + Notification::make() + ->title(__('Select a destination type first')) + ->warning() + ->send(); + + return; + } + + $config = match ($type) { + 'sftp' => [ + 'type' => 'sftp', + 'host' => $get('host') ?? '', + 'port' => (int) ($get('port') ?? 22), + 'username' => $get('username') ?? '', + 'password' => $get('password') ?? '', + 'private_key' => $get('private_key') ?? '', + 'path' => $get('path') ?? '/backups', + ], + 'nfs' => [ + 'type' => 'nfs', + 'server' => $get('server') ?? '', + 'share' => $get('share') ?? '', + 'path' => $get('path') ?? '', + ], + 's3' => [ + 'type' => 's3', + 'endpoint' => $get('endpoint') ?? '', + 'bucket' => $get('bucket') ?? '', + 'access_key' => $get('access_key') ?? '', + 'secret_key' => $get('secret_key') ?? '', + 'region' => $get('region') ?? 'us-east-1', + 'path' => $get('path') ?? 'backups', + ], + default => [], + }; + + if (empty($config)) { + Notification::make() + ->title(__('Invalid destination type')) + ->danger() + ->send(); + + return; + } + + try { + $result = $livewire->getAgent()->backupTestDestination($config); + if ($result['success']) { + Notification::make() + ->title(__('Connection successful')) + ->body(__('The destination is reachable and ready to use.')) + ->success() + ->send(); + } else { + Notification::make() + ->title(__('Connection failed')) + ->body($result['error'] ?? __('Could not connect to destination')) + ->danger() + ->send(); + } + } catch (Exception $e) { + Notification::make() + ->title(__('Connection test failed')) + ->body($e->getMessage()) + ->danger() + ->send(); + } + }), + ])->visible(fn ($get) => ! empty($get('type'))), + ]; + } + + public function saveDestination(array $data): void + { + $config = []; + $type = $data['type']; + + switch ($type) { + case 'sftp': + $config = [ + 'host' => $data['host'] ?? '', + 'port' => (int) ($data['port'] ?? 22), + 'username' => $data['username'] ?? '', + 'password' => $data['password'] ?? '', + 'private_key' => $data['private_key'] ?? '', + 'path' => $data['path'] ?? '/backups', + ]; + break; + + case 'nfs': + $config = [ + 'server' => $data['server'] ?? '', + 'share' => $data['share'] ?? '', + 'path' => $data['path'] ?? '', + ]; + break; + + case 's3': + $config = [ + 'endpoint' => $data['endpoint'] ?? '', + 'bucket' => $data['bucket'] ?? '', + 'access_key' => $data['access_key'] ?? '', + 'secret_key' => $data['secret_key'] ?? '', + 'region' => $data['region'] ?? 'us-east-1', + 'path' => $data['path'] ?? 'backups', + ]; + break; + } + + $testConfig = array_merge($config, ['type' => $type]); + try { + $result = $this->getAgent()->backupTestDestination($testConfig); + if (! $result['success']) { + Notification::make() + ->title(__('Connection failed')) + ->body($result['error'] ?? __('Could not connect to destination')) + ->danger() + ->send(); + + return; + } + } catch (Exception $e) { + Notification::make() + ->title(__('Connection test failed')) + ->body($e->getMessage()) + ->danger() + ->send(); + + return; + } + + BackupDestination::create([ + 'name' => $data['name'], + 'type' => $type, + 'config' => $config, + 'is_server_backup' => true, + 'is_default' => $data['is_default'] ?? false, + 'is_active' => true, + 'last_tested_at' => now(), + 'test_status' => 'success', + ]); + + Notification::make()->title(__('Destination verified and added'))->success()->send(); + $this->resetTable(); + } + + public function testDestination(int $id): void + { + $destination = BackupDestination::find($id); + if (! $destination) { + return; + } + + try { + $config = array_merge($destination->config ?? [], ['type' => $destination->type]); + $result = $this->getAgent()->backupTestDestination($config); + + $destination->update([ + 'last_tested_at' => now(), + 'test_status' => $result['success'] ? 'success' : 'failed', + 'test_message' => $result['message'] ?? $result['error'] ?? null, + ]); + + if ($result['success']) { + Notification::make()->title(__('Connection successful'))->success()->send(); + } else { + Notification::make()->title(__('Connection failed'))->body($result['error'] ?? __('Unknown error'))->danger()->send(); + } + } catch (Exception $e) { + $destination->update([ + 'last_tested_at' => now(), + 'test_status' => 'failed', + 'test_message' => $e->getMessage(), + ]); + Notification::make()->title(__('Test failed'))->body($e->getMessage())->danger()->send(); + } + + $this->resetTable(); + } + + public function deleteDestination(int $id): void + { + BackupDestination::where('id', $id)->delete(); + Notification::make()->title(__('Destination deleted'))->success()->send(); + $this->resetTable(); + } + + public function createServerBackup(array $data): void + { + $backupType = $data['backup_type'] ?? 'full'; + $timestamp = now()->format('Y-m-d_His'); + $folderName = $timestamp; + $baseFolder = rtrim($data['local_path'] ?? '/var/backups/jabali', '/'); + $outputPath = "{$baseFolder}/{$folderName}"; + + $isIncrementalRemote = $backupType === 'incremental' && ! empty($data['destination_id']); + + if ($isIncrementalRemote) { + $destination = BackupDestination::find($data['destination_id']); + if (! $destination || ! in_array($destination->type, ['sftp', 'nfs'])) { + Notification::make() + ->title(__('Invalid destination')) + ->body(__('Incremental backups require an SFTP or NFS destination')) + ->danger() + ->send(); + + return; + } + } + + // Create backup record with pending status + $backup = Backup::create([ + 'name' => $data['name'], + 'filename' => $folderName, + 'type' => 'server', + 'include_files' => $data['include_files'] ?? true, + 'include_databases' => $data['include_databases'] ?? true, + 'include_mailboxes' => $data['include_mailboxes'] ?? true, + 'include_dns' => $data['include_dns'] ?? true, + 'users' => ! empty($data['users']) ? $data['users'] : null, + 'destination_id' => ! empty($data['destination_id']) ? $data['destination_id'] : null, + 'schedule_id' => $data['schedule_id'] ?? null, + 'status' => 'pending', + 'local_path' => $isIncrementalRemote ? null : $outputPath, + 'metadata' => ['backup_type' => $backupType], + ]); + + // Dispatch job to run backup in background + \App\Jobs\RunServerBackup::dispatch($backup->id); + + // Show notification and refresh table + Notification::make() + ->title(__('Backup started')) + ->body(__('The backup is running in the background. The status will update automatically.')) + ->info() + ->send(); + + $this->resetTable(); + } + + protected function uploadToRemote(Backup $backup, bool $keepLocal = false): bool + { + if (! $backup->destination || ! $backup->local_path) { + return false; + } + + try { + $backup->update(['status' => 'uploading']); + + $config = array_merge($backup->destination->config ?? [], ['type' => $backup->destination->type]); + $backupType = $backup->metadata['backup_type'] ?? 'full'; + $result = $this->getAgent()->backupUploadRemote($backup->local_path, $config, $backupType); + + if ($result['success']) { + $backup->update([ + 'status' => 'completed', + 'remote_path' => $result['remote_path'] ?? null, + ]); + + if (! $keepLocal && $backup->local_path) { + $this->getAgent()->backupDeleteServer($backup->local_path); + $backup->update(['local_path' => null]); + } + + return true; + } else { + throw new Exception($result['error'] ?? __('Upload failed')); + } + } catch (Exception $e) { + $backup->update([ + 'status' => 'completed', + 'error_message' => __('Remote upload failed').': '.$e->getMessage(), + ]); + + return false; + } + } + + public function deleteBackup(int $id): void + { + $backup = Backup::find($id); + if (! $backup) { + return; + } + + // Delete local file/folder + if ($backup->local_path && file_exists($backup->local_path)) { + if (is_file($backup->local_path)) { + unlink($backup->local_path); + } else { + exec('rm -rf '.escapeshellarg($backup->local_path)); + } + } + + // Delete from remote destination if exists + if ($backup->remote_path && $backup->destination) { + try { + $config = array_merge( + $backup->destination->config ?? [], + ['type' => $backup->destination->type] + ); + $this->getAgent()->send('backup.delete_remote', [ + 'remote_path' => $backup->remote_path, + 'destination' => $config, + ]); + } catch (Exception $e) { + // Log but continue - we still want to delete the DB record + logger()->warning('Failed to delete remote backup: '.$e->getMessage()); + } + } + + $backup->delete(); + Notification::make()->title(__('Backup deleted'))->success()->send(); + $this->resetTable(); + } + + public function addScheduleAction(): Action + { + return Action::make('addSchedule') + ->label(__('Add Schedule')) + ->icon('heroicon-o-clock') + ->color('primary') + ->form([ + TextInput::make('name') + ->label(__('Schedule Name')) + ->required(), + Select::make('destination_id') + ->label(__('Destination')) + ->options(fn () => BackupDestination::where('is_server_backup', true) + ->where('is_active', true) + ->pluck('name', 'id') + ->prepend(__('Local Storage'), '')) + ->default('') + ->live() + ->afterStateUpdated(fn ($set, $state) => $set('backup_type', $this->supportsIncremental($state) ? 'incremental' : 'full')), + Radio::make('backup_type') + ->label(__('Backup Type')) + ->options(fn ($get) => $this->supportsIncremental($get('destination_id')) + ? [ + 'incremental' => __('Incremental (rsync)'), + 'full' => __('Full (tar.gz)'), + ] + : [ + 'full' => __('Full (tar.gz)'), + ]) + ->default('full') + ->required(), + Select::make('frequency') + ->label(__('Frequency')) + ->options([ + 'hourly' => __('Hourly'), + 'daily' => __('Daily'), + 'weekly' => __('Weekly'), + 'monthly' => __('Monthly'), + ]) + ->required() + ->live(), + TextInput::make('time') + ->label(__('Time (HH:MM)')) + ->default('02:00') + ->visible(fn ($get) => in_array($get('frequency'), ['daily', 'weekly', 'monthly'])), + Select::make('day_of_week') + ->label(__('Day of Week')) + ->options([ + 0 => __('Sunday'), 1 => __('Monday'), 2 => __('Tuesday'), + 3 => __('Wednesday'), 4 => __('Thursday'), 5 => __('Friday'), 6 => __('Saturday'), + ]) + ->visible(fn ($get) => $get('frequency') === 'weekly'), + Select::make('day_of_month') + ->label(__('Day of Month')) + ->options(array_combine(range(1, 28), range(1, 28))) + ->visible(fn ($get) => $get('frequency') === 'monthly'), + TextInput::make('retention_count') + ->label(__('Keep Last N Backups')) + ->numeric() + ->default(7), + Section::make(__('Include')) + ->schema([ + Grid::make(2)->schema([ + Toggle::make('include_files')->label(__('Website Files'))->default(true), + Toggle::make('include_databases')->label(__('Databases'))->default(true), + Toggle::make('include_mailboxes')->label(__('Mailboxes'))->default(true), + Toggle::make('include_dns')->label(__('DNS Records'))->default(true), + ]), + ]), + ]) + ->action(function (array $data) { + $schedule = BackupSchedule::create([ + 'name' => $data['name'], + 'is_server_backup' => true, + 'is_active' => true, + 'frequency' => $data['frequency'], + 'time' => $data['time'] ?? '02:00', + 'day_of_week' => $data['day_of_week'] ?? null, + 'day_of_month' => $data['day_of_month'] ?? null, + 'destination_id' => ! empty($data['destination_id']) ? $data['destination_id'] : null, + 'retention_count' => $data['retention_count'] ?? 7, + 'include_files' => $data['include_files'] ?? true, + 'include_databases' => $data['include_databases'] ?? true, + 'include_mailboxes' => $data['include_mailboxes'] ?? true, + 'include_dns' => $data['include_dns'] ?? true, + 'metadata' => ['backup_type' => $data['backup_type'] ?? 'full'], + ]); + + $schedule->calculateNextRun(); + $schedule->save(); + + Notification::make()->title(__('Schedule created'))->success()->send(); + $this->resetTable(); + }); + } + + public function toggleSchedule(int $id): void + { + $schedule = BackupSchedule::find($id); + if (! $schedule) { + return; + } + + $schedule->update(['is_active' => ! $schedule->is_active]); + + if ($schedule->is_active) { + $schedule->calculateNextRun(); + $schedule->save(); + } + + Notification::make()->title($schedule->is_active ? __('Schedule enabled') : __('Schedule disabled'))->success()->send(); + $this->resetTable(); + } + + public function deleteSchedule(int $id): void + { + BackupSchedule::where('id', $id)->delete(); + Notification::make()->title(__('Schedule deleted'))->success()->send(); + $this->resetTable(); + } + + public function editScheduleAction(): Action + { + return Action::make('editSchedule') + ->label(__('Edit Schedule')) + ->icon('heroicon-o-pencil') + ->color('gray') + ->fillForm(function (array $arguments): array { + $schedule = BackupSchedule::find($arguments['id']); + if (! $schedule) { + return []; + } + + return [ + 'name' => $schedule->name, + 'backup_type' => $schedule->metadata['backup_type'] ?? 'full', + 'frequency' => $schedule->frequency, + 'time' => $schedule->time, + 'day_of_week' => $schedule->day_of_week, + 'day_of_month' => $schedule->day_of_month, + 'destination_id' => $schedule->destination_id ?? '', + 'retention_count' => $schedule->retention_count, + 'include_files' => $schedule->include_files, + 'include_databases' => $schedule->include_databases, + 'include_mailboxes' => $schedule->include_mailboxes, + 'include_dns' => $schedule->include_dns, + ]; + }) + ->form([ + TextInput::make('name')->label(__('Schedule Name'))->required(), + Select::make('destination_id') + ->label(__('Destination')) + ->options(fn () => BackupDestination::where('is_server_backup', true) + ->where('is_active', true) + ->pluck('name', 'id') + ->prepend(__('Local Storage'), '')) + ->default('') + ->live(), + Radio::make('backup_type') + ->label(__('Backup Type')) + ->options(fn ($get) => $this->supportsIncremental($get('destination_id')) + ? ['incremental' => __('Incremental'), 'full' => __('Full')] + : ['full' => __('Full')]) + ->required(), + Select::make('frequency') + ->label(__('Frequency')) + ->options(['hourly' => __('Hourly'), 'daily' => __('Daily'), 'weekly' => __('Weekly'), 'monthly' => __('Monthly')]) + ->required() + ->live(), + TextInput::make('time')->label(__('Time (HH:MM)'))->visible(fn ($get) => in_array($get('frequency'), ['daily', 'weekly', 'monthly'])), + Select::make('day_of_week') + ->label(__('Day of Week')) + ->options([0 => __('Sunday'), 1 => __('Monday'), 2 => __('Tuesday'), 3 => __('Wednesday'), 4 => __('Thursday'), 5 => __('Friday'), 6 => __('Saturday')]) + ->visible(fn ($get) => $get('frequency') === 'weekly'), + Select::make('day_of_month') + ->label(__('Day of Month')) + ->options(array_combine(range(1, 28), range(1, 28))) + ->visible(fn ($get) => $get('frequency') === 'monthly'), + TextInput::make('retention_count')->label(__('Keep Last N Backups'))->numeric(), + Section::make(__('Include')) + ->schema([ + Grid::make(2)->schema([ + Toggle::make('include_files')->label(__('Website Files')), + Toggle::make('include_databases')->label(__('Databases')), + Toggle::make('include_mailboxes')->label(__('Mailboxes')), + Toggle::make('include_dns')->label(__('DNS Records')), + ]), + ]), + ]) + ->action(function (array $data, array $arguments) { + $schedule = BackupSchedule::find($arguments['id']); + if (! $schedule) { + return; + } + + $schedule->update([ + 'name' => $data['name'], + 'frequency' => $data['frequency'], + 'time' => $data['time'] ?? '02:00', + 'day_of_week' => $data['day_of_week'] ?? null, + 'day_of_month' => $data['day_of_month'] ?? null, + 'destination_id' => ! empty($data['destination_id']) ? $data['destination_id'] : null, + 'retention_count' => $data['retention_count'] ?? 7, + 'include_files' => $data['include_files'] ?? true, + 'include_databases' => $data['include_databases'] ?? true, + 'include_mailboxes' => $data['include_mailboxes'] ?? true, + 'include_dns' => $data['include_dns'] ?? true, + 'metadata' => array_merge($schedule->metadata ?? [], ['backup_type' => $data['backup_type'] ?? 'full']), + ]); + + $schedule->calculateNextRun(); + $schedule->save(); + + Notification::make()->title(__('Schedule updated'))->success()->send(); + $this->resetTable(); + }); + } + + public function runScheduleNow(int $id): void + { + $schedule = BackupSchedule::find($id); + if (! $schedule) { + return; + } + + $runningBackup = Backup::where('schedule_id', $id)->running()->first(); + if ($runningBackup) { + Notification::make()->title(__('Backup already running'))->warning()->send(); + + return; + } + + $this->createServerBackup([ + 'name' => $schedule->name.' - '.__('Manual Run').' '.now()->format('Y-m-d H:i'), + 'backup_type' => $schedule->metadata['backup_type'] ?? 'full', + 'destination_id' => $schedule->destination_id, + 'schedule_id' => $schedule->id, + 'include_files' => $schedule->include_files, + 'include_databases' => $schedule->include_databases, + 'include_mailboxes' => $schedule->include_mailboxes, + 'include_dns' => $schedule->include_dns, + 'users' => $schedule->users, + ]); + } + + public function stopScheduleBackup(int $id): void + { + $backup = Backup::where('schedule_id', $id)->running()->first(); + if ($backup) { + $backup->update([ + 'status' => 'failed', + 'error_message' => __('Cancelled by user'), + 'completed_at' => now(), + ]); + Notification::make()->title(__('Backup cancelled'))->success()->send(); + $this->resetTable(); + } + } + + public function createUserBackupAction(): Action + { + return Action::make('createUserBackup') + ->label(__('Backup User')) + ->icon('heroicon-o-user') + ->color('gray') + ->form([ + Select::make('user_id') + ->label(__('User')) + ->options(fn () => User::where('is_admin', false) + ->where('is_active', true) + ->pluck('username', 'id')) + ->required() + ->searchable(), + Section::make(__('Include')) + ->schema([ + Grid::make(2)->schema([ + Toggle::make('include_files')->label(__('Website Files'))->default(true), + Toggle::make('include_databases')->label(__('Databases'))->default(true), + Toggle::make('include_mailboxes')->label(__('Mailboxes'))->default(true), + Toggle::make('include_dns')->label(__('DNS Records'))->default(true), + ]), + ]), + ]) + ->action(function (array $data) { + $user = User::find($data['user_id']); + if (! $user) { + Notification::make()->title(__('User not found'))->danger()->send(); + + return; + } + + $timestamp = now()->format('Y-m-d_His'); + $filename = "backup_{$timestamp}.tar.gz"; + $outputPath = "/home/{$user->username}/backups/{$filename}"; + + $backup = Backup::create([ + 'user_id' => $user->id, + 'name' => "{$user->username} ".__('Backup').' '.now()->format('Y-m-d H:i'), + 'filename' => $filename, + 'type' => 'full', + 'include_files' => $data['include_files'] ?? true, + 'include_databases' => $data['include_databases'] ?? true, + 'include_mailboxes' => $data['include_mailboxes'] ?? true, + 'include_dns' => $data['include_dns'] ?? true, + 'status' => 'pending', + 'local_path' => $outputPath, + 'metadata' => ['backup_type' => 'full'], + ]); + + try { + $backup->update(['status' => 'running', 'started_at' => now()]); + + $result = $this->getAgent()->backupCreate($user->username, $outputPath, [ + 'backup_type' => 'full', + 'include_files' => $data['include_files'] ?? true, + 'include_databases' => $data['include_databases'] ?? true, + 'include_mailboxes' => $data['include_mailboxes'] ?? true, + 'include_dns' => $data['include_dns'] ?? true, + ]); + + if ($result['success']) { + $backup->update([ + 'status' => 'completed', + 'completed_at' => now(), + 'size_bytes' => $result['size'] ?? 0, + 'checksum' => $result['checksum'] ?? null, + 'domains' => $result['domains'] ?? null, + 'databases' => $result['databases'] ?? null, + 'mailboxes' => $result['mailboxes'] ?? null, + ]); + Notification::make()->title(__('Backup created for :username', ['username' => $user->username]))->success()->send(); + } else { + throw new Exception($result['error'] ?? __('Backup failed')); + } + } catch (Exception $e) { + $backup->update([ + 'status' => 'failed', + 'completed_at' => now(), + 'error_message' => $e->getMessage(), + ]); + Notification::make()->title(__('Backup failed'))->body($e->getMessage())->danger()->send(); + } + + $this->resetTable(); + }); + } + + protected function executeRestore(Backup $backup, array $data): void + { + // Use username from form (allows selecting user for server backups) + $username = $data['restore_username'] ?? ''; + + if ($username === '__all__') { + $manifest = $this->getBackupManifest($backup); + $usernames = $manifest['users'] ?? $backup->users ?? []; + if (empty($usernames)) { + $usernames = array_filter([$manifest['username'] ?? '']); + } + + if (empty($usernames)) { + Notification::make()->title(__('Cannot determine users for this backup'))->danger()->send(); + + return; + } + + foreach ($usernames as $restoreUser) { + $data['restore_username'] = $restoreUser; + $this->executeRestore($backup, $data); + } + + return; + } + + if (empty($username)) { + $manifest = $this->getBackupManifest($backup); + $username = $manifest['username'] ?? ($backup->users[0] ?? ''); + } + + if (empty($username)) { + Notification::make()->title(__('Cannot determine user for this backup'))->danger()->send(); + + return; + } + + // Prepare backup path + $backupPath = $backup->local_path; + $tempDownloadPath = null; + + // For remote backups, download first + if ((! $backupPath || ! file_exists($backupPath)) && $backup->remote_path && $backup->destination) { + $destination = $backup->destination; + + if (! $destination) { + Notification::make()->title(__('Backup destination not found'))->danger()->send(); + + return; + } + + // Create temp directory for download + $tempDownloadPath = sys_get_temp_dir().'/jabali_restore_download_'.uniqid(); + mkdir($tempDownloadPath, 0755, true); + + // For incremental backups, we need to download the specific user's directory + $remotePath = $backup->remote_path; + + // If it's a server backup with per-user directories, construct the user-specific path + if (str_contains($remotePath, '/') && ! str_ends_with($remotePath, '.tar.gz')) { + // Incremental backup - download the user's directory + $userRemotePath = rtrim($remotePath, '/').'/'.$username; + } else { + $userRemotePath = $remotePath; + } + + Notification::make() + ->title(__('Downloading backup')) + ->body(__('Downloading from remote destination...')) + ->info() + ->send(); + + try { + $downloadResult = $this->getAgent()->send('backup.download_remote', [ + 'remote_path' => $userRemotePath, + 'local_path' => $tempDownloadPath, + 'destination' => array_merge( + $destination->config ?? [], + ['type' => $destination->type] + ), + ]); + + if (! ($downloadResult['success'] ?? false)) { + throw new Exception($downloadResult['error'] ?? __('Failed to download backup')); + } + + $backupPath = $tempDownloadPath; + } catch (Exception $e) { + // Cleanup temp directory on failure + if (is_dir($tempDownloadPath)) { + exec('rm -rf '.escapeshellarg($tempDownloadPath)); + } + Notification::make() + ->title(__('Download failed')) + ->body($e->getMessage()) + ->danger() + ->send(); + + return; + } + } + + if (! $backupPath || ! file_exists($backupPath)) { + Notification::make()->title(__('Backup file not found'))->danger()->send(); + + return; + } + + try { + $result = $this->getAgent()->send('backup.restore', [ + 'username' => $username, + 'backup_path' => $backupPath, + 'restore_files' => $data['restore_files'] ?? false, + 'restore_databases' => $data['restore_databases'] ?? false, + 'restore_mailboxes' => $data['restore_mailboxes'] ?? false, + 'restore_dns' => $data['restore_dns'] ?? false, + 'restore_ssl' => $data['restore_ssl'] ?? false, + 'selected_domains' => ! empty($data['selected_domains']) ? $data['selected_domains'] : null, + 'selected_databases' => ! empty($data['selected_databases']) ? $data['selected_databases'] : null, + 'selected_mailboxes' => ! empty($data['selected_mailboxes']) ? $data['selected_mailboxes'] : null, + ]); + + // Cleanup temp download if used + if ($tempDownloadPath && is_dir($tempDownloadPath)) { + exec('rm -rf '.escapeshellarg($tempDownloadPath)); + } + + if ($result['success'] ?? false) { + $restored = $result['restored'] ?? []; + $summary = []; + + if (! empty($restored['files'])) { + $summary[] = count($restored['files']).' '.__('domain(s)'); + } + if (! empty($restored['databases'])) { + $summary[] = count($restored['databases']).' '.__('database(s)'); + } + if (! empty($restored['mailboxes'])) { + $summary[] = count($restored['mailboxes']).' '.__('mailbox(es)'); + } + if (! empty($restored['ssl_certificates'])) { + $summary[] = count($restored['ssl_certificates']).' '.__('SSL cert(s)'); + } + if (! empty($restored['dns_zones'])) { + $summary[] = count($restored['dns_zones']).' '.__('DNS zone(s)'); + } + if ($restored['mysql_users'] ?? false) { + $summary[] = __('MySQL users'); + } + + Notification::make() + ->title(__('Restore completed')) + ->body(! empty($summary) ? __('Restored: :items', ['items' => implode(', ', $summary)]) : __('Nothing was restored')) + ->success() + ->send(); + } else { + throw new Exception($result['error'] ?? __('Restore failed')); + } + } catch (Exception $e) { + // Cleanup temp download on failure + if ($tempDownloadPath && is_dir($tempDownloadPath)) { + exec('rm -rf '.escapeshellarg($tempDownloadPath)); + } + Notification::make() + ->title(__('Restore failed')) + ->body($e->getMessage()) + ->danger() + ->send(); + } + } + + protected function getBackupManifest(Backup $backup, ?string $forUser = null): array + { + $backupPath = $backup->local_path; + + if (! $backupPath || ! file_exists($backupPath)) { + // For remote backups, try to get info from stored metadata + return [ + 'username' => $forUser ?? ($backup->users[0] ?? ''), + 'domains' => $backup->domains ?? [], + 'databases' => $backup->databases ?? [], + 'mailboxes' => $backup->mailboxes ?? [], + 'mysql_users' => $backup->metadata['mysql_users'] ?? [], + 'ssl_certificates' => $backup->ssl_certificates ?? [], + 'dns_zones' => $backup->dns_zones ?? [], + 'users' => $backup->users ?? [], + ]; + } + + try { + $result = $this->getAgent()->send('backup.get_info', [ + 'backup_path' => $backupPath, + ]); + + if ($result['success'] ?? false) { + $manifest = $result['manifest'] ?? []; + + // Handle server backup manifest format (has nested 'users' object) + if (isset($manifest['users']) && is_array($manifest['users']) && $manifest['type'] === 'server') { + $userList = array_keys($manifest['users']); + + // If no specific user requested, return aggregated data + if ($forUser === null) { + return [ + 'username' => $userList[0] ?? '', + 'users' => $userList, + 'type' => 'server', + 'domains' => $this->aggregateFromUsers($manifest['users'], 'domains'), + 'databases' => $this->aggregateFromUsers($manifest['users'], 'databases'), + 'mailboxes' => $this->aggregateFromUsers($manifest['users'], 'mailboxes'), + 'mysql_users' => [], + 'ssl_certificates' => [], + 'dns_zones' => [], + ]; + } + + // Return specific user's data + if (isset($manifest['users'][$forUser])) { + $userData = $manifest['users'][$forUser]; + + return [ + 'username' => $forUser, + 'users' => $userList, + 'type' => 'server', + 'domains' => $userData['domains'] ?? [], + 'databases' => $userData['databases'] ?? [], + 'mailboxes' => $userData['mailboxes'] ?? [], + 'mysql_users' => [], + 'ssl_certificates' => [], + 'dns_zones' => [], + ]; + } + } + + return $manifest; + } + } catch (Exception $e) { + // Fall back to stored data + } + + return [ + 'username' => $forUser ?? ($backup->users[0] ?? ''), + 'domains' => $backup->domains ?? [], + 'databases' => $backup->databases ?? [], + 'mailboxes' => $backup->mailboxes ?? [], + 'mysql_users' => [], + 'ssl_certificates' => [], + 'dns_zones' => [], + 'users' => $backup->users ?? [], + ]; + } + + protected function aggregateFromUsers(array $users, string $key): array + { + $result = []; + foreach ($users as $userData) { + if (isset($userData[$key]) && is_array($userData[$key])) { + $result = array_merge($result, $userData[$key]); + } + } + + return array_unique($result); + } + + /** + * Get the system timezone for display purposes. + * Laravel uses UTC internally but we display times in server's local timezone. + */ + protected function getSystemTimezone(): string + { + static $timezone = null; + if ($timezone === null) { + $timezone = trim(shell_exec('cat /etc/timezone 2>/dev/null') ?? ''); + if ($timezone === '') { + $timezone = trim(shell_exec('timedatectl show -p Timezone --value 2>/dev/null') ?? ''); + } + if ($timezone === '') { + $timezone = 'UTC'; + } + } + + return $timezone; + } +} diff --git a/app/Models/BackupSchedule.php b/app/Models/BackupSchedule.php index 0dbafb9..81ef79a 100644 --- a/app/Models/BackupSchedule.php +++ b/app/Models/BackupSchedule.php @@ -185,51 +185,3 @@ class BackupSchedule extends Model return $timezone; } - /** - * Scope for active schedules. - */ - public function scopeActive($query) - { - return $query->where('is_active', true); - } - - /** - * Scope for due schedules. - */ - public function scopeDue($query) - { - return $query->active() - ->where(function ($q) { - $q->whereNull('next_run_at') - ->orWhere('next_run_at', '<=', now()); - }); - } - - /** - * Scope for user schedules. - */ - public function scopeForUser($query, int $userId) - { - return $query->where('user_id', $userId); - } - - /** - * Scope for server backup schedules. - */ - public function scopeServerBackups($query) - { - return $query->where('is_server_backup', true); - } - - /** - * Get last status color for UI. - */ - public function getLastStatusColorAttribute(): string - { - return match ($this->last_status) { - 'success' => 'success', - 'failed' => 'danger', - default => 'gray', - }; - } -} diff --git a/doccs/site/.gitignore b/doccs/site/.gitignore new file mode 100644 index 0000000..de35ccf --- /dev/null +++ b/doccs/site/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +dist/ +.astro/ +.DS_Store diff --git a/doccs/site/.vscode/extensions.json b/doccs/site/.vscode/extensions.json new file mode 100644 index 0000000..22a1505 --- /dev/null +++ b/doccs/site/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + "recommendations": ["astro-build.astro-vscode"], + "unwantedRecommendations": [] +} diff --git a/doccs/site/.vscode/launch.json b/doccs/site/.vscode/launch.json new file mode 100644 index 0000000..d642209 --- /dev/null +++ b/doccs/site/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "command": "./node_modules/.bin/astro dev", + "name": "Development server", + "request": "launch", + "type": "node-terminal" + } + ] +} diff --git a/doccs/site/README.md b/doccs/site/README.md new file mode 100644 index 0000000..1b7f5c3 --- /dev/null +++ b/doccs/site/README.md @@ -0,0 +1,49 @@ +# Starlight Starter Kit: Basics + +[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) + +``` +npm create astro@latest -- --template starlight +``` + +> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! + +## 🚀 Project Structure + +Inside of your Astro + Starlight project, you'll see the following folders and files: + +``` +. +├── public/ +├── src/ +│ ├── assets/ +│ ├── content/ +│ │ └── docs/ +│ └── content.config.ts +├── astro.config.mjs +├── package.json +└── tsconfig.json +``` + +Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. + +Images can be added to `src/assets/` and embedded in Markdown with a relative link. + +Static assets, like favicons, can be placed in the `public/` directory. + +## 🧞 Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `npm install` | Installs dependencies | +| `npm run dev` | Starts local dev server at `localhost:4321` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | + +## 👀 Want to learn more? + +Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). diff --git a/doccs/site/astro.config.mjs b/doccs/site/astro.config.mjs new file mode 100644 index 0000000..3fa76af --- /dev/null +++ b/doccs/site/astro.config.mjs @@ -0,0 +1,34 @@ +// @ts-check +import { defineConfig } from 'astro/config'; +import starlight from '@astrojs/starlight'; + +// https://astro.build/config +export default defineConfig({ + server: { + allowedHosts: ['jabali.lan'], + }, + integrations: [ + starlight({ + title: 'Jabali Panel Documentation', + description: 'Feature documentation and screenshots for the Jabali hosting panel.', + sidebar: [ + { + label: 'Getting Started', + items: [{ label: 'Overview', slug: 'overview' }], + }, + { + label: 'Admin Panel', + autogenerate: { directory: 'admin' }, + }, + { + label: 'User Panel', + autogenerate: { directory: 'user' }, + }, + { + label: 'Platform', + autogenerate: { directory: 'platform' }, + }, + ], + }), + ], +}); diff --git a/doccs/site/package-lock.json b/doccs/site/package-lock.json new file mode 100644 index 0000000..41b34af --- /dev/null +++ b/doccs/site/package-lock.json @@ -0,0 +1,6394 @@ +{ + "name": "doccs-site", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "doccs-site", + "version": "0.0.1", + "dependencies": { + "@astrojs/starlight": "^0.37.6", + "astro": "^5.6.1", + "sharp": "^0.34.2" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", + "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", + "license": "MIT" + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", + "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", + "license": "MIT" + }, + "node_modules/@astrojs/markdown-remark": { + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", + "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/prism": "3.3.0", + "github-slugger": "^2.0.0", + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.1", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.2", + "remark-smartypants": "^3.0.2", + "shiki": "^3.19.0", + "smol-toml": "^1.5.2", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3" + } + }, + "node_modules/@astrojs/mdx": { + "version": "4.3.13", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.13.tgz", + "integrity": "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "6.3.10", + "@mdx-js/mdx": "^3.1.1", + "acorn": "^8.15.0", + "es-module-lexer": "^1.7.0", + "estree-util-visit": "^2.0.0", + "hast-util-to-html": "^9.0.5", + "piccolore": "^0.1.3", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.1", + "remark-smartypants": "^3.0.2", + "source-map": "^0.7.6", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + }, + "peerDependencies": { + "astro": "^5.0.0" + } + }, + "node_modules/@astrojs/prism": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", + "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/sitemap": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", + "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", + "license": "MIT", + "dependencies": { + "sitemap": "^8.0.2", + "stream-replace-string": "^2.0.0", + "zod": "^3.25.76" + } + }, + "node_modules/@astrojs/starlight": { + "version": "0.37.6", + "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.37.6.tgz", + "integrity": "sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/mdx": "^4.2.3", + "@astrojs/sitemap": "^3.3.0", + "@pagefind/default-ui": "^1.3.0", + "@types/hast": "^3.0.4", + "@types/js-yaml": "^4.0.9", + "@types/mdast": "^4.0.4", + "astro-expressive-code": "^0.41.1", + "bcp-47": "^2.1.0", + "hast-util-from-html": "^2.0.1", + "hast-util-select": "^6.0.2", + "hast-util-to-string": "^3.0.0", + "hastscript": "^9.0.0", + "i18next": "^23.11.5", + "js-yaml": "^4.1.0", + "klona": "^2.0.6", + "magic-string": "^0.30.17", + "mdast-util-directive": "^3.0.0", + "mdast-util-to-markdown": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "pagefind": "^1.3.0", + "rehype": "^13.0.1", + "rehype-format": "^5.0.0", + "remark-directive": "^3.0.0", + "ultrahtml": "^1.6.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.2" + }, + "peerDependencies": { + "astro": "^5.5.0" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", + "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.2.0", + "debug": "^4.4.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "is-docker": "^3.0.0", + "is-wsl": "^3.1.0", + "which-pm-runs": "^1.1.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", + "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", + "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@expressive-code/core": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.41.6.tgz", + "integrity": "sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^4.0.4", + "hast-util-select": "^6.0.2", + "hast-util-to-html": "^9.0.1", + "hast-util-to-text": "^4.0.1", + "hastscript": "^9.0.0", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" + } + }, + "node_modules/@expressive-code/plugin-frames": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.41.6.tgz", + "integrity": "sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6" + } + }, + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.6.tgz", + "integrity": "sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6", + "shiki": "^3.2.2" + } + }, + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.6.tgz", + "integrity": "sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" + }, + "node_modules/@pagefind/darwin-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz", + "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/darwin-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz", + "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/default-ui": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.4.0.tgz", + "integrity": "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==", + "license": "MIT" + }, + "node_modules/@pagefind/freebsd-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz", + "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@pagefind/linux-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz", + "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/linux-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz", + "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/windows-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz", + "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", + "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", + "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz", + "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", + "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", + "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", + "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", + "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", + "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", + "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", + "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", + "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", + "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", + "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", + "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", + "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", + "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", + "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", + "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", + "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", + "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", + "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", + "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", + "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", + "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", + "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.22.0.tgz", + "integrity": "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.22.0.tgz", + "integrity": "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.22.0.tgz", + "integrity": "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.22.0.tgz", + "integrity": "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.22.0.tgz", + "integrity": "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.22.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.22.0.tgz", + "integrity": "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/node": { + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", + "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/astro": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.17.1.tgz", + "integrity": "sha512-oD3tlxTaVWGq/Wfbqk6gxzVRz98xa/rYlpe+gU2jXJMSD01k6sEDL01ZlT8mVSYB/rMgnvIOfiQQ3BbLdN237A==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.0", + "@astrojs/internal-helpers": "0.7.5", + "@astrojs/markdown-remark": "6.3.10", + "@astrojs/telemetry": "3.3.0", + "@capsizecss/unpack": "^4.0.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.3.0", + "acorn": "^8.15.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.3.1", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^1.1.1", + "cssesc": "^3.0.0", + "debug": "^4.4.3", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.6.2", + "diff": "^8.0.3", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.7.0", + "esbuild": "^0.25.0", + "estree-walker": "^3.0.3", + "flattie": "^1.1.1", + "fontace": "~0.4.0", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "import-meta-resolve": "^4.2.0", + "js-yaml": "^4.1.1", + "magic-string": "^0.30.21", + "magicast": "^0.5.1", + "mrmime": "^2.0.1", + "neotraverse": "^0.6.18", + "p-limit": "^6.2.0", + "p-queue": "^8.1.1", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.3", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.7.3", + "shiki": "^3.21.0", + "smol-toml": "^1.6.0", + "svgo": "^4.0.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tsconfck": "^3.1.6", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.3", + "unist-util-visit": "^5.0.0", + "unstorage": "^1.17.4", + "vfile": "^6.0.3", + "vite": "^6.4.1", + "vitefu": "^1.1.1", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "yocto-spinner": "^0.2.3", + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.34.0" + } + }, + "node_modules/astro-expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.41.6.tgz", + "integrity": "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw==", + "license": "MIT", + "dependencies": { + "rehype-expressive-code": "^0.41.6" + }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", + "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-selector-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", + "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", + "dependencies": { + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/devalue": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", + "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", + "license": "MIT" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.41.6.tgz", + "integrity": "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6", + "@expressive-code/plugin-frames": "^0.41.6", + "@expressive-code/plugin-shiki": "^0.41.6", + "@expressive-code/plugin-text-markers": "^0.41.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.2.tgz", + "integrity": "sha512-piJxbLnkD9Xcyi7dWJRnqszEURixe7CrF/efBfbffe2DPyabmuIuqraruY8cXTs19QoM8VJzx47BDRVNXETM7Q==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/h3": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.5.tgz", + "integrity": "sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.2", + "crossws": "^0.3.5", + "defu": "^6.1.4", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "node_modules/hast-util-embedded": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", + "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-format": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-format/-/hast-util-format-1.1.0.tgz", + "integrity": "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-minify-whitespace": "^1.0.0", + "hast-util-phrasing": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "html-whitespace-sensitive-tag-names": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-body-ok-link": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz", + "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-minify-whitespace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz", + "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-is-body-ok-link": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.4.tgz", + "integrity": "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "nth-check": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-whitespace-sensitive-tag-names": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-whitespace-sensitive-tag-names/-/html-whitespace-sensitive-tag-names-3.0.1.tgz", + "integrity": "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/i18next": { + "version": "23.16.8", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", + "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", + "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", + "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "license": "MIT" + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", + "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, + "node_modules/pagefind": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz", + "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==", + "license": "MIT", + "bin": { + "pagefind": "lib/runner/bin.cjs" + }, + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.4.0", + "@pagefind/darwin-x64": "1.4.0", + "@pagefind/freebsd-x64": "1.4.0", + "@pagefind/linux-arm64": "1.4.0", + "@pagefind/linux-x64": "1.4.0", + "@pagefind/windows-x64": "1.4.0" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/rehype-expressive-code/-/rehype-expressive-code-0.41.6.tgz", + "integrity": "sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g==", + "license": "MIT", + "dependencies": { + "expressive-code": "^0.41.6" + } + }, + "node_modules/rehype-format": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rehype-format/-/rehype-format-5.0.1.tgz", + "integrity": "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-format": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rollup": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", + "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.57.1", + "@rollup/rollup-android-arm64": "4.57.1", + "@rollup/rollup-darwin-arm64": "4.57.1", + "@rollup/rollup-darwin-x64": "4.57.1", + "@rollup/rollup-freebsd-arm64": "4.57.1", + "@rollup/rollup-freebsd-x64": "4.57.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", + "@rollup/rollup-linux-arm-musleabihf": "4.57.1", + "@rollup/rollup-linux-arm64-gnu": "4.57.1", + "@rollup/rollup-linux-arm64-musl": "4.57.1", + "@rollup/rollup-linux-loong64-gnu": "4.57.1", + "@rollup/rollup-linux-loong64-musl": "4.57.1", + "@rollup/rollup-linux-ppc64-gnu": "4.57.1", + "@rollup/rollup-linux-ppc64-musl": "4.57.1", + "@rollup/rollup-linux-riscv64-gnu": "4.57.1", + "@rollup/rollup-linux-riscv64-musl": "4.57.1", + "@rollup/rollup-linux-s390x-gnu": "4.57.1", + "@rollup/rollup-linux-x64-gnu": "4.57.1", + "@rollup/rollup-linux-x64-musl": "4.57.1", + "@rollup/rollup-openbsd-x64": "4.57.1", + "@rollup/rollup-openharmony-arm64": "4.57.1", + "@rollup/rollup-win32-arm64-msvc": "4.57.1", + "@rollup/rollup-win32-ia32-msvc": "4.57.1", + "@rollup/rollup-win32-x64-gnu": "4.57.1", + "@rollup/rollup-win32-x64-msvc": "4.57.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shiki": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.22.0.tgz", + "integrity": "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.22.0", + "@shikijs/engine-javascript": "3.22.0", + "@shikijs/engine-oniguruma": "3.22.0", + "@shikijs/langs": "3.22.0", + "@shikijs/themes": "3.22.0", + "@shikijs/types": "3.22.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.2.tgz", + "integrity": "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", + "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stream-replace-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", + "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/svgo": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", + "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.4.1" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", + "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unifont": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.3.tgz", + "integrity": "sha512-b0GtQzKCyuSHGsfj5vyN8st7muZ6VCI4XD4vFlr7Uy1rlWVYxC3npnfk8MyreHxJYrz1ooLDqDzFe9XqQTlAhA==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ofetch": "^1.5.1", + "ohash": "^2.0.11" + } + }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unstorage": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz", + "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.5", + "lru-cache": "^11.2.0", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which-pm-runs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", + "dependencies": { + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yocto-spinner": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", + "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", + "license": "MIT", + "dependencies": { + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18.19" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/doccs/site/package.json b/doccs/site/package.json new file mode 100644 index 0000000..10b3ca1 --- /dev/null +++ b/doccs/site/package.json @@ -0,0 +1,17 @@ +{ + "name": "doccs-site", + "type": "module", + "version": "0.0.1", + "scripts": { + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" + }, + "dependencies": { + "@astrojs/starlight": "^0.37.6", + "astro": "^5.6.1", + "sharp": "^0.34.2" + } +} \ No newline at end of file diff --git a/doccs/site/public/favicon.svg b/doccs/site/public/favicon.svg new file mode 100644 index 0000000..cba5ac1 --- /dev/null +++ b/doccs/site/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/doccs/site/public/screenshots/admin-automation-api.png b/doccs/site/public/screenshots/admin-automation-api.png new file mode 100644 index 0000000..029e4a4 Binary files /dev/null and b/doccs/site/public/screenshots/admin-automation-api.png differ diff --git a/doccs/site/public/screenshots/admin-backup-download.png b/doccs/site/public/screenshots/admin-backup-download.png new file mode 100644 index 0000000..d3c2d62 Binary files /dev/null and b/doccs/site/public/screenshots/admin-backup-download.png differ diff --git a/doccs/site/public/screenshots/admin-backups--tab-backups.png b/doccs/site/public/screenshots/admin-backups--tab-backups.png new file mode 100644 index 0000000..4d889a1 Binary files /dev/null and b/doccs/site/public/screenshots/admin-backups--tab-backups.png differ diff --git a/doccs/site/public/screenshots/admin-backups--tab-destinations.png b/doccs/site/public/screenshots/admin-backups--tab-destinations.png new file mode 100644 index 0000000..3250684 Binary files /dev/null and b/doccs/site/public/screenshots/admin-backups--tab-destinations.png differ diff --git a/doccs/site/public/screenshots/admin-backups--tab-schedules.png b/doccs/site/public/screenshots/admin-backups--tab-schedules.png new file mode 100644 index 0000000..91e70ab Binary files /dev/null and b/doccs/site/public/screenshots/admin-backups--tab-schedules.png differ diff --git a/doccs/site/public/screenshots/admin-backups.png b/doccs/site/public/screenshots/admin-backups.png new file mode 100644 index 0000000..3250684 Binary files /dev/null and b/doccs/site/public/screenshots/admin-backups.png differ diff --git a/doccs/site/public/screenshots/admin-cpanel-migration.png b/doccs/site/public/screenshots/admin-cpanel-migration.png new file mode 100644 index 0000000..431679f Binary files /dev/null and b/doccs/site/public/screenshots/admin-cpanel-migration.png differ diff --git a/doccs/site/public/screenshots/admin-dashboard.png b/doccs/site/public/screenshots/admin-dashboard.png new file mode 100644 index 0000000..2c913fc Binary files /dev/null and b/doccs/site/public/screenshots/admin-dashboard.png differ diff --git a/doccs/site/public/screenshots/admin-database-tuning.png b/doccs/site/public/screenshots/admin-database-tuning.png new file mode 100644 index 0000000..63c95fc Binary files /dev/null and b/doccs/site/public/screenshots/admin-database-tuning.png differ diff --git a/doccs/site/public/screenshots/admin-dns-zones.png b/doccs/site/public/screenshots/admin-dns-zones.png new file mode 100644 index 0000000..955e643 Binary files /dev/null and b/doccs/site/public/screenshots/admin-dns-zones.png differ diff --git a/doccs/site/public/screenshots/admin-email-logs.png b/doccs/site/public/screenshots/admin-email-logs.png new file mode 100644 index 0000000..38b095c Binary files /dev/null and b/doccs/site/public/screenshots/admin-email-logs.png differ diff --git a/doccs/site/public/screenshots/admin-email-queue.png b/doccs/site/public/screenshots/admin-email-queue.png new file mode 100644 index 0000000..38b095c Binary files /dev/null and b/doccs/site/public/screenshots/admin-email-queue.png differ diff --git a/doccs/site/public/screenshots/admin-geo-block-rules-5-edit.png b/doccs/site/public/screenshots/admin-geo-block-rules-5-edit.png new file mode 100644 index 0000000..c2a17c2 Binary files /dev/null and b/doccs/site/public/screenshots/admin-geo-block-rules-5-edit.png differ diff --git a/doccs/site/public/screenshots/admin-geo-block-rules-create.png b/doccs/site/public/screenshots/admin-geo-block-rules-create.png new file mode 100644 index 0000000..dc7f9ed Binary files /dev/null and b/doccs/site/public/screenshots/admin-geo-block-rules-create.png differ diff --git a/doccs/site/public/screenshots/admin-geo-block-rules-edit.png b/doccs/site/public/screenshots/admin-geo-block-rules-edit.png new file mode 100644 index 0000000..c2a17c2 Binary files /dev/null and b/doccs/site/public/screenshots/admin-geo-block-rules-edit.png differ diff --git a/doccs/site/public/screenshots/admin-geo-block-rules.png b/doccs/site/public/screenshots/admin-geo-block-rules.png new file mode 100644 index 0000000..8d532af Binary files /dev/null and b/doccs/site/public/screenshots/admin-geo-block-rules.png differ diff --git a/doccs/site/public/screenshots/admin-home.png b/doccs/site/public/screenshots/admin-home.png new file mode 100644 index 0000000..2c913fc Binary files /dev/null and b/doccs/site/public/screenshots/admin-home.png differ diff --git a/doccs/site/public/screenshots/admin-hosting-packages-1-edit.png b/doccs/site/public/screenshots/admin-hosting-packages-1-edit.png new file mode 100644 index 0000000..0476fa2 Binary files /dev/null and b/doccs/site/public/screenshots/admin-hosting-packages-1-edit.png differ diff --git a/doccs/site/public/screenshots/admin-hosting-packages-create.png b/doccs/site/public/screenshots/admin-hosting-packages-create.png new file mode 100644 index 0000000..03ac40a Binary files /dev/null and b/doccs/site/public/screenshots/admin-hosting-packages-create.png differ diff --git a/doccs/site/public/screenshots/admin-hosting-packages-edit.png b/doccs/site/public/screenshots/admin-hosting-packages-edit.png new file mode 100644 index 0000000..0476fa2 Binary files /dev/null and b/doccs/site/public/screenshots/admin-hosting-packages-edit.png differ diff --git a/doccs/site/public/screenshots/admin-hosting-packages.png b/doccs/site/public/screenshots/admin-hosting-packages.png new file mode 100644 index 0000000..87a6a67 Binary files /dev/null and b/doccs/site/public/screenshots/admin-hosting-packages.png differ diff --git a/doccs/site/public/screenshots/admin-ip-addresses.png b/doccs/site/public/screenshots/admin-ip-addresses.png new file mode 100644 index 0000000..b38642c Binary files /dev/null and b/doccs/site/public/screenshots/admin-ip-addresses.png differ diff --git a/doccs/site/public/screenshots/admin-login.png b/doccs/site/public/screenshots/admin-login.png new file mode 100644 index 0000000..cc31f1f Binary files /dev/null and b/doccs/site/public/screenshots/admin-login.png differ diff --git a/doccs/site/public/screenshots/admin-migration--tab-cpanel-migration.png b/doccs/site/public/screenshots/admin-migration--tab-cpanel-migration.png new file mode 100644 index 0000000..1693a74 Binary files /dev/null and b/doccs/site/public/screenshots/admin-migration--tab-cpanel-migration.png differ diff --git a/doccs/site/public/screenshots/admin-migration--tab-whm-migration.png b/doccs/site/public/screenshots/admin-migration--tab-whm-migration.png new file mode 100644 index 0000000..536b96e Binary files /dev/null and b/doccs/site/public/screenshots/admin-migration--tab-whm-migration.png differ diff --git a/doccs/site/public/screenshots/admin-migration.png b/doccs/site/public/screenshots/admin-migration.png new file mode 100644 index 0000000..1693a74 Binary files /dev/null and b/doccs/site/public/screenshots/admin-migration.png differ diff --git a/doccs/site/public/screenshots/admin-password-reset-request.png b/doccs/site/public/screenshots/admin-password-reset-request.png new file mode 100644 index 0000000..ec6075d Binary files /dev/null and b/doccs/site/public/screenshots/admin-password-reset-request.png differ diff --git a/doccs/site/public/screenshots/admin-password-reset-reset.png b/doccs/site/public/screenshots/admin-password-reset-reset.png new file mode 100644 index 0000000..4f44da7 Binary files /dev/null and b/doccs/site/public/screenshots/admin-password-reset-reset.png differ diff --git a/doccs/site/public/screenshots/admin-php-manager.png b/doccs/site/public/screenshots/admin-php-manager.png new file mode 100644 index 0000000..234a681 Binary files /dev/null and b/doccs/site/public/screenshots/admin-php-manager.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-antivirus.png b/doccs/site/public/screenshots/admin-security--tab-antivirus.png new file mode 100644 index 0000000..012372a Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-antivirus.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-fail2ban.png b/doccs/site/public/screenshots/admin-security--tab-fail2ban.png new file mode 100644 index 0000000..012372a Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-fail2ban.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-firewall.png b/doccs/site/public/screenshots/admin-security--tab-firewall.png new file mode 100644 index 0000000..35c33fc Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-firewall.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-modsecurity-waf.png b/doccs/site/public/screenshots/admin-security--tab-modsecurity-waf.png new file mode 100644 index 0000000..b414d82 Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-modsecurity-waf.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-overview.png b/doccs/site/public/screenshots/admin-security--tab-overview.png new file mode 100644 index 0000000..1611179 Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-overview.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-ssh.png b/doccs/site/public/screenshots/admin-security--tab-ssh.png new file mode 100644 index 0000000..012372a Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-ssh.png differ diff --git a/doccs/site/public/screenshots/admin-security--tab-vulnerability-scanner.png b/doccs/site/public/screenshots/admin-security--tab-vulnerability-scanner.png new file mode 100644 index 0000000..e7aa16d Binary files /dev/null and b/doccs/site/public/screenshots/admin-security--tab-vulnerability-scanner.png differ diff --git a/doccs/site/public/screenshots/admin-security.png b/doccs/site/public/screenshots/admin-security.png new file mode 100644 index 0000000..1611179 Binary files /dev/null and b/doccs/site/public/screenshots/admin-security.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-database-tuning.png b/doccs/site/public/screenshots/admin-server-settings--tab-database-tuning.png new file mode 100644 index 0000000..1b25340 Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-database-tuning.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-dns.png b/doccs/site/public/screenshots/admin-server-settings--tab-dns.png new file mode 100644 index 0000000..90cd53f Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-dns.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-email.png b/doccs/site/public/screenshots/admin-server-settings--tab-email.png new file mode 100644 index 0000000..31de073 Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-email.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-general.png b/doccs/site/public/screenshots/admin-server-settings--tab-general.png new file mode 100644 index 0000000..a745c29 Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-general.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-notifications.png b/doccs/site/public/screenshots/admin-server-settings--tab-notifications.png new file mode 100644 index 0000000..1c925de Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-notifications.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-php-fpm.png b/doccs/site/public/screenshots/admin-server-settings--tab-php-fpm.png new file mode 100644 index 0000000..65ea45f Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-php-fpm.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings--tab-storage.png b/doccs/site/public/screenshots/admin-server-settings--tab-storage.png new file mode 100644 index 0000000..9ed0ba4 Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings--tab-storage.png differ diff --git a/doccs/site/public/screenshots/admin-server-settings.png b/doccs/site/public/screenshots/admin-server-settings.png new file mode 100644 index 0000000..a745c29 Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-settings.png differ diff --git a/doccs/site/public/screenshots/admin-server-status.png b/doccs/site/public/screenshots/admin-server-status.png new file mode 100644 index 0000000..2204a5d Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-status.png differ diff --git a/doccs/site/public/screenshots/admin-server-updates.png b/doccs/site/public/screenshots/admin-server-updates.png new file mode 100644 index 0000000..5a2172d Binary files /dev/null and b/doccs/site/public/screenshots/admin-server-updates.png differ diff --git a/doccs/site/public/screenshots/admin-services.png b/doccs/site/public/screenshots/admin-services.png new file mode 100644 index 0000000..1ccec0f Binary files /dev/null and b/doccs/site/public/screenshots/admin-services.png differ diff --git a/doccs/site/public/screenshots/admin-ssl-manager.png b/doccs/site/public/screenshots/admin-ssl-manager.png new file mode 100644 index 0000000..e75e384 Binary files /dev/null and b/doccs/site/public/screenshots/admin-ssl-manager.png differ diff --git a/doccs/site/public/screenshots/admin-two-factor-challenge.png b/doccs/site/public/screenshots/admin-two-factor-challenge.png new file mode 100644 index 0000000..4231887 Binary files /dev/null and b/doccs/site/public/screenshots/admin-two-factor-challenge.png differ diff --git a/doccs/site/public/screenshots/admin-users-1-edit.png b/doccs/site/public/screenshots/admin-users-1-edit.png new file mode 100644 index 0000000..f8ed56e Binary files /dev/null and b/doccs/site/public/screenshots/admin-users-1-edit.png differ diff --git a/doccs/site/public/screenshots/admin-users-create.png b/doccs/site/public/screenshots/admin-users-create.png new file mode 100644 index 0000000..3e5e9d5 Binary files /dev/null and b/doccs/site/public/screenshots/admin-users-create.png differ diff --git a/doccs/site/public/screenshots/admin-users-edit.png b/doccs/site/public/screenshots/admin-users-edit.png new file mode 100644 index 0000000..f8ed56e Binary files /dev/null and b/doccs/site/public/screenshots/admin-users-edit.png differ diff --git a/doccs/site/public/screenshots/admin-users.png b/doccs/site/public/screenshots/admin-users.png new file mode 100644 index 0000000..c011d59 Binary files /dev/null and b/doccs/site/public/screenshots/admin-users.png differ diff --git a/doccs/site/public/screenshots/admin-waf.png b/doccs/site/public/screenshots/admin-waf.png new file mode 100644 index 0000000..ebc5268 Binary files /dev/null and b/doccs/site/public/screenshots/admin-waf.png differ diff --git a/doccs/site/public/screenshots/admin-webhook-endpoints-1-edit.png b/doccs/site/public/screenshots/admin-webhook-endpoints-1-edit.png new file mode 100644 index 0000000..7764fa3 Binary files /dev/null and b/doccs/site/public/screenshots/admin-webhook-endpoints-1-edit.png differ diff --git a/doccs/site/public/screenshots/admin-webhook-endpoints-create.png b/doccs/site/public/screenshots/admin-webhook-endpoints-create.png new file mode 100644 index 0000000..b5fe648 Binary files /dev/null and b/doccs/site/public/screenshots/admin-webhook-endpoints-create.png differ diff --git a/doccs/site/public/screenshots/admin-webhook-endpoints-edit.png b/doccs/site/public/screenshots/admin-webhook-endpoints-edit.png new file mode 100644 index 0000000..7764fa3 Binary files /dev/null and b/doccs/site/public/screenshots/admin-webhook-endpoints-edit.png differ diff --git a/doccs/site/public/screenshots/admin-webhook-endpoints.png b/doccs/site/public/screenshots/admin-webhook-endpoints.png new file mode 100644 index 0000000..4537eb4 Binary files /dev/null and b/doccs/site/public/screenshots/admin-webhook-endpoints.png differ diff --git a/doccs/site/public/screenshots/admin-whm-migration.png b/doccs/site/public/screenshots/admin-whm-migration.png new file mode 100644 index 0000000..e47a01c Binary files /dev/null and b/doccs/site/public/screenshots/admin-whm-migration.png differ diff --git a/doccs/site/public/screenshots/user-backup-download.png b/doccs/site/public/screenshots/user-backup-download.png new file mode 100644 index 0000000..e37d205 Binary files /dev/null and b/doccs/site/public/screenshots/user-backup-download.png differ diff --git a/doccs/site/public/screenshots/user-backups--tab-my-backups.png b/doccs/site/public/screenshots/user-backups--tab-my-backups.png new file mode 100644 index 0000000..622d004 Binary files /dev/null and b/doccs/site/public/screenshots/user-backups--tab-my-backups.png differ diff --git a/doccs/site/public/screenshots/user-backups--tab-restore-history.png b/doccs/site/public/screenshots/user-backups--tab-restore-history.png new file mode 100644 index 0000000..e61935b Binary files /dev/null and b/doccs/site/public/screenshots/user-backups--tab-restore-history.png differ diff --git a/doccs/site/public/screenshots/user-backups--tab-server-backups.png b/doccs/site/public/screenshots/user-backups--tab-server-backups.png new file mode 100644 index 0000000..26d6b5b Binary files /dev/null and b/doccs/site/public/screenshots/user-backups--tab-server-backups.png differ diff --git a/doccs/site/public/screenshots/user-backups--tab-sftp-destinations.png b/doccs/site/public/screenshots/user-backups--tab-sftp-destinations.png new file mode 100644 index 0000000..6dda5e7 Binary files /dev/null and b/doccs/site/public/screenshots/user-backups--tab-sftp-destinations.png differ diff --git a/doccs/site/public/screenshots/user-backups.png b/doccs/site/public/screenshots/user-backups.png new file mode 100644 index 0000000..622d004 Binary files /dev/null and b/doccs/site/public/screenshots/user-backups.png differ diff --git a/doccs/site/public/screenshots/user-cdn-integration.png b/doccs/site/public/screenshots/user-cdn-integration.png new file mode 100644 index 0000000..19ca539 Binary files /dev/null and b/doccs/site/public/screenshots/user-cdn-integration.png differ diff --git a/doccs/site/public/screenshots/user-cpanel-migration.png b/doccs/site/public/screenshots/user-cpanel-migration.png new file mode 100644 index 0000000..76c81a2 Binary files /dev/null and b/doccs/site/public/screenshots/user-cpanel-migration.png differ diff --git a/doccs/site/public/screenshots/user-cron-jobs.png b/doccs/site/public/screenshots/user-cron-jobs.png new file mode 100644 index 0000000..6711257 Binary files /dev/null and b/doccs/site/public/screenshots/user-cron-jobs.png differ diff --git a/doccs/site/public/screenshots/user-dashboard.png b/doccs/site/public/screenshots/user-dashboard.png new file mode 100644 index 0000000..f9b2a38 Binary files /dev/null and b/doccs/site/public/screenshots/user-dashboard.png differ diff --git a/doccs/site/public/screenshots/user-databases.png b/doccs/site/public/screenshots/user-databases.png new file mode 100644 index 0000000..a9b5f24 Binary files /dev/null and b/doccs/site/public/screenshots/user-databases.png differ diff --git a/doccs/site/public/screenshots/user-dns-records.png b/doccs/site/public/screenshots/user-dns-records.png new file mode 100644 index 0000000..467a63c Binary files /dev/null and b/doccs/site/public/screenshots/user-dns-records.png differ diff --git a/doccs/site/public/screenshots/user-domains.png b/doccs/site/public/screenshots/user-domains.png new file mode 100644 index 0000000..f8193a4 Binary files /dev/null and b/doccs/site/public/screenshots/user-domains.png differ diff --git a/doccs/site/public/screenshots/user-email--tab-autoresponders.png b/doccs/site/public/screenshots/user-email--tab-autoresponders.png new file mode 100644 index 0000000..87b8565 Binary files /dev/null and b/doccs/site/public/screenshots/user-email--tab-autoresponders.png differ diff --git a/doccs/site/public/screenshots/user-email--tab-catch-all.png b/doccs/site/public/screenshots/user-email--tab-catch-all.png new file mode 100644 index 0000000..206c277 Binary files /dev/null and b/doccs/site/public/screenshots/user-email--tab-catch-all.png differ diff --git a/doccs/site/public/screenshots/user-email--tab-forwarders.png b/doccs/site/public/screenshots/user-email--tab-forwarders.png new file mode 100644 index 0000000..4041c7a Binary files /dev/null and b/doccs/site/public/screenshots/user-email--tab-forwarders.png differ diff --git a/doccs/site/public/screenshots/user-email--tab-logs.png b/doccs/site/public/screenshots/user-email--tab-logs.png new file mode 100644 index 0000000..2af2b03 Binary files /dev/null and b/doccs/site/public/screenshots/user-email--tab-logs.png differ diff --git a/doccs/site/public/screenshots/user-email--tab-mailboxes.png b/doccs/site/public/screenshots/user-email--tab-mailboxes.png new file mode 100644 index 0000000..dec06fa Binary files /dev/null and b/doccs/site/public/screenshots/user-email--tab-mailboxes.png differ diff --git a/doccs/site/public/screenshots/user-email--tab-spam-settings.png b/doccs/site/public/screenshots/user-email--tab-spam-settings.png new file mode 100644 index 0000000..388ac6f Binary files /dev/null and b/doccs/site/public/screenshots/user-email--tab-spam-settings.png differ diff --git a/doccs/site/public/screenshots/user-email.png b/doccs/site/public/screenshots/user-email.png new file mode 100644 index 0000000..dec06fa Binary files /dev/null and b/doccs/site/public/screenshots/user-email.png differ diff --git a/doccs/site/public/screenshots/user-files.png b/doccs/site/public/screenshots/user-files.png new file mode 100644 index 0000000..dd27c60 Binary files /dev/null and b/doccs/site/public/screenshots/user-files.png differ diff --git a/doccs/site/public/screenshots/user-git-deployment.png b/doccs/site/public/screenshots/user-git-deployment.png new file mode 100644 index 0000000..30e80a5 Binary files /dev/null and b/doccs/site/public/screenshots/user-git-deployment.png differ diff --git a/doccs/site/public/screenshots/user-home.png b/doccs/site/public/screenshots/user-home.png new file mode 100644 index 0000000..3a6a106 Binary files /dev/null and b/doccs/site/public/screenshots/user-home.png differ diff --git a/doccs/site/public/screenshots/user-image-optimization.png b/doccs/site/public/screenshots/user-image-optimization.png new file mode 100644 index 0000000..41274ea Binary files /dev/null and b/doccs/site/public/screenshots/user-image-optimization.png differ diff --git a/doccs/site/public/screenshots/user-login.png b/doccs/site/public/screenshots/user-login.png new file mode 100644 index 0000000..4d10057 Binary files /dev/null and b/doccs/site/public/screenshots/user-login.png differ diff --git a/doccs/site/public/screenshots/user-logs--tab-activity-log.png b/doccs/site/public/screenshots/user-logs--tab-activity-log.png new file mode 100644 index 0000000..ef5ef0f Binary files /dev/null and b/doccs/site/public/screenshots/user-logs--tab-activity-log.png differ diff --git a/doccs/site/public/screenshots/user-logs--tab-logs.png b/doccs/site/public/screenshots/user-logs--tab-logs.png new file mode 100644 index 0000000..5a58df0 Binary files /dev/null and b/doccs/site/public/screenshots/user-logs--tab-logs.png differ diff --git a/doccs/site/public/screenshots/user-logs--tab-statistics.png b/doccs/site/public/screenshots/user-logs--tab-statistics.png new file mode 100644 index 0000000..a66cd0e Binary files /dev/null and b/doccs/site/public/screenshots/user-logs--tab-statistics.png differ diff --git a/doccs/site/public/screenshots/user-logs.png b/doccs/site/public/screenshots/user-logs.png new file mode 100644 index 0000000..5a58df0 Binary files /dev/null and b/doccs/site/public/screenshots/user-logs.png differ diff --git a/doccs/site/public/screenshots/user-mailing-lists.png b/doccs/site/public/screenshots/user-mailing-lists.png new file mode 100644 index 0000000..7fd4532 Binary files /dev/null and b/doccs/site/public/screenshots/user-mailing-lists.png differ diff --git a/doccs/site/public/screenshots/user-password-reset-request.png b/doccs/site/public/screenshots/user-password-reset-request.png new file mode 100644 index 0000000..749a30f Binary files /dev/null and b/doccs/site/public/screenshots/user-password-reset-request.png differ diff --git a/doccs/site/public/screenshots/user-password-reset-reset.png b/doccs/site/public/screenshots/user-password-reset-reset.png new file mode 100644 index 0000000..4f44da7 Binary files /dev/null and b/doccs/site/public/screenshots/user-password-reset-reset.png differ diff --git a/doccs/site/public/screenshots/user-php-settings.png b/doccs/site/public/screenshots/user-php-settings.png new file mode 100644 index 0000000..1b598ce Binary files /dev/null and b/doccs/site/public/screenshots/user-php-settings.png differ diff --git a/doccs/site/public/screenshots/user-postgresql--tab-databases.png b/doccs/site/public/screenshots/user-postgresql--tab-databases.png new file mode 100644 index 0000000..2b693cb Binary files /dev/null and b/doccs/site/public/screenshots/user-postgresql--tab-databases.png differ diff --git a/doccs/site/public/screenshots/user-postgresql--tab-users.png b/doccs/site/public/screenshots/user-postgresql--tab-users.png new file mode 100644 index 0000000..b2626e0 Binary files /dev/null and b/doccs/site/public/screenshots/user-postgresql--tab-users.png differ diff --git a/doccs/site/public/screenshots/user-postgresql.png b/doccs/site/public/screenshots/user-postgresql.png new file mode 100644 index 0000000..2b693cb Binary files /dev/null and b/doccs/site/public/screenshots/user-postgresql.png differ diff --git a/doccs/site/public/screenshots/user-profile.png b/doccs/site/public/screenshots/user-profile.png new file mode 100644 index 0000000..7a9113a Binary files /dev/null and b/doccs/site/public/screenshots/user-profile.png differ diff --git a/doccs/site/public/screenshots/user-protected-directories.png b/doccs/site/public/screenshots/user-protected-directories.png new file mode 100644 index 0000000..6c15adf Binary files /dev/null and b/doccs/site/public/screenshots/user-protected-directories.png differ diff --git a/doccs/site/public/screenshots/user-ssh-keys.png b/doccs/site/public/screenshots/user-ssh-keys.png new file mode 100644 index 0000000..0f4c67f Binary files /dev/null and b/doccs/site/public/screenshots/user-ssh-keys.png differ diff --git a/doccs/site/public/screenshots/user-ssl.png b/doccs/site/public/screenshots/user-ssl.png new file mode 100644 index 0000000..7f45a91 Binary files /dev/null and b/doccs/site/public/screenshots/user-ssl.png differ diff --git a/doccs/site/public/screenshots/user-two-factor-challenge.png b/doccs/site/public/screenshots/user-two-factor-challenge.png new file mode 100644 index 0000000..15481ec Binary files /dev/null and b/doccs/site/public/screenshots/user-two-factor-challenge.png differ diff --git a/doccs/site/public/screenshots/user-wordpress.png b/doccs/site/public/screenshots/user-wordpress.png new file mode 100644 index 0000000..dcc8b2f Binary files /dev/null and b/doccs/site/public/screenshots/user-wordpress.png differ diff --git a/doccs/site/src/assets/houston.webp b/doccs/site/src/assets/houston.webp new file mode 100644 index 0000000..930c164 Binary files /dev/null and b/doccs/site/src/assets/houston.webp differ diff --git a/doccs/site/src/content.config.ts b/doccs/site/src/content.config.ts new file mode 100644 index 0000000..d9ee8c9 --- /dev/null +++ b/doccs/site/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/doccs/site/src/content/docs/admin/automation-api.md b/doccs/site/src/content/docs/admin/automation-api.md new file mode 100644 index 0000000..e61581e --- /dev/null +++ b/doccs/site/src/content/docs/admin/automation-api.md @@ -0,0 +1,21 @@ +--- +title: Api Access +description: Api Access page details, screenshots, and usage examples. +--- + +This page provides api access features for the admin panel. + +## Screenshot + +![Api Access Screenshot](/screenshots/admin-automation-api.png) + +## What this page does + +- This page provides api access features for the admin panel. +- Use api access to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use api access to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/backup-download.md b/doccs/site/src/content/docs/admin/backup-download.md new file mode 100644 index 0000000..5a38d07 --- /dev/null +++ b/doccs/site/src/content/docs/admin/backup-download.md @@ -0,0 +1,21 @@ +--- +title: Backup Download +description: Backup Download page details, screenshots, and usage examples. +--- + +This page provides backup download features for the admin panel. + +## Screenshot + +![Backup Download Screenshot](/screenshots/admin-backup-download.png) + +## What this page does + +- This page provides backup download features for the admin panel. +- Use backup download to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use backup download to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/backups.md b/doccs/site/src/content/docs/admin/backups.md new file mode 100644 index 0000000..5f236cc --- /dev/null +++ b/doccs/site/src/content/docs/admin/backups.md @@ -0,0 +1,55 @@ +--- +title: Backups +description: Backups page details, screenshots, and usage examples. +--- + +Manage backup destinations, schedules, and backup history in one place. + +## Screenshot + +![Backups Screenshot](/screenshots/admin-backups.png) + +## What this page does + +- Manage backup destinations, schedules, and backup history in one place. +- Create a daily schedule with remote storage. +- Verify backups weekly using the restore flow. + +## Typical examples + +- Example 1: Create a daily schedule with remote storage. +- Example 2: Verify backups weekly using the restore flow. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Destinations + +Remote and local backup targets. + +![Backups - Destinations](/screenshots/admin-backups--tab-destinations.png) + +Example: + +- Review destinations settings during onboarding or troubleshooting. + +### Schedules + +Backup schedule configuration and retention. + +![Backups - Schedules](/screenshots/admin-backups--tab-schedules.png) + +Example: + +- Review schedules settings during onboarding or troubleshooting. + +### Backups + +Backup history and run logs. + +![Backups - Backups](/screenshots/admin-backups--tab-backups.png) + +Example: + +- Review backups settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/admin/cpanel-migration.md b/doccs/site/src/content/docs/admin/cpanel-migration.md new file mode 100644 index 0000000..45494fd --- /dev/null +++ b/doccs/site/src/content/docs/admin/cpanel-migration.md @@ -0,0 +1,75 @@ +--- +title: Cpanel Migration +description: Cpanel Migration page details, screenshots, and usage examples. +--- + +This page provides cpanel migration features for the admin panel. + +## Screenshot + +![Cpanel Migration Screenshot](/screenshots/admin-cpanel-migration.png) + +## What this page does + +- This page provides cpanel migration features for the admin panel. +- Use cpanel migration to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use cpanel migration to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Domains + +Imported domain list from cPanel. + +![Cpanel Migration - Domains](/screenshots/admin-cpanel-migration--tab-domains.png) + +Example: + +- Review domains settings during onboarding or troubleshooting. + +### Databases + +Imported database list from cPanel. + +![Cpanel Migration - Databases](/screenshots/admin-cpanel-migration--tab-databases.png) + +Example: + +- Review databases settings during onboarding or troubleshooting. + +### Mailboxes + +Imported mailbox list from cPanel. + +![Cpanel Migration - Mailboxes](/screenshots/admin-cpanel-migration--tab-mailboxes.png) + +Example: + +- Review mailboxes settings during onboarding or troubleshooting. + +### Forwarders + +Imported forwarders from cPanel. + +![Cpanel Migration - Forwarders](/screenshots/admin-cpanel-migration--tab-forwarders.png) + +Example: + +- Review forwarders settings during onboarding or troubleshooting. + +### SSL + +Imported SSL assets from cPanel. + +![Cpanel Migration - SSL](/screenshots/admin-cpanel-migration--tab-ssl.png) + +Example: + +- Review ssl settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/admin/dashboard.md b/doccs/site/src/content/docs/admin/dashboard.md new file mode 100644 index 0000000..751c39a --- /dev/null +++ b/doccs/site/src/content/docs/admin/dashboard.md @@ -0,0 +1,21 @@ +--- +title: Dashboard +description: Dashboard page details, screenshots, and usage examples. +--- + +This dashboard summarizes key activity and server status for quick checks. + +## Screenshot + +![Dashboard Screenshot](/screenshots/admin-dashboard.png) + +## What this page does + +- This dashboard summarizes key activity and server status for quick checks. +- Review health cards and activity to confirm the server is stable. +- Use refresh to re-poll stats after maintenance. + +## Typical examples + +- Example 1: Review health cards and activity to confirm the server is stable. +- Example 2: Use refresh to re-poll stats after maintenance. diff --git a/doccs/site/src/content/docs/admin/database-tuning.md b/doccs/site/src/content/docs/admin/database-tuning.md new file mode 100644 index 0000000..eced0d4 --- /dev/null +++ b/doccs/site/src/content/docs/admin/database-tuning.md @@ -0,0 +1,21 @@ +--- +title: Database Tuning +description: Database Tuning page details, screenshots, and usage examples. +--- + +This page provides database tuning features for the admin panel. + +## Screenshot + +![Database Tuning Screenshot](/screenshots/admin-database-tuning.png) + +## What this page does + +- This page provides database tuning features for the admin panel. +- Use database tuning to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use database tuning to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/dns-zones.md b/doccs/site/src/content/docs/admin/dns-zones.md new file mode 100644 index 0000000..040736d --- /dev/null +++ b/doccs/site/src/content/docs/admin/dns-zones.md @@ -0,0 +1,21 @@ +--- +title: Dns Zones +description: Dns Zones page details, screenshots, and usage examples. +--- + +This page provides dns zones features for the admin panel. + +## Screenshot + +![Dns Zones Screenshot](/screenshots/admin-dns-zones.png) + +## What this page does + +- This page provides dns zones features for the admin panel. +- Use dns zones to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use dns zones to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/email-logs.md b/doccs/site/src/content/docs/admin/email-logs.md new file mode 100644 index 0000000..976911e --- /dev/null +++ b/doccs/site/src/content/docs/admin/email-logs.md @@ -0,0 +1,21 @@ +--- +title: Email Logs +description: Email Logs page details, screenshots, and usage examples. +--- + +This page provides email logs features for the admin panel. + +## Screenshot + +![Email Logs Screenshot](/screenshots/admin-email-logs.png) + +## What this page does + +- This page provides email logs features for the admin panel. +- Use email logs to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use email logs to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/email-queue.md b/doccs/site/src/content/docs/admin/email-queue.md new file mode 100644 index 0000000..e4ca1e7 --- /dev/null +++ b/doccs/site/src/content/docs/admin/email-queue.md @@ -0,0 +1,21 @@ +--- +title: Email Queue +description: Email Queue page details, screenshots, and usage examples. +--- + +This page provides email queue features for the admin panel. + +## Screenshot + +![Email Queue Screenshot](/screenshots/admin-email-queue.png) + +## What this page does + +- This page provides email queue features for the admin panel. +- Use email queue to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use email queue to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/geo-block-rules-create.md b/doccs/site/src/content/docs/admin/geo-block-rules-create.md new file mode 100644 index 0000000..dfdcce9 --- /dev/null +++ b/doccs/site/src/content/docs/admin/geo-block-rules-create.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Geo-Block-Rules/Create +description: Jabali-Admin/Geo-Block-Rules/Create page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/geo-block-rules/create features for the admin panel. + +## Screenshot + +![Jabali-Admin/Geo-Block-Rules/Create Screenshot](/screenshots/admin-geo-block-rules-create.png) + +## What this page does + +- This page provides jabali-admin/geo-block-rules/create features for the admin panel. +- Use jabali-admin/geo-block-rules/create to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/geo-block-rules/create to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/geo-block-rules-edit.md b/doccs/site/src/content/docs/admin/geo-block-rules-edit.md new file mode 100644 index 0000000..22d726d --- /dev/null +++ b/doccs/site/src/content/docs/admin/geo-block-rules-edit.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Geo-Block-Rules/{Record}/Edit +description: Jabali-Admin/Geo-Block-Rules/{Record}/Edit page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/geo-block-rules/{record}/edit features for the admin panel. + +## Screenshot + +![Jabali-Admin/Geo-Block-Rules/{Record}/Edit Screenshot](/screenshots/admin-geo-block-rules-edit.png) + +## What this page does + +- This page provides jabali-admin/geo-block-rules/{record}/edit features for the admin panel. +- Use jabali-admin/geo-block-rules/{record}/edit to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/geo-block-rules/{record}/edit to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/geo-block-rules.md b/doccs/site/src/content/docs/admin/geo-block-rules.md new file mode 100644 index 0000000..05f883c --- /dev/null +++ b/doccs/site/src/content/docs/admin/geo-block-rules.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Geo-Block-Rules +description: Jabali-Admin/Geo-Block-Rules page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/geo-block-rules features for the admin panel. + +## Screenshot + +![Jabali-Admin/Geo-Block-Rules Screenshot](/screenshots/admin-geo-block-rules.png) + +## What this page does + +- This page provides jabali-admin/geo-block-rules features for the admin panel. +- Use jabali-admin/geo-block-rules to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/geo-block-rules to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/home.md b/doccs/site/src/content/docs/admin/home.md new file mode 100644 index 0000000..ab132a5 --- /dev/null +++ b/doccs/site/src/content/docs/admin/home.md @@ -0,0 +1,21 @@ +--- +title: Home +description: Home page details, screenshots, and usage examples. +--- + +This page provides home features for the admin panel. + +## Screenshot + +![Home Screenshot](/screenshots/admin-home.png) + +## What this page does + +- This page provides home features for the admin panel. +- Use home to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use home to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/hosting-packages-create.md b/doccs/site/src/content/docs/admin/hosting-packages-create.md new file mode 100644 index 0000000..1428018 --- /dev/null +++ b/doccs/site/src/content/docs/admin/hosting-packages-create.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Hosting-Packages/Create +description: Jabali-Admin/Hosting-Packages/Create page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/hosting-packages/create features for the admin panel. + +## Screenshot + +![Jabali-Admin/Hosting-Packages/Create Screenshot](/screenshots/admin-hosting-packages-create.png) + +## What this page does + +- This page provides jabali-admin/hosting-packages/create features for the admin panel. +- Use jabali-admin/hosting-packages/create to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/hosting-packages/create to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/hosting-packages-edit.md b/doccs/site/src/content/docs/admin/hosting-packages-edit.md new file mode 100644 index 0000000..699f8bc --- /dev/null +++ b/doccs/site/src/content/docs/admin/hosting-packages-edit.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Hosting-Packages/{Record}/Edit +description: Jabali-Admin/Hosting-Packages/{Record}/Edit page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/hosting-packages/{record}/edit features for the admin panel. + +## Screenshot + +![Jabali-Admin/Hosting-Packages/{Record}/Edit Screenshot](/screenshots/admin-hosting-packages-edit.png) + +## What this page does + +- This page provides jabali-admin/hosting-packages/{record}/edit features for the admin panel. +- Use jabali-admin/hosting-packages/{record}/edit to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/hosting-packages/{record}/edit to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/hosting-packages.md b/doccs/site/src/content/docs/admin/hosting-packages.md new file mode 100644 index 0000000..4979838 --- /dev/null +++ b/doccs/site/src/content/docs/admin/hosting-packages.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Hosting-Packages +description: Jabali-Admin/Hosting-Packages page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/hosting-packages features for the admin panel. + +## Screenshot + +![Jabali-Admin/Hosting-Packages Screenshot](/screenshots/admin-hosting-packages.png) + +## What this page does + +- This page provides jabali-admin/hosting-packages features for the admin panel. +- Use jabali-admin/hosting-packages to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/hosting-packages to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/index.md b/doccs/site/src/content/docs/admin/index.md new file mode 100644 index 0000000..08e87ce --- /dev/null +++ b/doccs/site/src/content/docs/admin/index.md @@ -0,0 +1,18 @@ +--- +title: Admin Panel +description: Admin panel features and screenshots. +sidebar: + order: 1 +--- + +The admin panel is the control center for server-wide management. It is designed for hosting providers and server administrators who need full visibility into services, users, security, and system health. + +## What you can do here + +- Monitor server health and performance +- Manage users, domains, and quotas +- Configure DNS and mail services +- Manage backups and restores +- Review security posture and service status + +Each page below includes an up-to-date screenshot and a short explanation of the feature set. diff --git a/doccs/site/src/content/docs/admin/ip-addresses.md b/doccs/site/src/content/docs/admin/ip-addresses.md new file mode 100644 index 0000000..d92c33a --- /dev/null +++ b/doccs/site/src/content/docs/admin/ip-addresses.md @@ -0,0 +1,21 @@ +--- +title: Ip Addresses +description: Ip Addresses page details, screenshots, and usage examples. +--- + +This page provides ip addresses features for the admin panel. + +## Screenshot + +![Ip Addresses Screenshot](/screenshots/admin-ip-addresses.png) + +## What this page does + +- This page provides ip addresses features for the admin panel. +- Use ip addresses to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use ip addresses to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/login.md b/doccs/site/src/content/docs/admin/login.md new file mode 100644 index 0000000..d8dba11 --- /dev/null +++ b/doccs/site/src/content/docs/admin/login.md @@ -0,0 +1,21 @@ +--- +title: Login +description: Login page details, screenshots, and usage examples. +--- + +This page provides login features for the admin panel. + +## Screenshot + +![Login Screenshot](/screenshots/admin-login.png) + +## What this page does + +- This page provides login features for the admin panel. +- Use login to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use login to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/migration.md b/doccs/site/src/content/docs/admin/migration.md new file mode 100644 index 0000000..c10d65b --- /dev/null +++ b/doccs/site/src/content/docs/admin/migration.md @@ -0,0 +1,45 @@ +--- +title: Migration +description: Migration page details, screenshots, and usage examples. +--- + +This page provides migration features for the admin panel. + +## Screenshot + +![Migration Screenshot](/screenshots/admin-migration.png) + +## What this page does + +- This page provides migration features for the admin panel. +- Use migration to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use migration to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### cPanel Migration + +cPanel migration workflow. + +![Migration - cPanel Migration](/screenshots/admin-migration--tab-cpanel-migration.png) + +Example: + +- Review cpanel migration settings during onboarding or troubleshooting. + +### WHM Migration + +WHM migration workflow. + +![Migration - WHM Migration](/screenshots/admin-migration--tab-whm-migration.png) + +Example: + +- Review whm migration settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/admin/password-reset-request.md b/doccs/site/src/content/docs/admin/password-reset-request.md new file mode 100644 index 0000000..e96b695 --- /dev/null +++ b/doccs/site/src/content/docs/admin/password-reset-request.md @@ -0,0 +1,21 @@ +--- +title: Password Reset Request +description: Password Reset Request page details, screenshots, and usage examples. +--- + +This page provides password reset request features for the admin panel. + +## Screenshot + +![Password Reset Request Screenshot](/screenshots/admin-password-reset-request.png) + +## What this page does + +- This page provides password reset request features for the admin panel. +- Use password reset request to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use password reset request to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/password-reset-reset.md b/doccs/site/src/content/docs/admin/password-reset-reset.md new file mode 100644 index 0000000..757376f --- /dev/null +++ b/doccs/site/src/content/docs/admin/password-reset-reset.md @@ -0,0 +1,21 @@ +--- +title: Password Reset +description: Password Reset page details, screenshots, and usage examples. +--- + +This page provides password reset features for the admin panel. + +## Screenshot + +![Password Reset Screenshot](/screenshots/admin-password-reset-reset.png) + +## What this page does + +- This page provides password reset features for the admin panel. +- Use password reset to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use password reset to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/php-manager.md b/doccs/site/src/content/docs/admin/php-manager.md new file mode 100644 index 0000000..d2994fd --- /dev/null +++ b/doccs/site/src/content/docs/admin/php-manager.md @@ -0,0 +1,21 @@ +--- +title: Php Manager +description: Php Manager page details, screenshots, and usage examples. +--- + +This page provides php manager features for the admin panel. + +## Screenshot + +![Php Manager Screenshot](/screenshots/admin-php-manager.png) + +## What this page does + +- This page provides php manager features for the admin panel. +- Use php manager to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use php manager to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/security.md b/doccs/site/src/content/docs/admin/security.md new file mode 100644 index 0000000..6c70ae4 --- /dev/null +++ b/doccs/site/src/content/docs/admin/security.md @@ -0,0 +1,95 @@ +--- +title: Security +description: Security page details, screenshots, and usage examples. +--- + +Security center for firewall, WAF, scanning, and SSH access control. + +## Screenshot + +![Security Screenshot](/screenshots/admin-security.png) + +## What this page does + +- Security center for firewall, WAF, scanning, and SSH access control. +- Review firewall rules after adding new services. +- Run vulnerability scans after major updates. + +## Typical examples + +- Example 1: Review firewall rules after adding new services. +- Example 2: Run vulnerability scans after major updates. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Overview + +Security summary with recent events. + +![Security - Overview](/screenshots/admin-security--tab-overview.png) + +Example: + +- Review overview settings during onboarding or troubleshooting. + +### Firewall + +UFW rules and port access control. + +![Security - Firewall](/screenshots/admin-security--tab-firewall.png) + +Example: + +- Review firewall settings during onboarding or troubleshooting. + +### ModSecurity / WAF + +WAF rules, logs, and request filtering. + +![Security - ModSecurity / WAF](/screenshots/admin-security--tab-modsecurity-waf.png) + +Example: + +- Review modsecurity / waf settings during onboarding or troubleshooting. + +### Fail2ban + +Login protection and jail settings. + +![Security - Fail2ban](/screenshots/admin-security--tab-fail2ban.png) + +Example: + +- Review fail2ban settings during onboarding or troubleshooting. + +### Antivirus + +ClamAV status and scan controls. + +![Security - Antivirus](/screenshots/admin-security--tab-antivirus.png) + +Example: + +- Review antivirus settings during onboarding or troubleshooting. + +### SSH + +SSH access settings and recent logins. + +![Security - SSH](/screenshots/admin-security--tab-ssh.png) + +Example: + +- Review ssh settings during onboarding or troubleshooting. + +### Vulnerability Scanner + +Scan results and remediation guidance. + +![Security - Vulnerability Scanner](/screenshots/admin-security--tab-vulnerability-scanner.png) + +Example: + +- Review vulnerability scanner settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/admin/server-settings.md b/doccs/site/src/content/docs/admin/server-settings.md new file mode 100644 index 0000000..e1e264b --- /dev/null +++ b/doccs/site/src/content/docs/admin/server-settings.md @@ -0,0 +1,95 @@ +--- +title: Server Settings +description: Server Settings page details, screenshots, and usage examples. +--- + +Central configuration for global DNS, storage, notifications, and runtime defaults. + +## Screenshot + +![Server Settings Screenshot](/screenshots/admin-server-settings.png) + +## What this page does + +- Central configuration for global DNS, storage, notifications, and runtime defaults. +- Add notification recipients before production go-live. +- Tune PHP-FPM defaults if performance needs adjustment. + +## Typical examples + +- Example 1: Add notification recipients before production go-live. +- Example 2: Tune PHP-FPM defaults if performance needs adjustment. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### General + +Base panel identity, system defaults, and global settings. + +![Server Settings - General](/screenshots/admin-server-settings--tab-general.png) + +Example: + +- Review general settings during onboarding or troubleshooting. + +### DNS + +Nameserver and DNS behavior configuration. + +![Server Settings - DNS](/screenshots/admin-server-settings--tab-dns.png) + +Example: + +- Review dns settings during onboarding or troubleshooting. + +### Storage + +Disk and backup storage settings. + +![Server Settings - Storage](/screenshots/admin-server-settings--tab-storage.png) + +Example: + +- Review storage settings during onboarding or troubleshooting. + +### Email + +Mail defaults and system mail configuration. + +![Server Settings - Email](/screenshots/admin-server-settings--tab-email.png) + +Example: + +- Review email settings during onboarding or troubleshooting. + +### Notifications + +Alert destinations, thresholds, and notification toggles. + +![Server Settings - Notifications](/screenshots/admin-server-settings--tab-notifications.png) + +Example: + +- Review notifications settings during onboarding or troubleshooting. + +### PHP-FPM + +Runtime defaults for PHP-FPM pools and limits. + +![Server Settings - PHP-FPM](/screenshots/admin-server-settings--tab-php-fpm.png) + +Example: + +- Review php-fpm settings during onboarding or troubleshooting. + +### Database Tuning + +MariaDB and database performance parameters. + +![Server Settings - Database Tuning](/screenshots/admin-server-settings--tab-database-tuning.png) + +Example: + +- Review database tuning settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/admin/server-status.md b/doccs/site/src/content/docs/admin/server-status.md new file mode 100644 index 0000000..3c2f8fb --- /dev/null +++ b/doccs/site/src/content/docs/admin/server-status.md @@ -0,0 +1,21 @@ +--- +title: Server Status +description: Server Status page details, screenshots, and usage examples. +--- + +Live charts and service indicators help diagnose resource or service issues. + +## Screenshot + +![Server Status Screenshot](/screenshots/admin-server-status.png) + +## What this page does + +- Live charts and service indicators help diagnose resource or service issues. +- Check CPU and memory trends when users report slowness. +- Verify service status after restarts or upgrades. + +## Typical examples + +- Example 1: Check CPU and memory trends when users report slowness. +- Example 2: Verify service status after restarts or upgrades. diff --git a/doccs/site/src/content/docs/admin/server-updates.md b/doccs/site/src/content/docs/admin/server-updates.md new file mode 100644 index 0000000..885d3dd --- /dev/null +++ b/doccs/site/src/content/docs/admin/server-updates.md @@ -0,0 +1,21 @@ +--- +title: System Updates +description: System Updates page details, screenshots, and usage examples. +--- + +This page provides system updates features for the admin panel. + +## Screenshot + +![System Updates Screenshot](/screenshots/admin-server-updates.png) + +## What this page does + +- This page provides system updates features for the admin panel. +- Use system updates to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use system updates to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/services.md b/doccs/site/src/content/docs/admin/services.md new file mode 100644 index 0000000..e927d98 --- /dev/null +++ b/doccs/site/src/content/docs/admin/services.md @@ -0,0 +1,21 @@ +--- +title: Services +description: Services page details, screenshots, and usage examples. +--- + +This page provides services features for the admin panel. + +## Screenshot + +![Services Screenshot](/screenshots/admin-services.png) + +## What this page does + +- This page provides services features for the admin panel. +- Use services to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use services to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/ssl-manager.md b/doccs/site/src/content/docs/admin/ssl-manager.md new file mode 100644 index 0000000..7b5cb4c --- /dev/null +++ b/doccs/site/src/content/docs/admin/ssl-manager.md @@ -0,0 +1,21 @@ +--- +title: Ssl Manager +description: Ssl Manager page details, screenshots, and usage examples. +--- + +This page provides ssl manager features for the admin panel. + +## Screenshot + +![Ssl Manager Screenshot](/screenshots/admin-ssl-manager.png) + +## What this page does + +- This page provides ssl manager features for the admin panel. +- Use ssl manager to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use ssl manager to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/two-factor-challenge.md b/doccs/site/src/content/docs/admin/two-factor-challenge.md new file mode 100644 index 0000000..1a5e742 --- /dev/null +++ b/doccs/site/src/content/docs/admin/two-factor-challenge.md @@ -0,0 +1,21 @@ +--- +title: Two-Factor Challenge +description: Two-Factor Challenge page details, screenshots, and usage examples. +--- + +This page provides two-factor challenge features for the admin panel. + +## Screenshot + +![Two-Factor Challenge Screenshot](/screenshots/admin-two-factor-challenge.png) + +## What this page does + +- This page provides two-factor challenge features for the admin panel. +- Use two-factor challenge to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use two-factor challenge to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/users-create.md b/doccs/site/src/content/docs/admin/users-create.md new file mode 100644 index 0000000..8b64e08 --- /dev/null +++ b/doccs/site/src/content/docs/admin/users-create.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Users/Create +description: Jabali-Admin/Users/Create page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/users/create features for the admin panel. + +## Screenshot + +![Jabali-Admin/Users/Create Screenshot](/screenshots/admin-users-create.png) + +## What this page does + +- This page provides jabali-admin/users/create features for the admin panel. +- Use jabali-admin/users/create to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/users/create to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/users-edit.md b/doccs/site/src/content/docs/admin/users-edit.md new file mode 100644 index 0000000..106f8dd --- /dev/null +++ b/doccs/site/src/content/docs/admin/users-edit.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Users/{Record}/Edit +description: Jabali-Admin/Users/{Record}/Edit page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/users/{record}/edit features for the admin panel. + +## Screenshot + +![Jabali-Admin/Users/{Record}/Edit Screenshot](/screenshots/admin-users-edit.png) + +## What this page does + +- This page provides jabali-admin/users/{record}/edit features for the admin panel. +- Use jabali-admin/users/{record}/edit to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/users/{record}/edit to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/users.md b/doccs/site/src/content/docs/admin/users.md new file mode 100644 index 0000000..2a83cdc --- /dev/null +++ b/doccs/site/src/content/docs/admin/users.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Users +description: Jabali-Admin/Users page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/users features for the admin panel. + +## Screenshot + +![Jabali-Admin/Users Screenshot](/screenshots/admin-users.png) + +## What this page does + +- This page provides jabali-admin/users features for the admin panel. +- Use jabali-admin/users to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/users to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/waf.md b/doccs/site/src/content/docs/admin/waf.md new file mode 100644 index 0000000..711c7b3 --- /dev/null +++ b/doccs/site/src/content/docs/admin/waf.md @@ -0,0 +1,21 @@ +--- +title: Modsecurity / Waf +description: Modsecurity / Waf page details, screenshots, and usage examples. +--- + +This page provides modsecurity / waf features for the admin panel. + +## Screenshot + +![Modsecurity / Waf Screenshot](/screenshots/admin-waf.png) + +## What this page does + +- This page provides modsecurity / waf features for the admin panel. +- Use modsecurity / waf to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use modsecurity / waf to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/webhook-endpoints-create.md b/doccs/site/src/content/docs/admin/webhook-endpoints-create.md new file mode 100644 index 0000000..0612dbe --- /dev/null +++ b/doccs/site/src/content/docs/admin/webhook-endpoints-create.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Webhook-Endpoints/Create +description: Jabali-Admin/Webhook-Endpoints/Create page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/webhook-endpoints/create features for the admin panel. + +## Screenshot + +![Jabali-Admin/Webhook-Endpoints/Create Screenshot](/screenshots/admin-webhook-endpoints-create.png) + +## What this page does + +- This page provides jabali-admin/webhook-endpoints/create features for the admin panel. +- Use jabali-admin/webhook-endpoints/create to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/webhook-endpoints/create to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/webhook-endpoints-edit.md b/doccs/site/src/content/docs/admin/webhook-endpoints-edit.md new file mode 100644 index 0000000..8fc7082 --- /dev/null +++ b/doccs/site/src/content/docs/admin/webhook-endpoints-edit.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Webhook-Endpoints/{Record}/Edit +description: Jabali-Admin/Webhook-Endpoints/{Record}/Edit page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/webhook-endpoints/{record}/edit features for the admin panel. + +## Screenshot + +![Jabali-Admin/Webhook-Endpoints/{Record}/Edit Screenshot](/screenshots/admin-webhook-endpoints-edit.png) + +## What this page does + +- This page provides jabali-admin/webhook-endpoints/{record}/edit features for the admin panel. +- Use jabali-admin/webhook-endpoints/{record}/edit to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/webhook-endpoints/{record}/edit to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/webhook-endpoints.md b/doccs/site/src/content/docs/admin/webhook-endpoints.md new file mode 100644 index 0000000..f659631 --- /dev/null +++ b/doccs/site/src/content/docs/admin/webhook-endpoints.md @@ -0,0 +1,21 @@ +--- +title: Jabali-Admin/Webhook-Endpoints +description: Jabali-Admin/Webhook-Endpoints page details, screenshots, and usage examples. +--- + +This page provides jabali-admin/webhook-endpoints features for the admin panel. + +## Screenshot + +![Jabali-Admin/Webhook-Endpoints Screenshot](/screenshots/admin-webhook-endpoints.png) + +## What this page does + +- This page provides jabali-admin/webhook-endpoints features for the admin panel. +- Use jabali-admin/webhook-endpoints to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use jabali-admin/webhook-endpoints to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/admin/whm-migration.md b/doccs/site/src/content/docs/admin/whm-migration.md new file mode 100644 index 0000000..57b9862 --- /dev/null +++ b/doccs/site/src/content/docs/admin/whm-migration.md @@ -0,0 +1,21 @@ +--- +title: Whm Migration +description: Whm Migration page details, screenshots, and usage examples. +--- + +This page provides whm migration features for the admin panel. + +## Screenshot + +![Whm Migration Screenshot](/screenshots/admin-whm-migration.png) + +## What this page does + +- This page provides whm migration features for the admin panel. +- Use whm migration to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use whm migration to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/index.mdx b/doccs/site/src/content/docs/index.mdx new file mode 100644 index 0000000..eccc37f --- /dev/null +++ b/doccs/site/src/content/docs/index.mdx @@ -0,0 +1,37 @@ +--- +title: Jabali Panel Documentation +description: Feature overview and screenshots for the Jabali hosting panel. +--- + +Welcome to the Jabali Panel documentation site. This site focuses on product features and provides up-to-date screenshots for both the admin and user panels. + +## Start here + +- Read the [Overview](/overview) for a quick product tour. +- Browse the [Admin Panel](/admin/dashboard) features. +- Browse the [User Panel](/user/dashboard) features. +- Learn about platform services under [Platform](/platform/stack). + +## Feature highlights + +### Admin panel + +![Admin Dashboard](/screenshots/admin-dashboard.png) + +### User panel + +![User Dashboard](/screenshots/user-dashboard.png) + +## Screenshot library + +All screenshots are generated from the live panel using the repo script: + +~~~ +node tests/take-screenshots.cjs --output-dir=docs/screenshots +~~~ + +The documentation site uses a copy of those images at: + +~~~ +/var/www/jabali/doccs/site/public/screenshots +~~~ diff --git a/doccs/site/src/content/docs/overview.md b/doccs/site/src/content/docs/overview.md new file mode 100644 index 0000000..e2b9a4d --- /dev/null +++ b/doccs/site/src/content/docs/overview.md @@ -0,0 +1,32 @@ +--- +title: Overview +description: Product overview, panels, and key services. +sidebar: + order: 1 +--- + +Jabali is a modern hosting control panel for WordPress and general PHP hosting. It combines a user-friendly interface with a privileged agent to perform system operations safely and consistently. + +## Panels + +- **Admin panel** (/jabali-admin): server-wide management, service health, security, backups, and global settings. +- **User panel** (/jabali-panel): per-account hosting tasks like domains, email, databases, and backups. + +## Core ideas + +- **Automation-first**: UI actions map to reliable backend jobs. +- **Isolation**: each user is isolated at the OS and service level. +- **Observability**: health checks, logs, and notifications are built in. +- **Consistency**: the agent applies changes using repeatable, auditable steps. + +## Where to find screenshots + +- Admin features: [Admin Panel](/admin/dashboard) +- User features: [User Panel](/user/dashboard) +- Platform services: [Platform](/platform/stack) + +## Typical workflows + +- **New server setup**: verify services, configure DNS and mail, set alerting. +- **Onboard user**: create user, set quotas, add domains, issue SSL. +- **Routine operations**: review health, run backups, rotate credentials. diff --git a/doccs/site/src/content/docs/platform/agent.md b/doccs/site/src/content/docs/platform/agent.md new file mode 100644 index 0000000..f46cb9a --- /dev/null +++ b/doccs/site/src/content/docs/platform/agent.md @@ -0,0 +1,27 @@ +--- +title: Privileged Agent +description: Root-level automation for system tasks. +sidebar: + order: 2 +--- + +The jabali-agent daemon runs as root and executes system-level tasks that cannot be safely handled by the web app alone. + +## Responsibilities + +- System user creation and deletion +- Vhost and PHP-FPM pool configuration +- SSL certificate issuance and renewal +- DNS zone updates +- Mail domain and mailbox operations +- Backup and restore workflows + +## Why it exists + +- Ensures privileged operations are centralized and auditable +- Reduces direct root access requirements in the UI +- Allows consistent, repeatable system changes + +## Communication + +- The panel communicates with the agent over a local Unix socket at /var/run/jabali/agent.sock. diff --git a/doccs/site/src/content/docs/platform/backups.md b/doccs/site/src/content/docs/platform/backups.md new file mode 100644 index 0000000..7fb127f --- /dev/null +++ b/doccs/site/src/content/docs/platform/backups.md @@ -0,0 +1,28 @@ +--- +title: Backup System +description: Local and remote backups with restore options. +sidebar: + order: 4 +--- + +Backups are available for individual users and for the full server. They include files, databases, mail, and configuration data. + +## Backup types + +- User backups stored under /home//backups +- Server backups stored under /var/backups/jabali +- Incremental backups to remote targets + +## Restore coverage + +- Website files +- Databases and users +- Mailboxes +- SSL certificates +- DNS zone files + +## Best practices + +- Keep at least one remote destination +- Test restores on a schedule +- Maintain retention policies to save storage diff --git a/doccs/site/src/content/docs/platform/cli.md b/doccs/site/src/content/docs/platform/cli.md new file mode 100644 index 0000000..6e7d6b1 --- /dev/null +++ b/doccs/site/src/content/docs/platform/cli.md @@ -0,0 +1,308 @@ +--- +title: Jabali CLI +description: Full command reference with options and examples. +sidebar: + order: 6 +--- + +The Jabali CLI is a full-featured administrative interface to the panel and the privileged agent. Use it for automation, server tasks, backups, migrations, and operational maintenance. + +## Run location + +Run all commands from the repo root: + +~~~ +cd /var/www/jabali +~~~ + +## Global help and options + +~~~ +jabali --help +jabali --help-full +jabali --version +~~~ + +Global options: + +- `-h`, `--help` show help +- `--help-full` show full command list +- `-v`, `--version` show version +- `-y`, `--yes` auto-confirm prompts +- `-q`, `--quiet` quiet mode + +## User management + +Commands: + +~~~ +jabali user list +jabali user create [--email=] [--password=] +jabali user show +jabali user delete +jabali user password [--password=] +jabali user suspend +jabali user unsuspend +~~~ + +Notes: + +- `user create` creates a system user through the agent and a panel user in the database. +- `user password` updates both the panel password and system user password. + +## Domain management + +Commands: + +~~~ +jabali domain list [--user=] +jabali domain create --user= +jabali domain show +jabali domain delete +jabali domain enable +jabali domain disable +~~~ + +Notes: + +- `domain create` triggers agent provisioning and then creates the panel record. + +## Service management + +Commands: + +~~~ +jabali service list +jabali service status +jabali service start +jabali service stop +jabali service restart +jabali service enable +jabali service disable +~~~ + +Services include common system daemons and any installed PHP-FPM versions. + +## WordPress tools + +Commands: + +~~~ +jabali wp list +jabali wp install [--title=] [--admin=<user>] [--email=<email>] [--password=<pass>] +jabali wp scan <username> +jabali wp import <username> <path> +jabali wp delete <username> <site_id> [--files] [--database] +jabali wp update <username> <site_id> +~~~ + +Notes: + +- `wp install` will generate a password if one is not provided. +- `wp scan` discovers existing WordPress installs under a user. + +## Database tools (MariaDB) + +Commands: + +~~~ +jabali db list [--user=<username>] +jabali db create <db_name> [--user=<username>] +jabali db delete <db_name> +jabali db users [--user=<username>] +jabali db user-create <username> [--password=<password>] [--host=<host>] +jabali db user-delete <username> [--host=<host>] +~~~ + +Notes: + +- `db list` defaults to `admin` unless `--user` is provided. +- User creation validates password complexity if provided. + +## Email (mailboxes) + +Commands: + +~~~ +jabali mail list [--domain=<domain>] +jabali mail create <email> [--password=<password>] [--quota=<mb>] +jabali mail delete <email> +jabali mail password <email> [--password=<password>] +jabali mail quota <email> <size_mb> +jabali mail domains +~~~ + +Notes: + +- `mail domains` lists domains with mail enabled and DKIM status. + +## Backups (users + server) + +### Local and user backups + +~~~ +jabali backup list [--user=<user>] +jabali backup user-list <user> +jabali backup create <user> [--type=full|incremental] [--output=<path>] [--incremental-base=<path>] + [--domains=a,b] [--databases=a,b] [--mailboxes=a,b] + [--no-files] [--no-databases] [--no-mailboxes] [--no-dns] [--no-ssl] + +jabali backup restore <path> [<user>] + [--user=<user>] [--domains=a,b] [--databases=a,b] [--mailboxes=a,b] + [--no-files] [--no-databases] [--no-mailboxes] [--no-dns] [--no-ssl] + +jabali backup info <path> +jabali backup verify <path> +jabali backup delete <file|id> [--user=<user>] +~~~ + +### Server backups + +~~~ +jabali backup server [--type=full|incremental] [--users=u1,u2] [--dest=<id>] +jabali backup server-list +~~~ + +### Backup history (database) + +~~~ +jabali backup history [--limit=<n>] [--status=<status>] [--type=<type>] +jabali backup show <id> +~~~ + +### Backup schedules + +~~~ +jabali backup schedules +jabali backup schedule-create --name=<name> [--frequency=daily|weekly] [--time=HH:MM] + [--retention=<n>] [--dest=<id>] [--backup-type=full|incremental] + [--no-files] [--no-databases] [--no-mailboxes] [--no-dns] + +jabali backup schedule-run <id> +jabali backup schedule-enable <id> +jabali backup schedule-disable <id> +jabali backup schedule-delete <id> +~~~ + +### Backup destinations + +~~~ +jabali backup destinations +jabali backup dest-add --type=sftp --name=<name> --host=<host> --user=<user> [--password=<pass>] [--port=22] [--path=/backups] + +jabali backup dest-add --type=nfs --name=<name> --host=<host> --path=<remote-path> [--mount=/mnt/backup] + +jabali backup dest-add --type=s3 --name=<name> --bucket=<name> --key=<access-key> --secret=<secret-key> [--region=us-east-1] [--path=prefix] + +jabali backup dest-test <id> +jabali backup dest-delete <id> +~~~ + +## cPanel migration + +Commands: + +~~~ +jabali cpanel analyze <file> [--timeout=600] +jabali cpanel restore <file> <user> + [--no-files] [--no-databases] [--no-emails] [--no-ssl] + [--log=/path/to/log.jsonl] [--analyze] [--timeout=7200] + +jabali cpanel fix-permissions <file> +~~~ + +Notes: + +- `cpanel restore` requires the panel user and the system user to already exist. +- `--analyze` runs analysis and reuses results before restore. + +## System information + +Commands: + +~~~ +jabali system info +jabali system status +jabali system hostname [<new-hostname>] +jabali system disk +jabali system memory +~~~ + +## Agent control + +Commands: + +~~~ +jabali agent status +jabali agent start +jabali agent stop +jabali agent restart +jabali agent ping +jabali agent log [--lines=<n>] +~~~ + +## PHP versions + +Commands: + +~~~ +jabali php list +jabali php install <version> +jabali php uninstall <version> +jabali php default [<version>] +jabali php status +~~~ + +Notes: + +- `php default` without a version prints the current default. + +## Firewall (UFW) + +Commands: + +~~~ +jabali firewall status +jabali firewall enable +jabali firewall disable +jabali firewall rules +jabali firewall allow <port> +jabali firewall deny <port> +jabali firewall delete <rule_number> +~~~ + +## SSL certificates + +Commands: + +~~~ +jabali ssl check [<domain>] [--issue-only] [--renew-only] +jabali ssl issue <domain> [--force] +jabali ssl renew <domain> +jabali ssl status <domain> +jabali ssl list +~~~ + +## Example workflows + +### Onboard a new user and domain + +~~~ +jabali user create demo --email=demo@example.com +jabali domain create example.com --user=demo +jabali ssl issue example.com +~~~ + +### Create and verify a user backup + +~~~ +jabali backup create demo --type=full +jabali backup verify /home/demo/backups/demo_2026-02-04_120000.tar.gz +~~~ + +### Run a cPanel migration + +~~~ +jabali cpanel analyze /var/backups/jabali/cpanel-migrations/site.tar.gz +jabali cpanel restore /var/backups/jabali/cpanel-migrations/site.tar.gz demo +~~~ diff --git a/doccs/site/src/content/docs/platform/dnssec.md b/doccs/site/src/content/docs/platform/dnssec.md new file mode 100644 index 0000000..49e2b6b --- /dev/null +++ b/doccs/site/src/content/docs/platform/dnssec.md @@ -0,0 +1,27 @@ +--- +title: DNSSEC +description: DNSSEC management and DS records. +sidebar: + order: 5 +--- + +DNSSEC adds cryptographic signatures to DNS records for stronger integrity guarantees. + +## What it does + +- Signs DNS zones with cryptographic keys +- Lets resolvers validate responses +- Reduces risk of DNS spoofing + +## Setup flow + +1. Enable DNSSEC for a domain +2. Copy the DS record from the panel +3. Add the DS record at the registrar +4. Wait for propagation + +## Management tips + +- Rotate keys only when necessary +- Keep DS records in sync with the panel +- Monitor for DNSSEC validation errors diff --git a/doccs/site/src/content/docs/platform/index.md b/doccs/site/src/content/docs/platform/index.md new file mode 100644 index 0000000..c48078d --- /dev/null +++ b/doccs/site/src/content/docs/platform/index.md @@ -0,0 +1,8 @@ +--- +title: Platform +description: Core services and operational tooling. +sidebar: + order: 1 +--- + +The platform section covers core services, privileged automation, monitoring, backups, DNSSEC, and the Jabali CLI. diff --git a/doccs/site/src/content/docs/platform/monitoring.md b/doccs/site/src/content/docs/platform/monitoring.md new file mode 100644 index 0000000..a2a2c99 --- /dev/null +++ b/doccs/site/src/content/docs/platform/monitoring.md @@ -0,0 +1,29 @@ +--- +title: Monitoring and Alerts +description: Health monitoring, logs, and notifications. +sidebar: + order: 3 +--- + +Jabali includes a health monitor daemon and a notification system to keep administrators informed. + +## Health monitor + +- Checks critical services every 30 seconds +- Attempts automatic restarts on failures +- Logs events to /var/log/jabali/health-monitor.log + +## Alert types + +- SSL expiration and errors +- Backup failures +- Disk quota warnings +- Login failures +- Service health alerts +- High load notifications + +## Operational tips + +- Configure alert recipients during initial setup +- Test the mail sender before relying on alerts +- Review notification logs during incidents diff --git a/doccs/site/src/content/docs/platform/stack.md b/doccs/site/src/content/docs/platform/stack.md new file mode 100644 index 0000000..e018149 --- /dev/null +++ b/doccs/site/src/content/docs/platform/stack.md @@ -0,0 +1,28 @@ +--- +title: Platform Stack +description: Core services and runtime components. +sidebar: + order: 1 +--- + +Jabali uses a modern Laravel application for the control plane and a privileged agent for system operations. + +## Application stack + +- Laravel 12 with Filament v5 and Livewire v4 +- Tailwind-based UI +- SQLite for panel metadata + +## Service stack + +- Nginx and PHP-FPM +- MariaDB for user databases +- Postfix, Dovecot, and Rspamd for mail +- BIND9 for DNS +- Redis for cache and queue + +## Runtime targets + +- Debian 12 or 13 +- PHP 8.4 +- Node 20 and Vite for assets diff --git a/doccs/site/src/content/docs/user/backup-download.md b/doccs/site/src/content/docs/user/backup-download.md new file mode 100644 index 0000000..1b0c094 --- /dev/null +++ b/doccs/site/src/content/docs/user/backup-download.md @@ -0,0 +1,21 @@ +--- +title: Backup Download +description: Backup Download page details, screenshots, and usage examples. +--- + +This page provides backup download features for the jabali panel. + +## Screenshot + +![Backup Download Screenshot](/screenshots/user-backup-download.png) + +## What this page does + +- This page provides backup download features for the jabali panel. +- Use backup download to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use backup download to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/backups.md b/doccs/site/src/content/docs/user/backups.md new file mode 100644 index 0000000..5ff1e6e --- /dev/null +++ b/doccs/site/src/content/docs/user/backups.md @@ -0,0 +1,65 @@ +--- +title: Backups +description: Backups page details, screenshots, and usage examples. +--- + +Manage backup destinations, schedules, and backup history in one place. + +## Screenshot + +![Backups Screenshot](/screenshots/user-backups.png) + +## What this page does + +- Manage backup destinations, schedules, and backup history in one place. +- Create a daily schedule with remote storage. +- Verify backups weekly using the restore flow. + +## Typical examples + +- Example 1: Create a daily schedule with remote storage. +- Example 2: Verify backups weekly using the restore flow. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### My Backups + +User-owned backups and restore points. + +![Backups - My Backups](/screenshots/user-backups--tab-my-backups.png) + +Example: + +- Review my backups settings during onboarding or troubleshooting. + +### Server Backups + +Server-level backups available to the user. + +![Backups - Server Backups](/screenshots/user-backups--tab-server-backups.png) + +Example: + +- Review server backups settings during onboarding or troubleshooting. + +### SFTP Destinations + +Remote destinations for backups. + +![Backups - SFTP Destinations](/screenshots/user-backups--tab-sftp-destinations.png) + +Example: + +- Review sftp destinations settings during onboarding or troubleshooting. + +### Restore History + +Log of recent restore actions. + +![Backups - Restore History](/screenshots/user-backups--tab-restore-history.png) + +Example: + +- Review restore history settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/user/cdn-integration.md b/doccs/site/src/content/docs/user/cdn-integration.md new file mode 100644 index 0000000..219fc36 --- /dev/null +++ b/doccs/site/src/content/docs/user/cdn-integration.md @@ -0,0 +1,21 @@ +--- +title: Cdn Integration +description: Cdn Integration page details, screenshots, and usage examples. +--- + +This page provides cdn integration features for the jabali panel. + +## Screenshot + +![Cdn Integration Screenshot](/screenshots/user-cdn-integration.png) + +## What this page does + +- This page provides cdn integration features for the jabali panel. +- Use cdn integration to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use cdn integration to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/cpanel-migration.md b/doccs/site/src/content/docs/user/cpanel-migration.md new file mode 100644 index 0000000..2b1f281 --- /dev/null +++ b/doccs/site/src/content/docs/user/cpanel-migration.md @@ -0,0 +1,75 @@ +--- +title: Cpanel Migration +description: Cpanel Migration page details, screenshots, and usage examples. +--- + +This page provides cpanel migration features for the jabali panel. + +## Screenshot + +![Cpanel Migration Screenshot](/screenshots/user-cpanel-migration.png) + +## What this page does + +- This page provides cpanel migration features for the jabali panel. +- Use cpanel migration to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use cpanel migration to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Domains + +Imported domain list from cPanel. + +![Cpanel Migration - Domains](/screenshots/user-cpanel-migration--tab-domains.png) + +Example: + +- Review domains settings during onboarding or troubleshooting. + +### Databases + +Imported database list from cPanel. + +![Cpanel Migration - Databases](/screenshots/user-cpanel-migration--tab-databases.png) + +Example: + +- Review databases settings during onboarding or troubleshooting. + +### Mailboxes + +Imported mailbox list from cPanel. + +![Cpanel Migration - Mailboxes](/screenshots/user-cpanel-migration--tab-mailboxes.png) + +Example: + +- Review mailboxes settings during onboarding or troubleshooting. + +### Forwarders + +Imported forwarders from cPanel. + +![Cpanel Migration - Forwarders](/screenshots/user-cpanel-migration--tab-forwarders.png) + +Example: + +- Review forwarders settings during onboarding or troubleshooting. + +### SSL + +Imported SSL assets from cPanel. + +![Cpanel Migration - SSL](/screenshots/user-cpanel-migration--tab-ssl.png) + +Example: + +- Review ssl settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/user/cron-jobs.md b/doccs/site/src/content/docs/user/cron-jobs.md new file mode 100644 index 0000000..d80c067 --- /dev/null +++ b/doccs/site/src/content/docs/user/cron-jobs.md @@ -0,0 +1,21 @@ +--- +title: Cron Jobs +description: Cron Jobs page details, screenshots, and usage examples. +--- + +This page provides cron jobs features for the jabali panel. + +## Screenshot + +![Cron Jobs Screenshot](/screenshots/user-cron-jobs.png) + +## What this page does + +- This page provides cron jobs features for the jabali panel. +- Use cron jobs to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use cron jobs to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/dashboard.md b/doccs/site/src/content/docs/user/dashboard.md new file mode 100644 index 0000000..16ca915 --- /dev/null +++ b/doccs/site/src/content/docs/user/dashboard.md @@ -0,0 +1,22 @@ +--- +title: Dashboard +description: User overview of resources and recent activity. +sidebar: + order: 2 +--- + +The user dashboard is the landing view after login. It summarizes current usage and highlights key actions. + +## What you see + +- Domain and mailbox counts +- Database usage +- SSL coverage summary +- Recent activity and backups + +## Why it matters + +- Detect limits before they become a problem +- Jump into key tasks with fewer clicks + +![User Dashboard](/screenshots/user-dashboard.png) diff --git a/doccs/site/src/content/docs/user/databases.md b/doccs/site/src/content/docs/user/databases.md new file mode 100644 index 0000000..0c108c7 --- /dev/null +++ b/doccs/site/src/content/docs/user/databases.md @@ -0,0 +1,21 @@ +--- +title: Databases +description: Databases page details, screenshots, and usage examples. +--- + +This page provides databases features for the jabali panel. + +## Screenshot + +![Databases Screenshot](/screenshots/user-databases.png) + +## What this page does + +- This page provides databases features for the jabali panel. +- Use databases to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use databases to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/dns-records.md b/doccs/site/src/content/docs/user/dns-records.md new file mode 100644 index 0000000..d7bfc9a --- /dev/null +++ b/doccs/site/src/content/docs/user/dns-records.md @@ -0,0 +1,21 @@ +--- +title: Dns Records +description: Dns Records page details, screenshots, and usage examples. +--- + +This page provides dns records features for the jabali panel. + +## Screenshot + +![Dns Records Screenshot](/screenshots/user-dns-records.png) + +## What this page does + +- This page provides dns records features for the jabali panel. +- Use dns records to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use dns records to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/domains.md b/doccs/site/src/content/docs/user/domains.md new file mode 100644 index 0000000..aeb9c3e --- /dev/null +++ b/doccs/site/src/content/docs/user/domains.md @@ -0,0 +1,21 @@ +--- +title: Domains +description: Domains page details, screenshots, and usage examples. +--- + +Domain management for hosting sites, SSL, and DNS integration. + +## Screenshot + +![Domains Screenshot](/screenshots/user-domains.png) + +## What this page does + +- Domain management for hosting sites, SSL, and DNS integration. +- Add a new domain and issue SSL. +- Set a redirect when decommissioning a site. + +## Typical examples + +- Example 1: Add a new domain and issue SSL. +- Example 2: Set a redirect when decommissioning a site. diff --git a/doccs/site/src/content/docs/user/email.md b/doccs/site/src/content/docs/user/email.md new file mode 100644 index 0000000..7033acc --- /dev/null +++ b/doccs/site/src/content/docs/user/email.md @@ -0,0 +1,85 @@ +--- +title: Email +description: Email page details, screenshots, and usage examples. +--- + +Email management for domains, mailboxes, and spam controls. + +## Screenshot + +![Email Screenshot](/screenshots/user-email.png) + +## What this page does + +- Email management for domains, mailboxes, and spam controls. +- Create mailboxes for new staff accounts. +- Adjust spam settings after a deliverability issue. + +## Typical examples + +- Example 1: Create mailboxes for new staff accounts. +- Example 2: Adjust spam settings after a deliverability issue. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Mailboxes + +Imported mailbox list from cPanel. + +![Email - Mailboxes](/screenshots/user-email--tab-mailboxes.png) + +Example: + +- Review mailboxes settings during onboarding or troubleshooting. + +### Forwarders + +Imported forwarders from cPanel. + +![Email - Forwarders](/screenshots/user-email--tab-forwarders.png) + +Example: + +- Review forwarders settings during onboarding or troubleshooting. + +### Autoresponders + +Automatic replies for mailboxes. + +![Email - Autoresponders](/screenshots/user-email--tab-autoresponders.png) + +Example: + +- Review autoresponders settings during onboarding or troubleshooting. + +### Catch-All + +Domain-wide catch-all routing. + +![Email - Catch-All](/screenshots/user-email--tab-catch-all.png) + +Example: + +- Review catch-all settings during onboarding or troubleshooting. + +### Logs + +Raw log entries for troubleshooting. + +![Email - Logs](/screenshots/user-email--tab-logs.png) + +Example: + +- Review logs settings during onboarding or troubleshooting. + +### Spam Settings + +Spam filtering and scoring. + +![Email - Spam Settings](/screenshots/user-email--tab-spam-settings.png) + +Example: + +- Review spam settings settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/user/files.md b/doccs/site/src/content/docs/user/files.md new file mode 100644 index 0000000..2064a33 --- /dev/null +++ b/doccs/site/src/content/docs/user/files.md @@ -0,0 +1,21 @@ +--- +title: Files +description: Files page details, screenshots, and usage examples. +--- + +This page provides files features for the jabali panel. + +## Screenshot + +![Files Screenshot](/screenshots/user-files.png) + +## What this page does + +- This page provides files features for the jabali panel. +- Use files to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use files to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/git-deployment.md b/doccs/site/src/content/docs/user/git-deployment.md new file mode 100644 index 0000000..85b83cc --- /dev/null +++ b/doccs/site/src/content/docs/user/git-deployment.md @@ -0,0 +1,21 @@ +--- +title: Git Deployment +description: Git Deployment page details, screenshots, and usage examples. +--- + +This page provides git deployment features for the jabali panel. + +## Screenshot + +![Git Deployment Screenshot](/screenshots/user-git-deployment.png) + +## What this page does + +- This page provides git deployment features for the jabali panel. +- Use git deployment to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use git deployment to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/home.md b/doccs/site/src/content/docs/user/home.md new file mode 100644 index 0000000..5234a9c --- /dev/null +++ b/doccs/site/src/content/docs/user/home.md @@ -0,0 +1,21 @@ +--- +title: Dashboard +description: Dashboard page details, screenshots, and usage examples. +--- + +This page provides dashboard features for the jabali panel. + +## Screenshot + +![Dashboard Screenshot](/screenshots/user-home.png) + +## What this page does + +- This page provides dashboard features for the jabali panel. +- Use dashboard to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use dashboard to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/image-optimization.md b/doccs/site/src/content/docs/user/image-optimization.md new file mode 100644 index 0000000..5da8f5b --- /dev/null +++ b/doccs/site/src/content/docs/user/image-optimization.md @@ -0,0 +1,21 @@ +--- +title: Image Optimization +description: Image Optimization page details, screenshots, and usage examples. +--- + +This page provides image optimization features for the jabali panel. + +## Screenshot + +![Image Optimization Screenshot](/screenshots/user-image-optimization.png) + +## What this page does + +- This page provides image optimization features for the jabali panel. +- Use image optimization to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use image optimization to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/index.md b/doccs/site/src/content/docs/user/index.md new file mode 100644 index 0000000..4dc0729 --- /dev/null +++ b/doccs/site/src/content/docs/user/index.md @@ -0,0 +1,16 @@ +--- +title: User Panel +description: User panel features and screenshots. +sidebar: + order: 1 +--- + +The user panel is designed for everyday hosting tasks. It gives users full control over their domains, email, databases, and backups while keeping the experience simple. + +## What users can do + +- Add and manage domains +- Configure DNS records +- Manage email mailboxes and forwarders +- Install and maintain WordPress +- Create backups and restore data diff --git a/doccs/site/src/content/docs/user/login.md b/doccs/site/src/content/docs/user/login.md new file mode 100644 index 0000000..c324b6d --- /dev/null +++ b/doccs/site/src/content/docs/user/login.md @@ -0,0 +1,21 @@ +--- +title: Login +description: Login page details, screenshots, and usage examples. +--- + +This page provides login features for the jabali panel. + +## Screenshot + +![Login Screenshot](/screenshots/user-login.png) + +## What this page does + +- This page provides login features for the jabali panel. +- Use login to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use login to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/logs.md b/doccs/site/src/content/docs/user/logs.md new file mode 100644 index 0000000..051e8b8 --- /dev/null +++ b/doccs/site/src/content/docs/user/logs.md @@ -0,0 +1,55 @@ +--- +title: Logs & Statistics +description: Logs & Statistics page details, screenshots, and usage examples. +--- + +This page provides logs & statistics features for the jabali panel. + +## Screenshot + +![Logs & Statistics Screenshot](/screenshots/user-logs.png) + +## What this page does + +- This page provides logs & statistics features for the jabali panel. +- Use logs & statistics to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use logs & statistics to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Logs + +Raw log entries for troubleshooting. + +![Logs & Statistics - Logs](/screenshots/user-logs--tab-logs.png) + +Example: + +- Review logs settings during onboarding or troubleshooting. + +### Statistics + +Aggregated usage and traffic metrics. + +![Logs & Statistics - Statistics](/screenshots/user-logs--tab-statistics.png) + +Example: + +- Review statistics settings during onboarding or troubleshooting. + +### Activity Log + +User actions and important events. + +![Logs & Statistics - Activity Log](/screenshots/user-logs--tab-activity-log.png) + +Example: + +- Review activity log settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/user/mailing-lists.md b/doccs/site/src/content/docs/user/mailing-lists.md new file mode 100644 index 0000000..0817756 --- /dev/null +++ b/doccs/site/src/content/docs/user/mailing-lists.md @@ -0,0 +1,21 @@ +--- +title: Mailing Lists +description: Mailing Lists page details, screenshots, and usage examples. +--- + +This page provides mailing lists features for the jabali panel. + +## Screenshot + +![Mailing Lists Screenshot](/screenshots/user-mailing-lists.png) + +## What this page does + +- This page provides mailing lists features for the jabali panel. +- Use mailing lists to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use mailing lists to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/password-reset-request.md b/doccs/site/src/content/docs/user/password-reset-request.md new file mode 100644 index 0000000..95888e7 --- /dev/null +++ b/doccs/site/src/content/docs/user/password-reset-request.md @@ -0,0 +1,21 @@ +--- +title: Password Reset Request +description: Password Reset Request page details, screenshots, and usage examples. +--- + +This page provides password reset request features for the jabali panel. + +## Screenshot + +![Password Reset Request Screenshot](/screenshots/user-password-reset-request.png) + +## What this page does + +- This page provides password reset request features for the jabali panel. +- Use password reset request to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use password reset request to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/password-reset-reset.md b/doccs/site/src/content/docs/user/password-reset-reset.md new file mode 100644 index 0000000..92c49a9 --- /dev/null +++ b/doccs/site/src/content/docs/user/password-reset-reset.md @@ -0,0 +1,21 @@ +--- +title: Password Reset +description: Password Reset page details, screenshots, and usage examples. +--- + +This page provides password reset features for the jabali panel. + +## Screenshot + +![Password Reset Screenshot](/screenshots/user-password-reset-reset.png) + +## What this page does + +- This page provides password reset features for the jabali panel. +- Use password reset to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use password reset to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/php-settings.md b/doccs/site/src/content/docs/user/php-settings.md new file mode 100644 index 0000000..e085cf1 --- /dev/null +++ b/doccs/site/src/content/docs/user/php-settings.md @@ -0,0 +1,21 @@ +--- +title: Php Settings +description: Php Settings page details, screenshots, and usage examples. +--- + +This page provides php settings features for the jabali panel. + +## Screenshot + +![Php Settings Screenshot](/screenshots/user-php-settings.png) + +## What this page does + +- This page provides php settings features for the jabali panel. +- Use php settings to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use php settings to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/postgresql.md b/doccs/site/src/content/docs/user/postgresql.md new file mode 100644 index 0000000..863e4fe --- /dev/null +++ b/doccs/site/src/content/docs/user/postgresql.md @@ -0,0 +1,45 @@ +--- +title: Postgresql +description: Postgresql page details, screenshots, and usage examples. +--- + +This page provides postgresql features for the jabali panel. + +## Screenshot + +![Postgresql Screenshot](/screenshots/user-postgresql.png) + +## What this page does + +- This page provides postgresql features for the jabali panel. +- Use postgresql to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use postgresql to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. + +## Tabs + +This page contains tabs. Each tab is captured and explained below. + +### Databases + +Imported database list from cPanel. + +![Postgresql - Databases](/screenshots/user-postgresql--tab-databases.png) + +Example: + +- Review databases settings during onboarding or troubleshooting. + +### Users + +Database user accounts and privileges. + +![Postgresql - Users](/screenshots/user-postgresql--tab-users.png) + +Example: + +- Review users settings during onboarding or troubleshooting. diff --git a/doccs/site/src/content/docs/user/profile.md b/doccs/site/src/content/docs/user/profile.md new file mode 100644 index 0000000..30f3f99 --- /dev/null +++ b/doccs/site/src/content/docs/user/profile.md @@ -0,0 +1,21 @@ +--- +title: Profile +description: Profile page details, screenshots, and usage examples. +--- + +This page provides profile features for the jabali panel. + +## Screenshot + +![Profile Screenshot](/screenshots/user-profile.png) + +## What this page does + +- This page provides profile features for the jabali panel. +- Use profile to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use profile to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/protected-directories.md b/doccs/site/src/content/docs/user/protected-directories.md new file mode 100644 index 0000000..735e94b --- /dev/null +++ b/doccs/site/src/content/docs/user/protected-directories.md @@ -0,0 +1,21 @@ +--- +title: Protected Directories +description: Protected Directories page details, screenshots, and usage examples. +--- + +This page provides protected directories features for the jabali panel. + +## Screenshot + +![Protected Directories Screenshot](/screenshots/user-protected-directories.png) + +## What this page does + +- This page provides protected directories features for the jabali panel. +- Use protected directories to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use protected directories to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/ssh-keys.md b/doccs/site/src/content/docs/user/ssh-keys.md new file mode 100644 index 0000000..c044d45 --- /dev/null +++ b/doccs/site/src/content/docs/user/ssh-keys.md @@ -0,0 +1,21 @@ +--- +title: Ssh & Sftp +description: Ssh & Sftp page details, screenshots, and usage examples. +--- + +This page provides ssh & sftp features for the jabali panel. + +## Screenshot + +![Ssh & Sftp Screenshot](/screenshots/user-ssh-keys.png) + +## What this page does + +- This page provides ssh & sftp features for the jabali panel. +- Use ssh & sftp to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use ssh & sftp to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/ssl.md b/doccs/site/src/content/docs/user/ssl.md new file mode 100644 index 0000000..436a34f --- /dev/null +++ b/doccs/site/src/content/docs/user/ssl.md @@ -0,0 +1,21 @@ +--- +title: Ssl Certificates +description: Ssl Certificates page details, screenshots, and usage examples. +--- + +This page provides ssl certificates features for the jabali panel. + +## Screenshot + +![Ssl Certificates Screenshot](/screenshots/user-ssl.png) + +## What this page does + +- This page provides ssl certificates features for the jabali panel. +- Use ssl certificates to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use ssl certificates to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/two-factor-challenge.md b/doccs/site/src/content/docs/user/two-factor-challenge.md new file mode 100644 index 0000000..bd6c19b --- /dev/null +++ b/doccs/site/src/content/docs/user/two-factor-challenge.md @@ -0,0 +1,21 @@ +--- +title: Two-Factor Challenge +description: Two-Factor Challenge page details, screenshots, and usage examples. +--- + +This page provides two-factor challenge features for the jabali panel. + +## Screenshot + +![Two-Factor Challenge Screenshot](/screenshots/user-two-factor-challenge.png) + +## What this page does + +- This page provides two-factor challenge features for the jabali panel. +- Use two-factor challenge to complete common operational tasks. +- Review this page after configuration changes to confirm results. + +## Typical examples + +- Example 1: Use two-factor challenge to complete common operational tasks. +- Example 2: Review this page after configuration changes to confirm results. diff --git a/doccs/site/src/content/docs/user/wordpress.md b/doccs/site/src/content/docs/user/wordpress.md new file mode 100644 index 0000000..b0d177d --- /dev/null +++ b/doccs/site/src/content/docs/user/wordpress.md @@ -0,0 +1,21 @@ +--- +title: Wordpress +description: Wordpress page details, screenshots, and usage examples. +--- + +WordPress tools for installs, updates, and security actions. + +## Screenshot + +![Wordpress Screenshot](/screenshots/user-wordpress.png) + +## What this page does + +- WordPress tools for installs, updates, and security actions. +- Install WordPress for a new site in one click. +- Run a security scan after updates. + +## Typical examples + +- Example 1: Install WordPress for a new site in one click. +- Example 2: Run a security scan after updates. diff --git a/doccs/site/tsconfig.json b/doccs/site/tsconfig.json new file mode 100644 index 0000000..8bf91d3 --- /dev/null +++ b/doccs/site/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"] +} diff --git a/docs/architecture/control-panel-blueprint.md b/docs/architecture/control-panel-blueprint.md index f2f864d..2aa6d60 100644 --- a/docs/architecture/control-panel-blueprint.md +++ b/docs/architecture/control-panel-blueprint.md @@ -126,3 +126,8 @@ This blueprint describes a modern web hosting control panel (cPanel/DirectAdmin- - Read-only middleware should block data mutations but allow authentication. - Demo deployments may run without privileged agent sockets; provide static demo data for agent-dependent pages. - Reverse proxy must be trusted to ensure Livewire update URLs are HTTPS. +## Documentation Coverage Notes + +- Documentation screenshots are generated for every admin and user page, including tabs where available. +- cPanel Migration tabs (Domains, Databases, Mailboxes, Forwarders, SSL) appear only after a backup is analyzed. Without a sample backup, those tab screenshots cannot be captured. +- To complete coverage, provide a cPanel backup archive and run the screenshot capture flow after analysis. diff --git a/docs/screenshots/admin-backups.png b/docs/screenshots/admin-backups.png index 3b7f3d4..3c7d5b6 100644 Binary files a/docs/screenshots/admin-backups.png and b/docs/screenshots/admin-backups.png differ diff --git a/docs/screenshots/admin-dashboard.png b/docs/screenshots/admin-dashboard.png index 1adbf5a..d878802 100644 Binary files a/docs/screenshots/admin-dashboard.png and b/docs/screenshots/admin-dashboard.png differ diff --git a/docs/screenshots/admin-dns-zones.png b/docs/screenshots/admin-dns-zones.png index 925de19..aeae42e 100644 Binary files a/docs/screenshots/admin-dns-zones.png and b/docs/screenshots/admin-dns-zones.png differ diff --git a/docs/screenshots/admin-security.png b/docs/screenshots/admin-security.png index a46bea9..ff75312 100644 Binary files a/docs/screenshots/admin-security.png and b/docs/screenshots/admin-security.png differ diff --git a/docs/screenshots/admin-server-settings.png b/docs/screenshots/admin-server-settings.png index eab7433..16c1b4f 100644 Binary files a/docs/screenshots/admin-server-settings.png and b/docs/screenshots/admin-server-settings.png differ diff --git a/docs/screenshots/admin-server-status.png b/docs/screenshots/admin-server-status.png index a4e2c3a..a850028 100644 Binary files a/docs/screenshots/admin-server-status.png and b/docs/screenshots/admin-server-status.png differ diff --git a/docs/screenshots/admin-services.png b/docs/screenshots/admin-services.png index 2ed2459..0abfc1e 100644 Binary files a/docs/screenshots/admin-services.png and b/docs/screenshots/admin-services.png differ diff --git a/docs/screenshots/admin-ssl-manager.png b/docs/screenshots/admin-ssl-manager.png index 789a9e7..15a8a21 100644 Binary files a/docs/screenshots/admin-ssl-manager.png and b/docs/screenshots/admin-ssl-manager.png differ diff --git a/docs/screenshots/admin-users.png b/docs/screenshots/admin-users.png index e4710a7..58fc74b 100644 Binary files a/docs/screenshots/admin-users.png and b/docs/screenshots/admin-users.png differ diff --git a/docs/screenshots/full/admin-automation-api.png b/docs/screenshots/full/admin-automation-api.png new file mode 100644 index 0000000..029e4a4 Binary files /dev/null and b/docs/screenshots/full/admin-automation-api.png differ diff --git a/docs/screenshots/full/admin-backup-download.png b/docs/screenshots/full/admin-backup-download.png new file mode 100644 index 0000000..d3c2d62 Binary files /dev/null and b/docs/screenshots/full/admin-backup-download.png differ diff --git a/docs/screenshots/full/admin-backups--tab-backups.png b/docs/screenshots/full/admin-backups--tab-backups.png new file mode 100644 index 0000000..4d889a1 Binary files /dev/null and b/docs/screenshots/full/admin-backups--tab-backups.png differ diff --git a/docs/screenshots/full/admin-backups--tab-destinations.png b/docs/screenshots/full/admin-backups--tab-destinations.png new file mode 100644 index 0000000..3250684 Binary files /dev/null and b/docs/screenshots/full/admin-backups--tab-destinations.png differ diff --git a/docs/screenshots/full/admin-backups--tab-schedules.png b/docs/screenshots/full/admin-backups--tab-schedules.png new file mode 100644 index 0000000..91e70ab Binary files /dev/null and b/docs/screenshots/full/admin-backups--tab-schedules.png differ diff --git a/docs/screenshots/full/admin-backups.png b/docs/screenshots/full/admin-backups.png new file mode 100644 index 0000000..3250684 Binary files /dev/null and b/docs/screenshots/full/admin-backups.png differ diff --git a/docs/screenshots/full/admin-cpanel-migration.png b/docs/screenshots/full/admin-cpanel-migration.png new file mode 100644 index 0000000..431679f Binary files /dev/null and b/docs/screenshots/full/admin-cpanel-migration.png differ diff --git a/docs/screenshots/full/admin-dashboard.png b/docs/screenshots/full/admin-dashboard.png new file mode 100644 index 0000000..2c913fc Binary files /dev/null and b/docs/screenshots/full/admin-dashboard.png differ diff --git a/docs/screenshots/full/admin-database-tuning.png b/docs/screenshots/full/admin-database-tuning.png new file mode 100644 index 0000000..63c95fc Binary files /dev/null and b/docs/screenshots/full/admin-database-tuning.png differ diff --git a/docs/screenshots/full/admin-dns-zones.png b/docs/screenshots/full/admin-dns-zones.png new file mode 100644 index 0000000..955e643 Binary files /dev/null and b/docs/screenshots/full/admin-dns-zones.png differ diff --git a/docs/screenshots/full/admin-email-logs.png b/docs/screenshots/full/admin-email-logs.png new file mode 100644 index 0000000..38b095c Binary files /dev/null and b/docs/screenshots/full/admin-email-logs.png differ diff --git a/docs/screenshots/full/admin-email-queue.png b/docs/screenshots/full/admin-email-queue.png new file mode 100644 index 0000000..38b095c Binary files /dev/null and b/docs/screenshots/full/admin-email-queue.png differ diff --git a/docs/screenshots/full/admin-geo-block-rules-create.png b/docs/screenshots/full/admin-geo-block-rules-create.png new file mode 100644 index 0000000..dc7f9ed Binary files /dev/null and b/docs/screenshots/full/admin-geo-block-rules-create.png differ diff --git a/docs/screenshots/full/admin-geo-block-rules-edit.png b/docs/screenshots/full/admin-geo-block-rules-edit.png new file mode 100644 index 0000000..c2a17c2 Binary files /dev/null and b/docs/screenshots/full/admin-geo-block-rules-edit.png differ diff --git a/docs/screenshots/full/admin-geo-block-rules.png b/docs/screenshots/full/admin-geo-block-rules.png new file mode 100644 index 0000000..8d532af Binary files /dev/null and b/docs/screenshots/full/admin-geo-block-rules.png differ diff --git a/docs/screenshots/full/admin-home.png b/docs/screenshots/full/admin-home.png new file mode 100644 index 0000000..2c913fc Binary files /dev/null and b/docs/screenshots/full/admin-home.png differ diff --git a/docs/screenshots/full/admin-hosting-packages-create.png b/docs/screenshots/full/admin-hosting-packages-create.png new file mode 100644 index 0000000..03ac40a Binary files /dev/null and b/docs/screenshots/full/admin-hosting-packages-create.png differ diff --git a/docs/screenshots/full/admin-hosting-packages-edit.png b/docs/screenshots/full/admin-hosting-packages-edit.png new file mode 100644 index 0000000..0476fa2 Binary files /dev/null and b/docs/screenshots/full/admin-hosting-packages-edit.png differ diff --git a/docs/screenshots/full/admin-hosting-packages.png b/docs/screenshots/full/admin-hosting-packages.png new file mode 100644 index 0000000..87a6a67 Binary files /dev/null and b/docs/screenshots/full/admin-hosting-packages.png differ diff --git a/docs/screenshots/full/admin-ip-addresses.png b/docs/screenshots/full/admin-ip-addresses.png new file mode 100644 index 0000000..b38642c Binary files /dev/null and b/docs/screenshots/full/admin-ip-addresses.png differ diff --git a/docs/screenshots/full/admin-login.png b/docs/screenshots/full/admin-login.png new file mode 100644 index 0000000..cc31f1f Binary files /dev/null and b/docs/screenshots/full/admin-login.png differ diff --git a/docs/screenshots/full/admin-migration--tab-cpanel-migration.png b/docs/screenshots/full/admin-migration--tab-cpanel-migration.png new file mode 100644 index 0000000..1693a74 Binary files /dev/null and b/docs/screenshots/full/admin-migration--tab-cpanel-migration.png differ diff --git a/docs/screenshots/full/admin-migration--tab-whm-migration.png b/docs/screenshots/full/admin-migration--tab-whm-migration.png new file mode 100644 index 0000000..536b96e Binary files /dev/null and b/docs/screenshots/full/admin-migration--tab-whm-migration.png differ diff --git a/docs/screenshots/full/admin-migration.png b/docs/screenshots/full/admin-migration.png new file mode 100644 index 0000000..1693a74 Binary files /dev/null and b/docs/screenshots/full/admin-migration.png differ diff --git a/docs/screenshots/full/admin-password-reset-request.png b/docs/screenshots/full/admin-password-reset-request.png new file mode 100644 index 0000000..ec6075d Binary files /dev/null and b/docs/screenshots/full/admin-password-reset-request.png differ diff --git a/docs/screenshots/full/admin-password-reset-reset.png b/docs/screenshots/full/admin-password-reset-reset.png new file mode 100644 index 0000000..4f44da7 Binary files /dev/null and b/docs/screenshots/full/admin-password-reset-reset.png differ diff --git a/docs/screenshots/full/admin-php-manager.png b/docs/screenshots/full/admin-php-manager.png new file mode 100644 index 0000000..234a681 Binary files /dev/null and b/docs/screenshots/full/admin-php-manager.png differ diff --git a/docs/screenshots/full/admin-security--tab-antivirus.png b/docs/screenshots/full/admin-security--tab-antivirus.png new file mode 100644 index 0000000..012372a Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-antivirus.png differ diff --git a/docs/screenshots/full/admin-security--tab-fail2ban.png b/docs/screenshots/full/admin-security--tab-fail2ban.png new file mode 100644 index 0000000..012372a Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-fail2ban.png differ diff --git a/docs/screenshots/full/admin-security--tab-firewall.png b/docs/screenshots/full/admin-security--tab-firewall.png new file mode 100644 index 0000000..35c33fc Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-firewall.png differ diff --git a/docs/screenshots/full/admin-security--tab-modsecurity-waf.png b/docs/screenshots/full/admin-security--tab-modsecurity-waf.png new file mode 100644 index 0000000..b414d82 Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-modsecurity-waf.png differ diff --git a/docs/screenshots/full/admin-security--tab-overview.png b/docs/screenshots/full/admin-security--tab-overview.png new file mode 100644 index 0000000..1611179 Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-overview.png differ diff --git a/docs/screenshots/full/admin-security--tab-ssh.png b/docs/screenshots/full/admin-security--tab-ssh.png new file mode 100644 index 0000000..012372a Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-ssh.png differ diff --git a/docs/screenshots/full/admin-security--tab-vulnerability-scanner.png b/docs/screenshots/full/admin-security--tab-vulnerability-scanner.png new file mode 100644 index 0000000..e7aa16d Binary files /dev/null and b/docs/screenshots/full/admin-security--tab-vulnerability-scanner.png differ diff --git a/docs/screenshots/full/admin-security.png b/docs/screenshots/full/admin-security.png new file mode 100644 index 0000000..1611179 Binary files /dev/null and b/docs/screenshots/full/admin-security.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-database-tuning.png b/docs/screenshots/full/admin-server-settings--tab-database-tuning.png new file mode 100644 index 0000000..1b25340 Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-database-tuning.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-dns.png b/docs/screenshots/full/admin-server-settings--tab-dns.png new file mode 100644 index 0000000..90cd53f Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-dns.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-email.png b/docs/screenshots/full/admin-server-settings--tab-email.png new file mode 100644 index 0000000..31de073 Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-email.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-general.png b/docs/screenshots/full/admin-server-settings--tab-general.png new file mode 100644 index 0000000..a745c29 Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-general.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-notifications.png b/docs/screenshots/full/admin-server-settings--tab-notifications.png new file mode 100644 index 0000000..1c925de Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-notifications.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-php-fpm.png b/docs/screenshots/full/admin-server-settings--tab-php-fpm.png new file mode 100644 index 0000000..65ea45f Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-php-fpm.png differ diff --git a/docs/screenshots/full/admin-server-settings--tab-storage.png b/docs/screenshots/full/admin-server-settings--tab-storage.png new file mode 100644 index 0000000..9ed0ba4 Binary files /dev/null and b/docs/screenshots/full/admin-server-settings--tab-storage.png differ diff --git a/docs/screenshots/full/admin-server-settings.png b/docs/screenshots/full/admin-server-settings.png new file mode 100644 index 0000000..a745c29 Binary files /dev/null and b/docs/screenshots/full/admin-server-settings.png differ diff --git a/docs/screenshots/full/admin-server-status.png b/docs/screenshots/full/admin-server-status.png new file mode 100644 index 0000000..2204a5d Binary files /dev/null and b/docs/screenshots/full/admin-server-status.png differ diff --git a/docs/screenshots/full/admin-server-updates.png b/docs/screenshots/full/admin-server-updates.png new file mode 100644 index 0000000..5a2172d Binary files /dev/null and b/docs/screenshots/full/admin-server-updates.png differ diff --git a/docs/screenshots/full/admin-services.png b/docs/screenshots/full/admin-services.png new file mode 100644 index 0000000..1ccec0f Binary files /dev/null and b/docs/screenshots/full/admin-services.png differ diff --git a/docs/screenshots/full/admin-ssl-manager.png b/docs/screenshots/full/admin-ssl-manager.png new file mode 100644 index 0000000..e75e384 Binary files /dev/null and b/docs/screenshots/full/admin-ssl-manager.png differ diff --git a/docs/screenshots/full/admin-two-factor-challenge.png b/docs/screenshots/full/admin-two-factor-challenge.png new file mode 100644 index 0000000..4231887 Binary files /dev/null and b/docs/screenshots/full/admin-two-factor-challenge.png differ diff --git a/docs/screenshots/full/admin-users-create.png b/docs/screenshots/full/admin-users-create.png new file mode 100644 index 0000000..3e5e9d5 Binary files /dev/null and b/docs/screenshots/full/admin-users-create.png differ diff --git a/docs/screenshots/full/admin-users-edit.png b/docs/screenshots/full/admin-users-edit.png new file mode 100644 index 0000000..f8ed56e Binary files /dev/null and b/docs/screenshots/full/admin-users-edit.png differ diff --git a/docs/screenshots/full/admin-users.png b/docs/screenshots/full/admin-users.png new file mode 100644 index 0000000..c011d59 Binary files /dev/null and b/docs/screenshots/full/admin-users.png differ diff --git a/docs/screenshots/full/admin-waf.png b/docs/screenshots/full/admin-waf.png new file mode 100644 index 0000000..ebc5268 Binary files /dev/null and b/docs/screenshots/full/admin-waf.png differ diff --git a/docs/screenshots/full/admin-webhook-endpoints-create.png b/docs/screenshots/full/admin-webhook-endpoints-create.png new file mode 100644 index 0000000..b5fe648 Binary files /dev/null and b/docs/screenshots/full/admin-webhook-endpoints-create.png differ diff --git a/docs/screenshots/full/admin-webhook-endpoints-edit.png b/docs/screenshots/full/admin-webhook-endpoints-edit.png new file mode 100644 index 0000000..7764fa3 Binary files /dev/null and b/docs/screenshots/full/admin-webhook-endpoints-edit.png differ diff --git a/docs/screenshots/full/admin-webhook-endpoints.png b/docs/screenshots/full/admin-webhook-endpoints.png new file mode 100644 index 0000000..4537eb4 Binary files /dev/null and b/docs/screenshots/full/admin-webhook-endpoints.png differ diff --git a/docs/screenshots/full/admin-whm-migration.png b/docs/screenshots/full/admin-whm-migration.png new file mode 100644 index 0000000..e47a01c Binary files /dev/null and b/docs/screenshots/full/admin-whm-migration.png differ diff --git a/docs/screenshots/full/user-backup-download.png b/docs/screenshots/full/user-backup-download.png new file mode 100644 index 0000000..e37d205 Binary files /dev/null and b/docs/screenshots/full/user-backup-download.png differ diff --git a/docs/screenshots/full/user-backups--tab-my-backups.png b/docs/screenshots/full/user-backups--tab-my-backups.png new file mode 100644 index 0000000..622d004 Binary files /dev/null and b/docs/screenshots/full/user-backups--tab-my-backups.png differ diff --git a/docs/screenshots/full/user-backups--tab-restore-history.png b/docs/screenshots/full/user-backups--tab-restore-history.png new file mode 100644 index 0000000..e61935b Binary files /dev/null and b/docs/screenshots/full/user-backups--tab-restore-history.png differ diff --git a/docs/screenshots/full/user-backups--tab-server-backups.png b/docs/screenshots/full/user-backups--tab-server-backups.png new file mode 100644 index 0000000..26d6b5b Binary files /dev/null and b/docs/screenshots/full/user-backups--tab-server-backups.png differ diff --git a/docs/screenshots/full/user-backups--tab-sftp-destinations.png b/docs/screenshots/full/user-backups--tab-sftp-destinations.png new file mode 100644 index 0000000..6dda5e7 Binary files /dev/null and b/docs/screenshots/full/user-backups--tab-sftp-destinations.png differ diff --git a/docs/screenshots/full/user-backups.png b/docs/screenshots/full/user-backups.png new file mode 100644 index 0000000..622d004 Binary files /dev/null and b/docs/screenshots/full/user-backups.png differ diff --git a/docs/screenshots/full/user-cdn-integration.png b/docs/screenshots/full/user-cdn-integration.png new file mode 100644 index 0000000..19ca539 Binary files /dev/null and b/docs/screenshots/full/user-cdn-integration.png differ diff --git a/docs/screenshots/full/user-cpanel-migration.png b/docs/screenshots/full/user-cpanel-migration.png new file mode 100644 index 0000000..76c81a2 Binary files /dev/null and b/docs/screenshots/full/user-cpanel-migration.png differ diff --git a/docs/screenshots/full/user-cron-jobs.png b/docs/screenshots/full/user-cron-jobs.png new file mode 100644 index 0000000..6711257 Binary files /dev/null and b/docs/screenshots/full/user-cron-jobs.png differ diff --git a/docs/screenshots/full/user-databases.png b/docs/screenshots/full/user-databases.png new file mode 100644 index 0000000..a9b5f24 Binary files /dev/null and b/docs/screenshots/full/user-databases.png differ diff --git a/docs/screenshots/full/user-dns-records.png b/docs/screenshots/full/user-dns-records.png new file mode 100644 index 0000000..467a63c Binary files /dev/null and b/docs/screenshots/full/user-dns-records.png differ diff --git a/docs/screenshots/full/user-domains.png b/docs/screenshots/full/user-domains.png new file mode 100644 index 0000000..f8193a4 Binary files /dev/null and b/docs/screenshots/full/user-domains.png differ diff --git a/docs/screenshots/full/user-email--tab-autoresponders.png b/docs/screenshots/full/user-email--tab-autoresponders.png new file mode 100644 index 0000000..87b8565 Binary files /dev/null and b/docs/screenshots/full/user-email--tab-autoresponders.png differ diff --git a/docs/screenshots/full/user-email--tab-catch-all.png b/docs/screenshots/full/user-email--tab-catch-all.png new file mode 100644 index 0000000..206c277 Binary files /dev/null and b/docs/screenshots/full/user-email--tab-catch-all.png differ diff --git a/docs/screenshots/full/user-email--tab-forwarders.png b/docs/screenshots/full/user-email--tab-forwarders.png new file mode 100644 index 0000000..4041c7a Binary files /dev/null and b/docs/screenshots/full/user-email--tab-forwarders.png differ diff --git a/docs/screenshots/full/user-email--tab-logs.png b/docs/screenshots/full/user-email--tab-logs.png new file mode 100644 index 0000000..2af2b03 Binary files /dev/null and b/docs/screenshots/full/user-email--tab-logs.png differ diff --git a/docs/screenshots/full/user-email--tab-mailboxes.png b/docs/screenshots/full/user-email--tab-mailboxes.png new file mode 100644 index 0000000..dec06fa Binary files /dev/null and b/docs/screenshots/full/user-email--tab-mailboxes.png differ diff --git a/docs/screenshots/full/user-email--tab-spam-settings.png b/docs/screenshots/full/user-email--tab-spam-settings.png new file mode 100644 index 0000000..388ac6f Binary files /dev/null and b/docs/screenshots/full/user-email--tab-spam-settings.png differ diff --git a/docs/screenshots/full/user-email.png b/docs/screenshots/full/user-email.png new file mode 100644 index 0000000..dec06fa Binary files /dev/null and b/docs/screenshots/full/user-email.png differ diff --git a/docs/screenshots/full/user-files.png b/docs/screenshots/full/user-files.png new file mode 100644 index 0000000..dd27c60 Binary files /dev/null and b/docs/screenshots/full/user-files.png differ diff --git a/docs/screenshots/full/user-git-deployment.png b/docs/screenshots/full/user-git-deployment.png new file mode 100644 index 0000000..30e80a5 Binary files /dev/null and b/docs/screenshots/full/user-git-deployment.png differ diff --git a/docs/screenshots/full/user-home.png b/docs/screenshots/full/user-home.png new file mode 100644 index 0000000..3a6a106 Binary files /dev/null and b/docs/screenshots/full/user-home.png differ diff --git a/docs/screenshots/full/user-image-optimization.png b/docs/screenshots/full/user-image-optimization.png new file mode 100644 index 0000000..41274ea Binary files /dev/null and b/docs/screenshots/full/user-image-optimization.png differ diff --git a/docs/screenshots/full/user-login.png b/docs/screenshots/full/user-login.png new file mode 100644 index 0000000..4d10057 Binary files /dev/null and b/docs/screenshots/full/user-login.png differ diff --git a/docs/screenshots/full/user-logs--tab-activity-log.png b/docs/screenshots/full/user-logs--tab-activity-log.png new file mode 100644 index 0000000..ef5ef0f Binary files /dev/null and b/docs/screenshots/full/user-logs--tab-activity-log.png differ diff --git a/docs/screenshots/full/user-logs--tab-logs.png b/docs/screenshots/full/user-logs--tab-logs.png new file mode 100644 index 0000000..5a58df0 Binary files /dev/null and b/docs/screenshots/full/user-logs--tab-logs.png differ diff --git a/docs/screenshots/full/user-logs--tab-statistics.png b/docs/screenshots/full/user-logs--tab-statistics.png new file mode 100644 index 0000000..a66cd0e Binary files /dev/null and b/docs/screenshots/full/user-logs--tab-statistics.png differ diff --git a/docs/screenshots/full/user-logs.png b/docs/screenshots/full/user-logs.png new file mode 100644 index 0000000..5a58df0 Binary files /dev/null and b/docs/screenshots/full/user-logs.png differ diff --git a/docs/screenshots/full/user-mailing-lists.png b/docs/screenshots/full/user-mailing-lists.png new file mode 100644 index 0000000..7fd4532 Binary files /dev/null and b/docs/screenshots/full/user-mailing-lists.png differ diff --git a/docs/screenshots/full/user-password-reset-request.png b/docs/screenshots/full/user-password-reset-request.png new file mode 100644 index 0000000..749a30f Binary files /dev/null and b/docs/screenshots/full/user-password-reset-request.png differ diff --git a/docs/screenshots/full/user-password-reset-reset.png b/docs/screenshots/full/user-password-reset-reset.png new file mode 100644 index 0000000..4f44da7 Binary files /dev/null and b/docs/screenshots/full/user-password-reset-reset.png differ diff --git a/docs/screenshots/full/user-php-settings.png b/docs/screenshots/full/user-php-settings.png new file mode 100644 index 0000000..1b598ce Binary files /dev/null and b/docs/screenshots/full/user-php-settings.png differ diff --git a/docs/screenshots/full/user-postgresql--tab-databases.png b/docs/screenshots/full/user-postgresql--tab-databases.png new file mode 100644 index 0000000..2b693cb Binary files /dev/null and b/docs/screenshots/full/user-postgresql--tab-databases.png differ diff --git a/docs/screenshots/full/user-postgresql--tab-users.png b/docs/screenshots/full/user-postgresql--tab-users.png new file mode 100644 index 0000000..b2626e0 Binary files /dev/null and b/docs/screenshots/full/user-postgresql--tab-users.png differ diff --git a/docs/screenshots/full/user-postgresql.png b/docs/screenshots/full/user-postgresql.png new file mode 100644 index 0000000..2b693cb Binary files /dev/null and b/docs/screenshots/full/user-postgresql.png differ diff --git a/docs/screenshots/full/user-profile.png b/docs/screenshots/full/user-profile.png new file mode 100644 index 0000000..7a9113a Binary files /dev/null and b/docs/screenshots/full/user-profile.png differ diff --git a/docs/screenshots/full/user-protected-directories.png b/docs/screenshots/full/user-protected-directories.png new file mode 100644 index 0000000..6c15adf Binary files /dev/null and b/docs/screenshots/full/user-protected-directories.png differ diff --git a/docs/screenshots/full/user-ssh-keys.png b/docs/screenshots/full/user-ssh-keys.png new file mode 100644 index 0000000..0f4c67f Binary files /dev/null and b/docs/screenshots/full/user-ssh-keys.png differ diff --git a/docs/screenshots/full/user-ssl.png b/docs/screenshots/full/user-ssl.png new file mode 100644 index 0000000..7f45a91 Binary files /dev/null and b/docs/screenshots/full/user-ssl.png differ diff --git a/docs/screenshots/full/user-two-factor-challenge.png b/docs/screenshots/full/user-two-factor-challenge.png new file mode 100644 index 0000000..15481ec Binary files /dev/null and b/docs/screenshots/full/user-two-factor-challenge.png differ diff --git a/docs/screenshots/full/user-wordpress.png b/docs/screenshots/full/user-wordpress.png new file mode 100644 index 0000000..dcc8b2f Binary files /dev/null and b/docs/screenshots/full/user-wordpress.png differ diff --git a/docs/screenshots/user-backups.png b/docs/screenshots/user-backups.png index 14e3e7a..7cd42fd 100644 Binary files a/docs/screenshots/user-backups.png and b/docs/screenshots/user-backups.png differ diff --git a/docs/screenshots/user-cpanel-migration.png b/docs/screenshots/user-cpanel-migration.png index e19ef01..121e074 100644 Binary files a/docs/screenshots/user-cpanel-migration.png and b/docs/screenshots/user-cpanel-migration.png differ diff --git a/docs/screenshots/user-dashboard.png b/docs/screenshots/user-dashboard.png index f223261..f9b2a38 100644 Binary files a/docs/screenshots/user-dashboard.png and b/docs/screenshots/user-dashboard.png differ diff --git a/docs/screenshots/user-domains.png b/docs/screenshots/user-domains.png index e040c55..aaff6ba 100644 Binary files a/docs/screenshots/user-domains.png and b/docs/screenshots/user-domains.png differ diff --git a/install.sh b/install.sh index be0b43d..613b3eb 100755 --- a/install.sh +++ b/install.sh @@ -16,7 +16,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if [[ -f "$SCRIPT_DIR/VERSION" ]]; then JABALI_VERSION="$(sed -n 's/^VERSION=//p' "$SCRIPT_DIR/VERSION")" fi -JABALI_VERSION="${JABALI_VERSION:-0.9-rc53}" +JABALI_VERSION="${JABALI_VERSION:-0.9-rc54}" # Colors RED='\033[0;31m' diff --git a/resources/views/filament/jabali/pages/files.blade.php b/resources/views/filament/jabali/pages/files.blade.php index e54577c..3c23b0f 100644 --- a/resources/views/filament/jabali/pages/files.blade.php +++ b/resources/views/filament/jabali/pages/files.blade.php @@ -12,6 +12,7 @@ <code class="px-1.5 py-0.5 rounded bg-warning-100 dark:bg-warning-900/50 fi-color-warning fi-text-color-700 dark:fi-text-color-300 font-mono fi-section-header-description">{{ __('conf') }}</code> {{ __('and') }} <code class="px-1.5 py-0.5 rounded bg-warning-100 dark:bg-warning-900/50 fi-color-warning fi-text-color-700 dark:fi-text-color-300 font-mono fi-section-header-description">{{ __('logs') }}</code> + {{ __('and') }} {{ __('folders unless you know what you are doing.') }} </x-slot> </x-filament::section> diff --git a/tests/docs-pages.json b/tests/docs-pages.json new file mode 100644 index 0000000..31797b6 --- /dev/null +++ b/tests/docs-pages.json @@ -0,0 +1,497 @@ +[ + { + "panel": "admin", + "uri": "jabali-admin", + "name": "filament.admin.home", + "label": "jabali-admin", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/automation-api", + "name": "filament.admin.pages.automation-api", + "label": "API Access", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/backup-download", + "name": "filament.admin.pages.backup-download", + "label": "jabali-admin/backup-download", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/backups", + "name": "filament.admin.pages.backups", + "label": "Backups", + "tabs": [ + "Destinations", + "Schedules", + "Backups" + ] + }, + { + "panel": "admin", + "uri": "jabali-admin/cpanel-migration", + "name": "filament.admin.pages.cpanel-migration", + "label": "cPanel Migration", + "tabs": [ + "Domains", + "Databases", + "Mailboxes", + "Forwarders", + "SSL" + ] + }, + { + "panel": "admin", + "uri": "jabali-admin/dashboard", + "name": "filament.admin.pages.dashboard", + "label": "Dashboard", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/database-tuning", + "name": "filament.admin.pages.database-tuning", + "label": "Database Tuning", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/dns-zones", + "name": "filament.admin.pages.dns-zones", + "label": "DNS Zones", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/email-logs", + "name": "filament.admin.pages.email-logs", + "label": "Email Logs", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/email-queue", + "name": "filament.admin.pages.email-queue", + "label": "Email Queue", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/geo-block-rules", + "name": "filament.admin.resources.geo-block-rules.index", + "label": "jabali-admin/geo-block-rules", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/geo-block-rules/create", + "name": "filament.admin.resources.geo-block-rules.create", + "label": "jabali-admin/geo-block-rules/create", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/geo-block-rules/{record}/edit", + "name": "filament.admin.resources.geo-block-rules.edit", + "label": "jabali-admin/geo-block-rules/{record}/edit", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/hosting-packages", + "name": "filament.admin.resources.hosting-packages.index", + "label": "jabali-admin/hosting-packages", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/hosting-packages/create", + "name": "filament.admin.resources.hosting-packages.create", + "label": "jabali-admin/hosting-packages/create", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/hosting-packages/{record}/edit", + "name": "filament.admin.resources.hosting-packages.edit", + "label": "jabali-admin/hosting-packages/{record}/edit", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/ip-addresses", + "name": "filament.admin.pages.ip-addresses", + "label": "IP Addresses", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/login", + "name": "filament.admin.auth.login", + "label": "jabali-admin/login", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/migration", + "name": "filament.admin.pages.migration", + "label": "Migration", + "tabs": [ + "cPanel Migration", + "WHM Migration" + ] + }, + { + "panel": "admin", + "uri": "jabali-admin/password-reset/request", + "name": "filament.admin.auth.password-reset.request", + "label": "jabali-admin/password-reset/request", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/password-reset/reset", + "name": "filament.admin.auth.password-reset.reset", + "label": "jabali-admin/password-reset/reset", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/php-manager", + "name": "filament.admin.pages.php-manager", + "label": "PHP Manager", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/security", + "name": "filament.admin.pages.security", + "label": "Security", + "tabs": [ + "Overview", + "Firewall", + "ModSecurity / WAF", + "Fail2ban", + "Antivirus", + "SSH", + "Vulnerability Scanner" + ] + }, + { + "panel": "admin", + "uri": "jabali-admin/server-settings", + "name": "filament.admin.pages.server-settings", + "label": "Server Settings", + "tabs": [ + "General", + "DNS", + "Storage", + "Email", + "Notifications", + "PHP-FPM", + "Database Tuning" + ] + }, + { + "panel": "admin", + "uri": "jabali-admin/server-status", + "name": "filament.admin.pages.server-status", + "label": "Server Status", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/server-updates", + "name": "filament.admin.pages.server-updates", + "label": "System Updates", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/services", + "name": "filament.admin.pages.services", + "label": "Services", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/ssl-manager", + "name": "filament.admin.pages.ssl-manager", + "label": "SSL Manager", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/two-factor-challenge", + "name": "filament.admin.auth.two-factor-challenge", + "label": "jabali-admin/two-factor-challenge", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/users", + "name": "filament.admin.resources.users.index", + "label": "jabali-admin/users", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/users/create", + "name": "filament.admin.resources.users.create", + "label": "jabali-admin/users/create", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/users/{record}/edit", + "name": "filament.admin.resources.users.edit", + "label": "jabali-admin/users/{record}/edit", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/waf", + "name": "filament.admin.pages.waf", + "label": "ModSecurity / WAF", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/webhook-endpoints", + "name": "filament.admin.resources.webhook-endpoints.index", + "label": "jabali-admin/webhook-endpoints", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/webhook-endpoints/create", + "name": "filament.admin.resources.webhook-endpoints.create", + "label": "jabali-admin/webhook-endpoints/create", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/webhook-endpoints/{record}/edit", + "name": "filament.admin.resources.webhook-endpoints.edit", + "label": "jabali-admin/webhook-endpoints/{record}/edit", + "tabs": [] + }, + { + "panel": "admin", + "uri": "jabali-admin/whm-migration", + "name": "filament.admin.pages.whm-migration", + "label": "WHM Migration", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel", + "name": "filament.jabali.pages.dashboard", + "label": "Dashboard", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/backup-download", + "name": "filament.jabali.pages.backup-download", + "label": "jabali-panel/backup-download", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/backups", + "name": "filament.jabali.pages.backups", + "label": "Backups", + "tabs": [ + "My Backups", + "Server Backups", + "SFTP Destinations", + "Restore History" + ] + }, + { + "panel": "jabali", + "uri": "jabali-panel/cdn-integration", + "name": "filament.jabali.pages.cdn-integration", + "label": "CDN Integration", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/cpanel-migration", + "name": "filament.jabali.pages.cpanel-migration", + "label": "cPanel Migration", + "tabs": [ + "Domains", + "Databases", + "Mailboxes", + "Forwarders", + "SSL" + ] + }, + { + "panel": "jabali", + "uri": "jabali-panel/cron-jobs", + "name": "filament.jabali.pages.cron-jobs", + "label": "Cron Jobs", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/databases", + "name": "filament.jabali.pages.databases", + "label": "Databases", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/dns-records", + "name": "filament.jabali.pages.dns-records", + "label": "DNS Records", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/domains", + "name": "filament.jabali.pages.domains", + "label": "Domains", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/email", + "name": "filament.jabali.pages.email", + "label": "Email", + "tabs": [ + "Mailboxes", + "Forwarders", + "Autoresponders", + "Catch-All", + "Logs", + "Spam Settings" + ] + }, + { + "panel": "jabali", + "uri": "jabali-panel/files", + "name": "filament.jabali.pages.files", + "label": "Files", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/git-deployment", + "name": "filament.jabali.pages.git-deployment", + "label": "Git Deployment", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/image-optimization", + "name": "filament.jabali.pages.image-optimization", + "label": "Image Optimization", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/login", + "name": "filament.jabali.auth.login", + "label": "jabali-panel/login", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/logs", + "name": "filament.jabali.pages.logs", + "label": "Logs & Statistics", + "tabs": [ + "Logs", + "Statistics", + "Activity Log" + ] + }, + { + "panel": "jabali", + "uri": "jabali-panel/mailing-lists", + "name": "filament.jabali.pages.mailing-lists", + "label": "Mailing Lists", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/password-reset/request", + "name": "filament.jabali.auth.password-reset.request", + "label": "jabali-panel/password-reset/request", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/password-reset/reset", + "name": "filament.jabali.auth.password-reset.reset", + "label": "jabali-panel/password-reset/reset", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/php-settings", + "name": "filament.jabali.pages.php-settings", + "label": "PHP Settings", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/postgresql", + "name": "filament.jabali.pages.postgresql", + "label": "PostgreSQL", + "tabs": [ + "Databases", + "Users" + ] + }, + { + "panel": "jabali", + "uri": "jabali-panel/profile", + "name": "filament.jabali.auth.profile", + "label": "jabali-panel/profile", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/protected-directories", + "name": "filament.jabali.pages.protected-directories", + "label": "Protected Directories", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/ssh-keys", + "name": "filament.jabali.pages.ssh-keys", + "label": "SSH & SFTP", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/ssl", + "name": "filament.jabali.pages.ssl", + "label": "SSL Certificates", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/two-factor-challenge", + "name": "filament.jabali.auth.two-factor-challenge", + "label": "jabali-panel/two-factor-challenge", + "tabs": [] + }, + { + "panel": "jabali", + "uri": "jabali-panel/wordpress", + "name": "filament.jabali.pages.wordpress", + "label": "WordPress", + "tabs": [] + } +] \ No newline at end of file diff --git a/tests/take-docs-screenshots.cjs b/tests/take-docs-screenshots.cjs new file mode 100644 index 0000000..3c28218 --- /dev/null +++ b/tests/take-docs-screenshots.cjs @@ -0,0 +1,246 @@ +#!/usr/bin/env node +/** + * Generate documentation screenshots for every admin/user route and each tab. + */ + +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); +const puppeteer = require('puppeteer'); + +const args = process.argv.slice(2); +const getArg = (key, fallback) => { + const arg = args.find((item) => item.startsWith(`--${key}=`)); + return arg ? arg.split('=').slice(1).join('=') : fallback; +}; +const hasFlag = (flag) => args.includes(`--${flag}`); + +const CONFIG = { + baseUrl: getArg('base-url', 'https://jabali.lan'), + outputDir: getArg('output-dir', '/var/www/jabali/docs/screenshots/full'), + pagesJson: getArg('pages-json', '/var/www/jabali/tests/docs-pages.json'), + admin: { + email: getArg('admin-email', 'admin@jabali.lan'), + password: getArg('admin-password', 'q1w2E#R$'), + path: getArg('admin-path', '/jabali-admin'), + }, + user: { + path: getArg('user-path', '/jabali-panel'), + }, + impersonateUserId: getArg('impersonate-user-id', '9'), + skipAdmin: hasFlag('skip-admin'), + skipUser: hasFlag('skip-user'), + fullPage: hasFlag('full-page'), + onlyMissing: hasFlag('only-missing'), +}; + +const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + +function slugify(value) { + return value + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, ''); +} + +function loadPages() { + return JSON.parse(fs.readFileSync(CONFIG.pagesJson, 'utf-8')); +} + +function queryId(table) { + try { + const out = execSync( + `sqlite3 /var/www/jabali/database/database.sqlite "select id from ${table} limit 1;"`, + { encoding: 'utf-8' } + ).trim(); + return out || null; + } catch (err) { + return null; + } +} + +function applyRecordIds(uri) { + if (!uri.includes('{record}')) return uri; + const resourceMap = { + 'jabali-admin/users': 'users', + 'jabali-admin/hosting-packages': 'hosting_packages', + 'jabali-admin/geo-block-rules': 'geo_block_rules', + 'jabali-admin/webhook-endpoints': 'webhook_endpoints', + }; + const base = uri.split('/{record}')[0]; + const table = resourceMap[base]; + if (!table) return uri; + const id = queryId(table); + if (!id) return uri; + return uri.replace('{record}', id); +} + +async function loginPanel(page, panelName, basePath, credentials) { + console.log(`Logging in to ${panelName} panel...`); + await page.goto(`${CONFIG.baseUrl}${basePath}/login`, { waitUntil: 'networkidle0' }); + await wait(1500); + await page.type('input[type="email"]', credentials.email); + await page.type('input[type="password"]', credentials.password); + await page.click('button[type="submit"]'); + await wait(4000); + const currentUrl = page.url(); + if (currentUrl.includes('/login')) { + throw new Error(`${panelName} login failed - still on login page`); + } + console.log(`${panelName} login successful!\n`); +} + +async function loginUserViaImpersonation(page) { + if (!CONFIG.impersonateUserId) { + throw new Error('Missing --impersonate-user-id for user screenshots'); + } + await loginPanel(page, 'Admin', CONFIG.admin.path, CONFIG.admin); + const impersonateUrl = `${CONFIG.baseUrl}/impersonate/start/${CONFIG.impersonateUserId}`; + console.log(`Impersonating user via: ${impersonateUrl}`); + await page.goto(impersonateUrl, { waitUntil: 'networkidle0' }); + await wait(2000); + const currentUrl = page.url(); + if (currentUrl.includes('/login')) { + throw new Error('Impersonation failed - still on login page'); + } + console.log('User impersonation successful!\n'); +} + +async function clickTab(page, tabLabel) { + const normalized = tabLabel.trim().toLowerCase(); + const clicked = await page.evaluate((label) => { + const tabs = Array.from(document.querySelectorAll('[role="tab"], button')); + const match = tabs.find((el) => { + const text = (el.textContent || '').trim().toLowerCase(); + return text === label; + }) || tabs.find((el) => { + const text = (el.textContent || '').trim().toLowerCase(); + return text.includes(label); + }); + if (match) { + match.click(); + return true; + } + return false; + }, normalized); + if (clicked) { + await wait(1500); + } + return clicked; +} + +async function captureRoute(context, entry, prefix) { + const page = await context.newPage(); + await page.setViewport({ width: 1400, height: 900 }); + + const uri = applyRecordIds(entry.uri); + const url = `${CONFIG.baseUrl}/${uri}`.replace(/\/+$/, ''); + const baseName = `${prefix}-${slugify(uri.replace(prefix === 'admin' ? 'jabali-admin' : 'jabali-panel', '')) || 'home'}`; + const filename = `${baseName}.png`; + const filepath = path.join(CONFIG.outputDir, filename); + + const skipBase = CONFIG.onlyMissing && fs.existsSync(filepath); + + try { + await page.goto(url, { waitUntil: 'networkidle0', timeout: 45000 }); + await wait(2000); + + if (!skipBase) { + await page.screenshot({ path: filepath, fullPage: CONFIG.fullPage }); + console.log(`Saved: ${filepath}`); + } + + if (entry.tabs && entry.tabs.length) { + for (const tab of entry.tabs) { + const tabFile = `${baseName}--tab-${slugify(tab)}.png`; + const tabPath = path.join(CONFIG.outputDir, tabFile); + if (CONFIG.onlyMissing && fs.existsSync(tabPath)) { + continue; + } + const clicked = await clickTab(page, tab); + if (!clicked) { + console.log(` Tab not found: ${tab}`); + continue; + } + await page.screenshot({ path: tabPath, fullPage: CONFIG.fullPage }); + console.log(` Tab saved: ${tabPath}`); + } + } + } catch (err) { + console.log(`Error capturing ${url}: ${err.message}`); + } finally { + await page.close(); + } +} + +async function captureAuthPages() { + const pages = loadPages(); + const authUris = pages.filter((entry) => entry.uri.includes('login') || entry.uri.includes('password-reset') || entry.uri.includes('two-factor')); + if (!authUris.length) return; + + const browser = await puppeteer.launch({ + headless: 'new', + args: ['--no-sandbox', '--disable-setuid-sandbox', '--ignore-certificate-errors'], + }); + + const context = await browser.createBrowserContext(); + for (const entry of authUris) { + const prefix = entry.panel === 'admin' ? 'admin' : 'user'; + await captureRoute(context, entry, prefix); + } + await browser.close(); +} + +async function main() { + fs.mkdirSync(CONFIG.outputDir, { recursive: true }); + const pages = loadPages(); + + await captureAuthPages(); + + const browser = await puppeteer.launch({ + headless: 'new', + args: ['--no-sandbox', '--disable-setuid-sandbox', '--ignore-certificate-errors'], + }); + + if (!CONFIG.skipAdmin) { + const context = await browser.createBrowserContext(); + const page = await context.newPage(); + await page.setViewport({ width: 1400, height: 900 }); + await loginPanel(page, 'Admin', CONFIG.admin.path, CONFIG.admin); + await page.close(); + + for (const entry of pages.filter((e) => e.panel === 'admin')) { + if (entry.uri.includes('login') || entry.uri.includes('password-reset') || entry.uri.includes('two-factor')) { + continue; + } + await captureRoute(context, entry, 'admin'); + } + + await context.close(); + } + + if (!CONFIG.skipUser) { + const context = await browser.createBrowserContext(); + const page = await context.newPage(); + await page.setViewport({ width: 1400, height: 900 }); + await loginUserViaImpersonation(page); + await page.close(); + + for (const entry of pages.filter((e) => e.panel === 'jabali')) { + if (entry.uri.includes('login') || entry.uri.includes('password-reset') || entry.uri.includes('two-factor')) { + continue; + } + await captureRoute(context, entry, 'user'); + } + + await context.close(); + } + + await browser.close(); + console.log('Documentation screenshots completed.'); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +});