diff --git a/app/Helpers/DocumentIdentifier.php b/app/Helpers/DocumentIdentifier.php new file mode 100644 index 0000000..6d6c6e1 --- /dev/null +++ b/app/Helpers/DocumentIdentifier.php @@ -0,0 +1,134 @@ + 'Ingeniería', + 'ARC' => 'Arquitectura', + 'CIV' => 'Civil', + 'MEC' => 'Mecánica', + 'ELC' => 'Eléctrica', + 'INS' => 'Instrumentación', + 'PIP' => 'Piping', + 'STR' => 'Estructural' + ]; + + private $tiposDocumentoValidos = [ + 'DRW' => 'Dibujo', + 'ESP' => 'Especificación', + 'LST' => 'Lista de materiales', + 'PRO' => 'Procedimiento', + 'INF' => 'Informe', + 'MAN' => 'Manual', + 'CAL' => 'Cálculo', + 'REP' => 'Reporte' + ]; + + public function analizarDocumento($codigoCompleto) { + // Validar formato básico + if (strpos($codigoCompleto, ' - ') === false) { + return $this->crearResultadoError("Formato inválido: falta separador ' - '"); + } + + list($codigo, $nombre) = explode(' - ', $codigoCompleto, 2); + $segmentos = explode('-', $codigo); + + // Validar número de segmentos + if (count($segmentos) != 5) { + return $this->crearResultadoError("Número incorrecto de segmentos"); + } + + // Extraer y validar cada parte + $codigoProyecto = $segmentos[0]; + $codigoMaker = $segmentos[1]; + $disciplina = $segmentos[2]; + $tipoDocumento = $segmentos[3]; + $revisionCompleta = $segmentos[4]; + + // Validar formato de revisión + if (strpos($revisionCompleta, 'REV.') !== 0) { + return $this->crearResultadoError("Formato de revisión inválido"); + } + + $numeroRevision = substr($revisionCompleta, 4); // Remover "REV." + + // Validar número de revisión + if (!ctype_digit($numeroRevision) || strlen($numeroRevision) != 2) { + return $this->crearResultadoError("Número de revisión inválido"); + } + + // Validar disciplinas y tipos + $disciplinaValida = $this->validarDisciplina($disciplina); + $tipoValido = $this->validarTipoDocumento($tipoDocumento); + + return [ + 'codigo_completo' => $codigoCompleto, + 'codigo_proyecto' => $codigoProyecto, + 'codigo_maker' => $codigoMaker, + 'disciplina' => $disciplina, + 'disciplina_desc' => $disciplinaValida, + 'tipo_documento' => $tipoDocumento, + 'tipo_documento_desc' => $tipoValido, + 'revision' => $numeroRevision, + 'nombre_documento' => $nombre, + 'estructura_valida' => true, + 'errores' => [] + ]; + } + + private function validarDisciplina($codigo) { + return isset($this->disciplinasValidas[$codigo]) + ? $this->disciplinasValidas[$codigo] + : "Desconocida"; + } + + private function validarTipoDocumento($codigo) { + return isset($this->tiposDocumentoValidos[$codigo]) + ? $this->tiposDocumentoValidos[$codigo] + : "Desconocido"; + } + + private function crearResultadoError($mensaje) { + return [ + 'estructura_valida' => false, + 'errores' => [$mensaje] + ]; + } + + // Método para generar un nuevo código + public function generarCodigo($proyecto, $maker, $disciplina, $tipo, $revision, $nombre = '') { + $revisionFormateada = str_pad($revision, 2, '0', STR_PAD_LEFT); + $codigo = "{$proyecto}-{$maker}-{$disciplina}-{$tipo}-REV.{$revisionFormateada}"; + + if (!empty($nombre)) { + $codigo .= " - {$nombre}"; + } + + return $codigo; + } +} + +// EJEMPLOS DE USO +/* +$analizador = new DocumentIdentifier(); + +// Analizar un código existente +$codigo1 = "MP00002-SOGOS-ENG-DRW-REV.01 - Plano principal"; +$resultado1 = $analizador->analizarDocumento($codigo1); + +echo "Análisis del documento:\n"; +print_r($resultado1); + +// Generar un nuevo código +$nuevoCodigo = $analizador->generarCodigo( + 'MP00002', + 'SOGOS', + 'CIV', + 'ESP', + '03', + 'Especificación técnica de cimientos' +); + +echo "\nNuevo código generado: " . $nuevoCodigo . "\n";*/ + +?> \ No newline at end of file diff --git a/app/Helpers/FileHelper.php b/app/Helpers/FileHelper.php index df40db8..1d536e9 100644 --- a/app/Helpers/FileHelper.php +++ b/app/Helpers/FileHelper.php @@ -20,4 +20,50 @@ class FileHelper default => 'document' }; } + + public static function getFileIconClass($filename) + { + $fileType = self::getFileType($filename); + + $classes = [ + 'pdf' => 'text-red-500', + 'word' => 'text-blue-500', + 'excel' => 'text-green-500', + 'image' => 'text-yellow-500', + 'archive' => 'text-purple-500', + 'text' => 'text-gray-500', + 'powerpoint' => 'text-orange-500', + 'document' => 'text-gray-400' + ]; + + return $classes[$fileType] ?? 'text-gray-400'; + } + + public static function getFileIconSvg($filename) + { + $fileType = self::getFileType($filename); + $colorClass = self::getFileIconClass($filename); + + $icons = [ + 'pdf' => ' + + ', + 'word' => ' + + ', + 'excel' => ' + + ', + 'image' => ' + + ', + 'archive' => ' + + ' + ]; + + return $icons[$fileType] ?? ' + + '; + } } \ No newline at end of file diff --git a/app/Http/Controllers/DocumentController.php b/app/Http/Controllers/DocumentController.php index 07b2dc8..ea2ade8 100644 --- a/app/Http/Controllers/DocumentController.php +++ b/app/Http/Controllers/DocumentController.php @@ -68,6 +68,8 @@ class DocumentController extends Controller $document->url = Storage::url($document->file_path); + $document->load('user'); + return view('documents.show', [ 'document' => $document, 'versions' => $document->versions()->latest()->get(), @@ -108,7 +110,7 @@ class DocumentController extends Controller foreach ($request->file('files') as $file) { $document = $project->documents()->create([ 'name' => $file->getClientOriginalName(), - 'status' => 'pending' + 'status' => 0 ]); $this->createVersion($document, $file); @@ -125,4 +127,331 @@ class DocumentController extends Controller $document->update(['current_version_id' => $version->id]); } + + + /** + * Actualizar PDF con anotaciones, firmas y sellos + */ + public function updatePdf(Request $request, Document $document) + { + $this->authorize('update', $document); + + $request->validate([ + 'pdf_data' => 'required|string', // PDF modificado en base64 + 'annotations' => 'sometimes|array', + 'signatures' => 'sometimes|array', + 'stamps' => 'sometimes|array', + ]); + + try { + // Procesar el PDF modificado + $modifiedPdf = $this->processPdfData($request->pdf_data); + + // Reemplazar el archivo original (sin crear nueva versión si no quieres) + $this->replaceOriginalPdf($document, $modifiedPdf); + + // Opcional: también crear una nueva versión para historial + $newVersion = $this->createNewVersion($document, $modifiedPdf, $request->all()); + + return response()->json([ + 'success' => true, + 'message' => 'PDF actualizado correctamente', + 'version_id' => $newVersion->id ?? null, + ]); + + } catch (\Exception $e) { + \Log::error('Error updating PDF: ' . $e->getMessage()); + + return response()->json([ + 'success' => false, + 'message' => 'Error al actualizar el PDF: ' . $e->getMessage() + ], 500); + } + } + + /** + * Procesar datos del PDF en base64 + */ + private function processPdfData($pdfData) + { + // Eliminar el prefijo data:application/pdf;base64, si existe + $pdfData = preg_replace('/^data:application\/pdf;base64,/', '', $pdfData); + + // Decodificar base64 + $pdfContent = base64_decode($pdfData); + + if (!$pdfContent) { + throw new \Exception('Datos PDF inválidos'); + } + + return $pdfContent; + } + + /** + * Procesar PDF con anotaciones (método alternativo) + */ + private function processPdfWithAnnotations($document, $data) + { + // Aquí integrarías una librería PHP para PDF como spatie/pdf-to-image o setasign/fpdi + // Por ahora, devolvemos el contenido del archivo original + // En producción, implementarías la lógica de modificación + + if ($document->currentVersion) { + $filePath = $document->currentVersion->file_path; + } else { + $filePath = $document->getFirstMedia('documents')->getPath(); + } + + if (!Storage::exists($filePath)) { + throw new \Exception('Archivo PDF no encontrado'); + } + + return Storage::get($filePath); + } + + /** + * Reemplazar el PDF original + */ + private function replaceOriginalPdf($document, $pdfContent) + { + // Obtener la ruta del archivo original + $filePath = $document->file_path; + + // Si el documento usa media library + if ($document->getFirstMedia('documents')) { + $media = $document->getFirstMedia('documents'); + $media->update([ + 'file_name' => $document->name . '.pdf', + 'size' => strlen($pdfContent), + ]); + + // Reemplazar el archivo + Storage::put($media->getPath(), $pdfContent); + } else { + // Si usas file_path directo + Storage::put($filePath, $pdfContent); + + // Actualizar metadata del documento + $document->update([ + 'file_size' => strlen($pdfContent), + 'updated_at' => now(), + ]); + } + } + + /** + * Crear nueva versión del documento + */ + private function createNewVersion($document, $pdfContent, $data = []) + { + $versionNumber = $document->versions()->count() + 1; + $fileName = "documents/{$document->id}/v{$versionNumber}.pdf"; + + // Guardar el nuevo PDF + Storage::put($fileName, $pdfContent); + + // Crear registro de versión + $version = $document->versions()->create([ + 'version_number' => $versionNumber, + 'file_path' => $fileName, + 'file_size' => strlen($pdfContent), + 'hash' => hash('sha256', $pdfContent), + 'created_by' => auth()->id(), + 'metadata' => [ + 'annotations_count' => count($data['annotations'] ?? []), + 'signatures_count' => count($data['signatures'] ?? []), + 'stamps_count' => count($data['stamps'] ?? []), + 'edited_at' => now()->toISOString(), + 'edited_by' => auth()->user()->name + ] + ]); + + return $version; + } + + /** + * Guardar metadatos de anotaciones + */ + private function saveAnnotationsMetadata($version, $data) + { + // Guardar anotaciones en la base de datos si es necesario + if (!empty($data['annotations'])) { + foreach ($data['annotations'] as $annotation) { + $version->annotations()->create([ + 'type' => $annotation['type'] ?? 'text', + 'content' => $annotation['content'] ?? '', + 'position' => $annotation['position'] ?? [], + 'page' => $annotation['page'] ?? 1, + 'created_by' => auth()->id() + ]); + } + } + } + + /** + * Subir firma + */ + public function uploadSignature(Request $request) + { + $request->validate([ + 'signature' => 'required|image|max:2048|mimes:png,jpg,jpeg' + ]); + + try { + $user = auth()->user(); + $path = $request->file('signature')->store("signatures/{$user->id}", 'public'); + + // Opcional: Guardar en base de datos + $user->signatures()->create([ + 'file_path' => $path, + 'file_name' => $request->file('signature')->getClientOriginalName() + ]); + + return response()->json([ + 'success' => true, + 'path' => Storage::url($path), + 'filename' => basename($path) + ]); + + } catch (\Exception $e) { + \Log::error('Error uploading signature: ' . $e->getMessage()); + + return response()->json([ + 'success' => false, + 'message' => 'Error al subir la firma' + ], 500); + } + } + + /** + * Subir sello + */ + public function uploadStamp(Request $request) + { + $request->validate([ + 'stamp' => 'required|image|max:2048|mimes:png,jpg,jpeg' + ]); + + try { + $user = auth()->user(); + $path = $request->file('stamp')->store("stamps/{$user->id}", 'public'); + + // Opcional: Guardar en base de datos + $user->stamps()->create([ + 'file_path' => $path, + 'file_name' => $request->file('stamp')->getClientOriginalName(), + 'type' => $request->type ?? 'custom' + ]); + + return response()->json([ + 'success' => true, + 'path' => Storage::url($path), + 'filename' => basename($path) + ]); + + } catch (\Exception $e) { + \Log::error('Error uploading stamp: ' . $e->getMessage()); + + return response()->json([ + 'success' => false, + 'message' => 'Error al subir el sello' + ], 500); + } + } + + /** + * Obtener firmas del usuario + */ + public function getSignatures() + { + $user = auth()->user(); + $signatures = $user->signatures()->get()->map(function($signature) { + return [ + 'id' => $signature->id, + 'url' => Storage::url($signature->file_path), + 'name' => $signature->file_name + ]; + }); + + return response()->json([ + 'success' => true, + 'signatures' => $signatures + ]); + } + + /** + * Obtener sellos del usuario + */ + public function getStamps() + { + $user = auth()->user(); + $stamps = $user->stamps()->get()->map(function($stamp) { + return [ + 'id' => $stamp->id, + 'url' => Storage::url($stamp->file_path), + 'name' => $stamp->file_name, + 'type' => $stamp->type + ]; + }); + + return response()->json([ + 'success' => true, + 'stamps' => $stamps + ]); + } + + /** + * Descargar documento + */ + public function download(Document $document, $versionId = null) + { + $this->authorize('view', $document); + + $version = $versionId ? + $document->versions()->findOrFail($versionId) : + $document->currentVersion; + + if (!$version || !Storage::exists($version->file_path)) { + abort(404); + } + + return Storage::download($version->file_path, $document->name . '.pdf'); + } + + /** + * Obtener el PDF actual para edición + */ + public function getPdfForEditing(Document $document) + { + $this->authorize('view', $document); + + try { + if ($document->getFirstMedia('documents')) { + $filePath = $document->getFirstMedia('documents')->getPath(); + } else { + $filePath = $document->file_path; + } + + if (!Storage::exists($filePath)) { + abort(404); + } + + $pdfContent = Storage::get($filePath); + $base64Pdf = base64_encode($pdfContent); + + return response()->json([ + 'success' => true, + 'pdf_data' => $base64Pdf, + 'document_name' => $document->name + ]); + + } catch (\Exception $e) { + \Log::error('Error getting PDF for editing: ' . $e->getMessage()); + + return response()->json([ + 'success' => false, + 'message' => 'Error al cargar el PDF' + ], 500); + } + } } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 97d1716..b291c68 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\Category; +use App\Models\Folder; use App\Models\Project; use App\Models\User; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; @@ -11,7 +12,7 @@ use Illuminate\Support\Facades\Storage; class ProjectController extends Controller { - use AuthorizesRequests; // ← Añadir este trait + use AuthorizesRequests; /** * Display a listing of the resource. @@ -43,7 +44,7 @@ class ProjectController extends Controller 'project' => $project, 'categories' => Category::orderBy('name')->get(), 'users' => User::where('id', '!=', auth()->id())->get(), - 'companies' => \App\Models\Company::all(), // Pass companies to the view + 'companies' => \App\Models\Company::all(), // Pass companies to the view, ]); } @@ -93,6 +94,12 @@ class ProjectController extends Controller if($request->has('categories')) { $project->categories()->sync($request->categories); } + + Folder::create([ + 'name' => 'Project', + 'project_id' => $project->id, + 'parent_id' => null, + ]); return redirect()->route('projects.show', $project)->with('success', 'Proyecto creado exitosamente'); @@ -172,6 +179,9 @@ class ProjectController extends Controller // } + /** + * Display the specified resource. + */ public function __invoke(Project $project) { return view('projects.show', [ diff --git a/app/Livewire/CodeEdit.php b/app/Livewire/CodeEdit.php new file mode 100644 index 0000000..93d2fa4 --- /dev/null +++ b/app/Livewire/CodeEdit.php @@ -0,0 +1,235 @@ + 'required|string|min:2|max:50', + 'codeInput' => 'required|string', + 'labelInput' => 'required|string', + 'maxLength' => 'required|integer|min:2|max:12', + ]; + + public function mount($componentId, $initialName = '') + { + $this->componentId = $componentId; + $this->name = $initialName; + $this->maxLength = 3; + + // Disparar evento inicial para establecer el nombre + $this->dispatch('nameUpdated', + componentId: $this->componentId, + data: [ + 'name' => $this->name + ] + ); + } + + public function updateName() + { + $this->validate([ + 'name' => 'required|string|min:2|max:50', + ]); + + $this->dispatch('nameUpdated', + componentId: $this->componentId, + data: [ + 'name' => $this->name + ] + ); + } + + public function updateMaxLength() + { + $this->validate([ + 'maxLength' => 'integer|min:2|max:12', + ]); + + if (strlen($this->codeInput) > $this->maxLength) { + $this->codeInput = substr($this->codeInput, 0, $this->maxLength); + } + } + + public function addField() + { + $this->validate([ + 'codeInput' => "required|string|size:{$this->maxLength}", + 'labelInput' => 'required|string|min:1', + ], [ + 'codeInput.size' => "El código debe tener exactamente {$this->maxLength} caracteres", + ]); + + $this->documentTypes[] = [ + 'code' => $this->codeInput, + 'label' => $this->labelInput, + 'max_length' => $this->maxLength, + ]; + + $this->sortList(); + $this->reset(['codeInput', 'labelInput']); + + $this->dispatch('componentUpdated', + componentId: $this->componentId, // Cambiado aquí + data: [ + 'documentTypes' => $this->documentTypes, + 'maxLength' => $this->maxLength + ] + ); + } + + public function addCode() + { + $this->validate([ + 'codeInput' => "required|string|size:{$this->maxLength}", + ], [ + 'codeInput.size' => "El código debe tener exactamente {$this->maxLength} caracteres", + ]); + + $this->dispatch('focus-label-input'); + } + + public function addLabel() + { + $this->validate([ + 'labelInput' => 'required|string|min:1', + ]); + + if (!empty($this->codeInput) && !empty($this->labelInput)) { + $this->addField(); + } + } + + public function removeField($index) + { + if (isset($this->documentTypes[$index])) { + unset($this->documentTypes[$index]); + $this->documentTypes = array_values($this->documentTypes); + + $this->dispatch('componentUpdated', + componentId: $this->componentId, // Cambiado aquí + data: [ + 'documentTypes' => $this->documentTypes, + 'maxLength' => $this->maxLength + ] + ); + } + } + + public function updatedMaxLength($value) + { + $this->validate([ + 'maxLength' => 'integer|min:2|max:12', + ]); + + if (strlen($this->codeInput) > $value) { + $this->codeInput = substr($this->codeInput, 0, $value); + } + } + + public function updatedCodeInput($value) + { + if (strlen($value) > $this->maxLength) { + $this->codeInput = substr($value, 0, $this->maxLength); + } + + $this->codeInput = strtoupper($value); + } + + public function sortByCode() + { + if ($this->sortBy === 'code') { + $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc'; + } else { + $this->sortBy = 'code'; + $this->sortDirection = 'asc'; + } + $this->sortList(); + } + + public function sortByLabel() + { + if ($this->sortBy === 'label') { + $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc'; + } else { + $this->sortBy = 'label'; + $this->sortDirection = 'asc'; + } + $this->sortList(); + } + + private function sortList() + { + $direction = $this->sortDirection === 'asc' ? SORT_ASC : SORT_DESC; + + if ($this->sortBy === 'code') { + array_multisort( + array_column($this->documentTypes, 'code'), + $direction, + SORT_STRING, + $this->documentTypes + ); + } else { + array_multisort( + array_column($this->documentTypes, 'label'), + $direction, + SORT_STRING, + $this->documentTypes + ); + } + } + + public function getSortedDocumentTypesProperty() + { + $sorted = $this->documentTypes; + $direction = $this->sortDirection === 'asc' ? SORT_ASC : SORT_DESC; + + if ($this->sortBy === 'code') { + array_multisort( + array_column($sorted, 'code'), + $direction, + SORT_STRING, + $sorted + ); + } else { + array_multisort( + array_column($sorted, 'label'), + $direction, + SORT_STRING, + $sorted + ); + } + + return $sorted; + } + + public function getTotalDocumentTypesProperty() + { + return count($this->documentTypes); + } + + public function getSortIcon($column) + { + if ($this->sortBy !== $column) { + return 'sort'; + } + + return $this->sortDirection === 'asc' ? 'sort-up' : 'sort-down'; + } + + public function render() + { + return view('livewire.code-edit'); + } +} diff --git a/app/Livewire/ProjectDocumentList.php b/app/Livewire/ProjectDocumentList.php new file mode 100644 index 0000000..5c476e2 --- /dev/null +++ b/app/Livewire/ProjectDocumentList.php @@ -0,0 +1,273 @@ +setPrimaryKey('id') + ->setAdditionalSelects(['documents.id as id']) + + /*->setConfigurableAreas([ + 'toolbar-left-start' => ['includes.areas.toolbar-left-start', ['param1' => 'Default', 'param2' => ['param2' => 2]]], + ])*/ + ->setPaginationEnabled() + ->setPaginationMethod('simple') + ->setPaginationVisibilityEnabled() + + + //->setReorderEnabled() + ->setHideReorderColumnUnlessReorderingEnabled() + ->setSecondaryHeaderTrAttributes(function ($rows) { + return ['class' => 'bg-gray-100']; + }) + ->setSecondaryHeaderTdAttributes(function (Column $column, $rows) { + if ($column->isField('id')) { + return ['class' => 'text-red-100']; + } + return ['default' => true]; + }) + ->setFooterTrAttributes(function ($rows) { + return ['class' => 'bg-gray-100']; + }) + ->setFooterTdAttributes(function (Column $column, $rows) { + if ($column->isField('name')) { + return ['class' => 'text-green-500']; + } + return ['default' => true]; + }) + ->setHideBulkActionsWhenEmptyEnabled() + ->setUseHeaderAsFooterEnabled() + + ->setPaginationEnabled() + ->setPaginationVisibilityEnabled() + //->setToolsDisabled() + //->setToolBarDisabled() + + // Configuración de paginación + ->setPerPage(25) // Número de elementos por página + ->setPerPageAccepted([10, 25, 50, 100]) // Opciones de elementos por página + ->setPaginationEnabled() // Asegurar que la paginación esté habilitada + ->setPaginationVisibilityStatus(true); // Hacer visible el paginador + ; + } + + public function mount($projectId = null, $folderId = null) + { + $this->projectId = $projectId; + $this->folderId = $folderId; + } + + public function columns(): array + { + return [ + Column::make("Código", "code") + ->sortable() + ->searchable() + ->secondaryHeaderFilter('code') // Filtro para esta columna + ->format( + fn($value, $row, Column $column) => + ''.$value.'' + )->html(), + + Column::make("Nombre", "name") + ->sortable() + ->searchable() + ->secondaryHeaderFilter('name') // Filtro para esta columna + ->format( + fn($value, $row, Column $column) => + '
+ + '.\App\Helpers\FileHelper::getFileIconSvg($value).' + + + '.$value.' + +
' + )->html(), + + Column::make("Estado", "status") + ->sortable() + ->searchable() + ->secondaryHeaderFilter('status') // Filtro para esta columna + ->format( + fn($value, $row, Column $column) => + ''. + $value.'' + )->html(), + + Column::make("Revisión", "revision") + ->sortable() + ->searchable(), + + Column::make("Versión", "version") + ->sortable() + ->searchable(), + + Column::make("Área", "area") + ->sortable() + ->searchable() + ->secondaryHeaderFilter('area'), // Filtro para esta columna + + Column::make("Disciplina", "discipline") + ->sortable() + ->searchable() + ->secondaryHeaderFilter('discipline'), // Filtro para esta columna + + Column::make("Tipo", "document_type") + ->sortable() + ->searchable() + ->secondaryHeaderFilter('type'), // Filtro para esta columna + + Column::make("Fecha Entrada", "entry_date") + ->sortable() + ->searchable() + ->format( + fn($value, $row, Column $column) => + $value ? \Carbon\Carbon::parse($value)->format('d/m/Y') : '-' + ), + + Column::make("Actualizado", "updated_at") + ->sortable() + ->searchable() + ->format( + fn($value, $row, Column $column) => + $value ? \Carbon\Carbon::parse($value)->diffForHumans() : '-' + ), + ]; + } + + public function filters(): array + { + return [ + TextFilter::make('Código', 'code') // Agregar clave 'code' + ->config([ + 'placeholder' => 'Buscar por código', + ]) + ->filter(function (Builder $builder, string $value) { + $builder->where('documents.code', 'like', '%'.$value.'%'); + }), + + TextFilter::make('Nombre', 'name') // Agregar clave 'name' + ->config([ + 'placeholder' => 'Buscar por nombre', + ]) + ->filter(function (Builder $builder, string $value) { + $builder->where('documents.name', 'like', '%'.$value.'%'); + }), + + SelectFilter::make('Estado', 'status') // Agregar clave 'status' + ->options([ + '' => 'Todos', + 'active' => 'Activo', + 'pending' => 'Pendiente', + 'inactive' => 'Inactivo', + ]) + ->filter(function (Builder $builder, string $value) { + if ($value) { + $builder->where('documents.status', $value); + } + }), + + SelectFilter::make('Disciplina', 'discipline') // Agregar clave 'discipline' + ->options( + collect(['Estructural', 'Arquitectura', 'Eléctrica', 'Mecánica', 'Civil', 'Otros']) + ->prepend('Todas', '') + ->toArray() + ) + ->filter(function (Builder $builder, string $value) { + if ($value) { + $builder->where('documents.discipline', $value); + } + }), + + SelectFilter::make('Area', 'area') // Agregar clave 'area' + ->options( + collect(['Estructural', 'Arquitectura', 'Eléctrica', 'Mecánica', 'Civil', 'Otros']) + ->prepend('Todas', '') + ->toArray() + ) + ->filter(function (Builder $builder, string $value) { + if ($value) { + $builder->where('documents.area', $value); + } + }), + + SelectFilter::make('Tipo', 'type') // Agregar clave 'document_type' + ->options( + collect(['Estructural', 'Arquitectura', 'Eléctrica', 'Mecánica', 'Civil', 'Otros']) + ->prepend('Todas', '') + ->toArray() + ) + ->filter(function (Builder $builder, string $value) { + if ($value) { + $builder->where('documents.document_type', $value); + } + }), + ]; + } + + public function builder(): Builder + { + $query = Document::query()->where('project_id', $this->projectId); + + if ($this->folderId) { + $query->where('folder_id', $this->folderId); + } else { + $query->whereNull('folder_id'); + } + + return $query->with('user'); + } + + public function bulkActions(): array + { + return [ + 'activate' => 'Activar', + 'deactivate' => 'Desactivar', + 'export' => 'Exportar', + ]; + } + + public function export() + { + $documents = $this->getSelected(); + + $this->clearSelected(); + + return Excel::download(new DocumentsExport($documents), 'documentos.xlsx'); + } + + public function activate() + { + Document::whereIn('id', $this->getSelected())->update(['status' => 'active']); + $this->clearSelected(); + $this->dispatch('documents-updated'); + } + + public function deactivate() + { + Document::whereIn('id', $this->getSelected())->update(['status' => 'inactive']); + $this->clearSelected(); + $this->dispatch('documents-updated'); + } +} \ No newline at end of file diff --git a/app/Livewire/ProjectNameCoder.php b/app/Livewire/ProjectNameCoder.php new file mode 100644 index 0000000..5c43255 --- /dev/null +++ b/app/Livewire/ProjectNameCoder.php @@ -0,0 +1,149 @@ + 'headerLabelUpdate', + 'componentUpdated' => 'handleComponentUpdate', + 'removeComponent' => 'removeComponent' + ]; + + public function mount() + { + // Inicializar con un componente vacío + $this->addComponent(); + } + + public function addComponent() + { + $id = $this->nextId++; + $this->components[] = [ + 'id' => $id, + 'data' => [], + 'order' => count($this->components), + 'headerLabel' => '' + ]; + } + + public function removeComponent($componentId) + { + $this->components = array_filter($this->components, function($component) use ($componentId) { + return $component['id'] != $componentId; + }); + + // Reindexar el orden + $this->reorderComponents(); + } + + public function headerLabelUpdate($componentId, $data) + { + foreach ($this->components as &$component) { + if ($component['id'] == $componentId) { + $component['headerLabel'] = $data['name']; + break; + } + } + } + + public function handleComponentUpdate($componentId, $data) + { + foreach ($this->components as &$component) { + if ($component['id'] == $componentId) { + $component['data'] = $data; + break; + } + } + } + + public function updateComponentOrder($orderedIds) + { + foreach ($orderedIds as $index => $id) { + foreach ($this->components as &$component) { + if ($component['id'] == $id) { + $component['order'] = $index; + break; + } + } + } + + // Ordenar el array por el campo 'order' + usort($this->components, function($a, $b) { + return $a['order'] - $b['order']; + }); + } + + private function reorderComponents() + { + foreach ($this->components as $index => &$component) { + $component['order'] = $index; + } + } + + public function moveComponentUp($componentId) + { + $index = $this->findComponentIndex($componentId); + + if ($index > 0) { + // Intercambiar con el componente anterior + $temp = $this->components[$index]; + $this->components[$index] = $this->components[$index - 1]; + $this->components[$index - 1] = $temp; + + // Actualizar órdenes + $this->reorderComponents(); + } + } + + public function moveComponentDown($componentId) + { + $index = $this->findComponentIndex($componentId); + + if ($index < count($this->components) - 1) { + // Intercambiar con el componente siguiente + $temp = $this->components[$index]; + $this->components[$index] = $this->components[$index + 1]; + $this->components[$index + 1] = $temp; + + // Actualizar órdenes + $this->reorderComponents(); + } + } + + private function findComponentIndex($componentId) + { + foreach ($this->components as $index => $component) { + if ($component['id'] == $componentId) { + return $index; + } + } + return -1; + } + + public function getComponentsCountProperty() + { + return count($this->components); + } + + public function getTotalDocumentTypesProperty() + { + $total = 0; + foreach ($this->components as $component) { + if (isset($component['data']['documentTypes'])) { + $total += count($component['data']['documentTypes']); + } + } + return $total; + } + + public function render() + { + return view('livewire.project-name-coder'); + } +} diff --git a/app/Livewire/ProjectShow.php b/app/Livewire/ProjectShow.php index 8e4836b..adda360 100644 --- a/app/Livewire/ProjectShow.php +++ b/app/Livewire/ProjectShow.php @@ -11,6 +11,8 @@ use App\Models\Document; use Illuminate\Validation\Rule; use Illuminate\Support\Facades\Auth; +use App\Helpers\DocumentIdentifier; + class ProjectShow extends Component { @@ -31,6 +33,8 @@ class ProjectShow extends Component public $selectedFiles = []; // Archivos temporales en el modal public $uploadProgress = []; + protected $listeners = ['documents-updated' => '$refresh']; + public function mount(Project $project) { @@ -80,28 +84,6 @@ class ProjectShow extends Component $this->project->refresh(); } - /*public function uploadFiles(): void - { - $this->validate([ - 'files.*' => 'file|max:10240|mimes:pdf,docx,xlsx,jpg,png' - ]); - dd($this->files); - foreach ($this->files as $file) { - Document::create([ - 'name' => $file->getClientOriginalName(), - 'file_path' => $file->store("projects/{$this->project->id}/documents"), - 'project_id' => $this->project->id, - 'folder_id' => $this->currentFolder?->id - ]); - } - - $this->reset('files'); - if ($this->currentFolder) { - $this->currentFolder->refresh(); // Recargar documentos - } - $this->reset('files'); - }*/ - public function getDocumentsProperty() { return $this->currentFolder @@ -158,20 +140,41 @@ class ProjectShow extends Component $this->selectedFiles = array_values($this->selectedFiles); // Reindexar array } - // Método para confirmar y guardar public function uploadFiles(): void { foreach ($this->selectedFiles as $file) { - Document::create([ - 'name' => $file->getClientOriginalName(), - 'file_path' => $file->store("projects/{$this->project->id}/documents"), - 'project_id' => $this->project->id, // Asegurar que se envía - 'folder_id' => $this->currentFolder?->id, - 'user_id' => Auth::id(), - //'status' => 'active' // Añadir si tu modelo lo requiere - ]); + //$analizador = analizarDocumento(); + //print_r($analizador); + //$resultado1 = $analizador->analizarDocumento($file->getClientOriginalName()); + + $code = $this->project->reference; + + // Buscar si ya existe un documento con el mismo nombre en el mismo proyecto y carpeta + $existingDocument = Document::where('project_id', $this->project->id) + ->where('folder_id', $this->currentFolder?->id) + ->where('name', $file->getClientOriginalName()) + ->first(); + + if ($existingDocument) { + // Si existe, crear una nueva versión/revisión + $existingDocument->createVersion($file); + + } else { + // Si no existe, crear el documento con revisión 0 + $document = Document::create([ + 'name' => $file->getClientOriginalName(), + 'file_path' => $file->store("projects/{$this->project->id}/documents"), + 'project_id' => $this->project->id, + 'folder_id' => $this->currentFolder?->id, + 'issuer_id' => Auth::id(), + 'code' => $code, + 'entry_date' => now(), + 'revision' => 0, // Revisión inicial + ]); + $document->createVersion($file); + } } - + $this->resetUpload(); $this->project->refresh(); } @@ -226,7 +229,8 @@ class ProjectShow extends Component 'file_path' => $path, 'project_id' => $this->project->id, 'folder_id' => $this->currentFolder?->id, - 'user_id' => Auth::id() + 'user_id' => Auth::id(), + 'code' => $code, ]); } catch (\Exception $e) { @@ -247,4 +251,9 @@ class ProjectShow extends Component { return \App\Helpers\ProjectNamingSchema::generate($fields); } + + public function sellectAllDocuments() + { + $this->selectedFiles = $this->documents->pluck('id')->toArray(); + } } diff --git a/app/Models/Document.php b/app/Models/Document.php index 3fd66e5..ef4f98f 100644 --- a/app/Models/Document.php +++ b/app/Models/Document.php @@ -6,6 +6,8 @@ use App\Events\DocumentVersionUpdated; use Illuminate\Database\Eloquent\Model; use Spatie\Activitylog\LogOptions; use Spatie\Activitylog\Traits\LogsActivity; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; class Document extends Model { @@ -20,22 +22,63 @@ class Document extends Model 'file_path', 'project_id', // Asegurar que está en fillable 'folder_id', - 'user_id', + 'issuer', 'status', 'revision', 'version', 'discipline', 'document_type', - 'issuer', 'entry_date', 'current_version_id', 'code', ]; - - public function versions() { + protected static function booted() + { + static::created(function ($document) { + if (request()->hasFile('file')) { + $file = request()->file('file'); + $document->createVersion($file); + } + }); + } + + /** + * Get all versions of the document. + */ + public function versions(): HasMany + { return $this->hasMany(DocumentVersion::class); } + + /** + * Get the current version of the document. + */ + public function currentVersion(): BelongsTo + { + return $this->belongsTo(DocumentVersion::class, 'current_version_id'); + } + + /** + * Get the latest version of the document. + */ + public function getLatestVersionAttribute() + { + return $this->versions()->latestFirst()->first(); + } + + /** + * Create a new version from file content. + */ + public function createVersion(string $content, array $changes = [], ?User $user = null): DocumentVersion + { + $version = DocumentVersion::createFromContent($this, $content, $changes, $user); + + // Update current version pointer + $this->update(['current_version_id' => $version->id]); + + return $version; + } public function approvals() { return $this->hasMany(Approval::class); @@ -44,17 +87,6 @@ class Document extends Model public function comments() { return $this->hasMany(Comment::class)->whereNull('parent_id'); } - - - public function createVersion($file) - { - return $this->versions()->create([ - 'file_path' => $file->store("documents/{$this->id}/versions"), - 'hash' => hash_file('sha256', $file), - 'user_id' => auth()->id(), - 'version_number' => $this->versions()->count() + 1 - ]); - } public function getCurrentVersionAttribute() { @@ -63,7 +95,7 @@ class Document extends Model public function uploadVersion($file) { - $this->versions()->create([ + $version = $this->versions()->create([ 'file_path' => $file->store("projects/{$this->id}/versions"), 'hash' => hash_file('sha256', $file), 'version' => $this->versions()->count() + 1, @@ -82,4 +114,9 @@ class Document extends Model ->logUnguarded(); } + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + } diff --git a/app/Models/DocumentVersion.php b/app/Models/DocumentVersion.php index 001827d..13bb5c9 100644 --- a/app/Models/DocumentVersion.php +++ b/app/Models/DocumentVersion.php @@ -2,9 +2,320 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Support\Facades\Storage; class DocumentVersion extends Model { - // -} + use HasFactory; + + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'document_id', + 'file_path', + 'hash', + 'version', + 'user_id', + 'changes', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'changes' => 'array', + 'version' => 'integer', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ]; + + /** + * The attributes that should be appended to the model's array form. + * + * @var array + */ + protected $appends = [ + 'file_url', + 'file_size_formatted', + 'created_at_formatted', + ]; + + /** + * Boot function for model events + */ + protected static function boot() + { + parent::boot(); + + static::creating(function ($model) { + // Asegurar que la versión sea incremental para el mismo documento + if (empty($model->version)) { + $lastVersion = self::where('document_id', $model->document_id) + ->max('version'); + $model->version = $lastVersion ? $lastVersion + 1 : 1; + } + }); + + static::deleting(function ($model) { + // No eliminar el archivo físico si hay otras versiones que lo usan + $sameFileCount = self::where('file_path', $model->file_path) + ->where('id', '!=', $model->id) + ->count(); + + if ($sameFileCount === 0 && Storage::exists($model->file_path)) { + Storage::delete($model->file_path); + } + }); + } + + /** + * Get the document that owns the version. + */ + public function document(): BelongsTo + { + return $this->belongsTo(Document::class); + } + + /** + * Get the user who created the version. + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + /** + * Get the file URL for the version. + */ + public function getFileUrlAttribute(): string + { + return Storage::url($this->file_path); + } + + /** + * Get the file size in a human-readable format. + */ + public function getFileSizeFormattedAttribute(): string + { + if (!Storage::exists($this->file_path)) { + return '0 B'; + } + + $bytes = Storage::size($this->file_path); + + $units = ['B', 'KB', 'MB', 'GB', 'TB']; + $index = 0; + + while ($bytes >= 1024 && $index < count($units) - 1) { + $bytes /= 1024; + $index++; + } + + return round($bytes, 2) . ' ' . $units[$index]; + } + + /** + * Get the actual file size in bytes. + */ + public function getFileSizeAttribute(): int + { + return Storage::exists($this->file_path) ? Storage::size($this->file_path) : 0; + } + + /** + * Get formatted created_at date. + */ + public function getCreatedAtFormattedAttribute(): string + { + return $this->created_at->format('d/m/Y H:i'); + } + + /** + * Get the version label (v1, v2, etc.) + */ + public function getVersionLabelAttribute(): string + { + return 'v' . $this->version; + } + + /** + * Check if this is the current version of the document. + */ + public function getIsCurrentAttribute(): bool + { + return $this->document->current_version_id === $this->id; + } + + /** + * Get changes summary for display. + */ + public function getChangesSummaryAttribute(): string + { + if (empty($this->changes)) { + return 'Sin cambios registrados'; + } + + $changes = $this->changes; + + if (is_array($changes)) { + $summary = []; + + if (isset($changes['annotations_count']) && $changes['annotations_count'] > 0) { + $summary[] = $changes['annotations_count'] . ' anotación(es)'; + } + + if (isset($changes['signatures_count']) && $changes['signatures_count'] > 0) { + $summary[] = $changes['signatures_count'] . ' firma(s)'; + } + + if (isset($changes['stamps_count']) && $changes['stamps_count'] > 0) { + $summary[] = $changes['stamps_count'] . ' sello(s)'; + } + + if (isset($changes['edited_by'])) { + $summary[] = 'por ' . $changes['edited_by']; + } + + return implode(', ', $summary); + } + + return (string) $changes; + } + + /** + * Scope a query to only include versions of a specific document. + */ + public function scopeOfDocument($query, $documentId) + { + return $query->where('document_id', $documentId); + } + + /** + * Scope a query to order versions by latest first. + */ + public function scopeLatestFirst($query) + { + return $query->orderBy('version', 'desc'); + } + + /** + * Scope a query to order versions by oldest first. + */ + public function scopeOldestFirst($query) + { + return $query->orderBy('version', 'asc'); + } + + /** + * Get the previous version. + */ + public function getPreviousVersion(): ?self + { + return self::where('document_id', $this->document_id) + ->where('version', '<', $this->version) + ->orderBy('version', 'desc') + ->first(); + } + + /** + * Get the next version. + */ + public function getNextVersion(): ?self + { + return self::where('document_id', $this->document_id) + ->where('version', '>', $this->version) + ->orderBy('version', 'asc') + ->first(); + } + + /** + * Check if file exists in storage. + */ + public function fileExists(): bool + { + return Storage::exists($this->file_path); + } + + /** + * Get file content. + */ + public function getFileContent(): ?string + { + return $this->fileExists() ? Storage::get($this->file_path) : null; + } + + /** + * Verify file integrity using hash. + */ + public function verifyIntegrity(): bool + { + if (!$this->fileExists()) { + return false; + } + + $currentHash = hash_file('sha256', Storage::path($this->file_path)); + return $currentHash === $this->hash; + } + + /** + * Create a new version from file content. + */ + public static function createFromContent(Document $document, string $content, array $changes = [], ?User $user = null): self + { + $user = $user ?: auth()->user(); + + // Calcular hash + $hash = hash('sha256', $content); + + // Determinar siguiente versión + $lastVersion = self::where('document_id', $document->id)->max('version'); + $version = $lastVersion ? $lastVersion + 1 : 1; + + // Guardar archivo + $filePath = "documents/{$document->id}/versions/v{$version}.pdf"; + Storage::put($filePath, $content); + + // Crear registro + return self::create([ + 'document_id' => $document->id, + 'file_path' => $filePath, + 'hash' => $hash, + 'version' => $version, + 'user_id' => $user->id, + 'changes' => $changes, + ]); + } + + /** + * Restore this version as the current version. + */ + public function restoreAsCurrent(): bool + { + if (!$this->fileExists()) { + return false; + } + + // Crear una nueva versión idéntica a esta + $content = $this->getFileContent(); + $newVersion = self::createFromContent( + $this->document, + $content, + ['restored_from' => 'v' . $this->version] + ); + + // Actualizar documento para apuntar a la nueva versión + $this->document->update([ + 'current_version_id' => $newVersion->id + ]); + + return true; + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 8c07288..3bfe57f 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,7 @@ "livewire/flux": "^2.1.1", "livewire/volt": "^1.7.0", "luvi-ui/laravel-luvi": "^0.6.0", + "rappasoft/laravel-livewire-tables": "^3.7", "spatie/laravel-activitylog": "^4.10", "spatie/laravel-medialibrary": "^11.12", "spatie/laravel-permission": "^6.17", diff --git a/composer.lock b/composer.lock index 5954c6a..2cb3b4e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,158 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3dbc041e01a11822ed0b28f2eb838625", + "content-hash": "066300d1440ecb28d9ef82afc2c057f2", "packages": [ + { + "name": "blade-ui-kit/blade-heroicons", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/driesvints/blade-heroicons.git", + "reference": "4553b2a1f6c76f0ac7f3bc0de4c0cfa06a097d19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/driesvints/blade-heroicons/zipball/4553b2a1f6c76f0ac7f3bc0de4c0cfa06a097d19", + "reference": "4553b2a1f6c76f0ac7f3bc0de4c0cfa06a097d19", + "shasum": "" + }, + "require": { + "blade-ui-kit/blade-icons": "^1.6", + "illuminate/support": "^9.0|^10.0|^11.0|^12.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.0|^10.5|^11.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Heroicons\\BladeHeroiconsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "BladeUI\\Heroicons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of Heroicons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-heroicons", + "keywords": [ + "Heroicons", + "blade", + "laravel" + ], + "support": { + "issues": "https://github.com/driesvints/blade-heroicons/issues", + "source": "https://github.com/driesvints/blade-heroicons/tree/2.6.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/driesvints", + "type": "github" + }, + { + "url": "https://www.paypal.com/paypalme/driesvints", + "type": "paypal" + } + ], + "time": "2025-02-13T20:53:33+00:00" + }, + { + "name": "blade-ui-kit/blade-icons", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/driesvints/blade-icons.git", + "reference": "7b743f27476acb2ed04cb518213d78abe096e814" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/driesvints/blade-icons/zipball/7b743f27476acb2ed04cb518213d78abe096e814", + "reference": "7b743f27476acb2ed04cb518213d78abe096e814", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/filesystem": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/view": "^8.0|^9.0|^10.0|^11.0|^12.0", + "php": "^7.4|^8.0", + "symfony/console": "^5.3|^6.0|^7.0", + "symfony/finder": "^5.3|^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.5.1", + "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.0|^10.5|^11.0" + }, + "bin": [ + "bin/blade-icons-generate" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Icons\\BladeIconsServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "BladeUI\\Icons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of icons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-icons", + "keywords": [ + "blade", + "icons", + "laravel", + "svg" + ], + "support": { + "issues": "https://github.com/blade-ui-kit/blade-icons/issues", + "source": "https://github.com/blade-ui-kit/blade-icons" + }, + "funding": [ + { + "url": "https://github.com/sponsors/driesvints", + "type": "github" + }, + { + "url": "https://www.paypal.com/paypalme/driesvints", + "type": "paypal" + } + ], + "time": "2025-02-13T20:35:06+00:00" + }, { "name": "brick/math", "version": "0.12.3", @@ -3999,6 +4149,87 @@ ], "time": "2024-04-27T21:32:50+00:00" }, + { + "name": "rappasoft/laravel-livewire-tables", + "version": "v3.7.3", + "source": { + "type": "git", + "url": "https://github.com/rappasoft/laravel-livewire-tables.git", + "reference": "74beb4c2672e024000d41ecad8a17b4ab8c934bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rappasoft/laravel-livewire-tables/zipball/74beb4c2672e024000d41ecad8a17b4ab8c934bd", + "reference": "74beb4c2672e024000d41ecad8a17b4ab8c934bd", + "shasum": "" + }, + "require": { + "blade-ui-kit/blade-heroicons": "^2.1", + "illuminate/contracts": "^10.0|^11.0|^12.0", + "illuminate/support": "^10.0|^11.0|^12.0", + "livewire/livewire": "^3.0|dev-main", + "php": "^8.1|^8.2|^8.3|^8.4" + }, + "require-dev": { + "brianium/paratest": "^5.0|^6.0|^7.0|^8.0|^9.0", + "ext-sqlite3": "*", + "larastan/larastan": "^2.6|^3.0", + "laravel/pint": "^1.10", + "monolog/monolog": "*", + "nunomaduro/collision": "^6.0|^7.0|^8.0|^9.0", + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.0|^10.0|^11.0|^12.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Rappasoft\\LaravelLivewireTables\\LaravelLivewireTablesServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Rappasoft\\LaravelLivewireTables\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Rappa", + "email": "rappa819@gmail.com", + "role": "Developer" + }, + { + "name": "Joe McElwee", + "email": "joe@lowerrocklabs.com", + "role": "Developer" + } + ], + "description": "A dynamic table component for Laravel Livewire", + "homepage": "https://github.com/rappasoft/laravel-livewire-tables", + "keywords": [ + "datatables", + "laravel", + "livewire", + "rappasoft", + "tables" + ], + "support": { + "issues": "https://github.com/rappasoft/laravel-livewire-tables/issues", + "source": "https://github.com/rappasoft/laravel-livewire-tables/tree/v3.7.3" + }, + "funding": [ + { + "url": "https://github.com/rappasoft", + "type": "github" + } + ], + "time": "2025-05-03T02:24:46+00:00" + }, { "name": "spatie/image", "version": "3.8.3", diff --git a/database/migrations/2025_04_19_000002_create_documents_table.php b/database/migrations/2025_04_19_000002_create_documents_table.php index 9bca6c2..4b31b75 100644 --- a/database/migrations/2025_04_19_000002_create_documents_table.php +++ b/database/migrations/2025_04_19_000002_create_documents_table.php @@ -13,10 +13,23 @@ return new class extends Migration { Schema::create('documents', function (Blueprint $table) { $table->id(); + $table->string('code'); $table->string('name'); - $table->enum('status', ['pending', 'in_review', 'approved', 'rejected'])->default('pending'); + $table->foreignId('project_id')->constrained(); $table->foreignId('folder_id')->nullable()->constrained(); + + $table->string('area', 2)->nullable(); + $table->string('discipline', 2)->nullable(); + $table->string('document_type', 3)->nullable(); + + $table->string('version')->nullable()->default("0"); + $table->string('revision')->nullable()->default("0"); + + $table->enum('status', [0, 1, 2, 3, 4])->default(0); //['pending', 'in_review', 'approved', 'rejected'] + + $table->string('issuer_id')->nullable(); + $table->date('entry_date')->nullable()->default(now()); //$table->foreignId('current_version_id')->nullable()->constrained('document_versions'); $table->timestamps(); }); diff --git a/database/migrations/2025_04_19_000003_create_document_versions_table.php b/database/migrations/2025_04_19_000003_create_document_versions_table.php index 865bf6b..b3d44a3 100644 --- a/database/migrations/2025_04_19_000003_create_document_versions_table.php +++ b/database/migrations/2025_04_19_000003_create_document_versions_table.php @@ -15,11 +15,19 @@ return new class extends Migration $table->id(); $table->foreignId('document_id')->constrained(); $table->string('file_path'); - $table->string('hash'); + $table->string('hash'); // SHA256 hash for integrity verification $table->unsignedInteger('version')->default(1); + $table->unsignedInteger('review')->default(0); $table->foreignId('user_id')->constrained(); $table->text('changes')->nullable(); $table->timestamps(); + + // Unique constraint to ensure one version per document + $table->unique(['document_id', 'version', 'review']); + + // Index for faster queries + $table->index(['document_id', 'version']); + $table->index('hash'); }); } diff --git a/database/migrations/2025_10_24_000001_add_fields_to_documents_table.php b/database/migrations/2025_10_24_000001_add_fields_to_documents_table.php deleted file mode 100644 index ed05511..0000000 --- a/database/migrations/2025_10_24_000001_add_fields_to_documents_table.php +++ /dev/null @@ -1,34 +0,0 @@ -string('code')->before('name'); - $table->string('revision')->nullable(); - $table->string('version')->nullable(); - $table->string('discipline')->nullable(); - $table->string('document_type')->nullable(); - $table->string('issuer')->nullable(); - $table->date('entry_date')->nullable(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('documents', function (Blueprint $table) { - $table->dropColumn(['code', 'revision', 'version', 'discipline', 'document_type', 'issuer', 'entry_date']); - }); - } -}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 84fd21f..c270686 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,9 @@ "autoprefixer": "^10.4.20", "axios": "^1.7.4", "concurrently": "^9.0.1", + "fabric": "^6.7.1", "laravel-vite-plugin": "^1.0", + "pdf-lib": "^1.17.1", "pdfjs-dist": "^5.2.133", "quill": "^2.0.3", "tailwindcss": "^4.0.7", @@ -431,6 +433,35 @@ "react": ">= 16" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/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==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@napi-rs/canvas": { "version": "0.1.70", "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.70.tgz", @@ -602,6 +633,22 @@ "node": ">= 10" } }, + "node_modules/@pdf-lib/standard-fonts": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", + "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", + "dependencies": { + "pako": "^1.0.6" + } + }, + "node_modules/@pdf-lib/upng": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", + "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", + "dependencies": { + "pako": "^1.0.10" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.40.2", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", @@ -1067,6 +1114,15 @@ "vite": "^5.2.0 || ^6" } }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -1086,6 +1142,65 @@ "react-dom": "*" } }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "optional": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "optional": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "optional": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1110,6 +1225,26 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/aproba": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", + "optional": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1163,6 +1298,22 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "optional": true + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/browserslist": { "version": "4.24.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", @@ -1228,6 +1379,21 @@ ], "license": "CC-BY-4.0" }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1256,6 +1422,15 @@ "node": ">=8" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -1288,6 +1463,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1300,6 +1484,12 @@ "node": ">= 0.8" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "optional": true + }, "node_modules/concurrently": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.1.2.tgz", @@ -1325,6 +1515,85 @@ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "optional": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "optional": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "optional": true + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "optional": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "optional": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "optional": true + }, + "node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1334,6 +1603,12 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -1346,6 +1621,19 @@ "node": ">=0.10" } }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "optional": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -1385,6 +1673,18 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "optional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -1479,11 +1779,75 @@ "node": ">=6" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "optional": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "optional": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "optional": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" }, + "node_modules/fabric": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/fabric/-/fabric-6.7.1.tgz", + "integrity": "sha512-dLxSmIvN4InJf4xOjbl1LFWh8WGOUIYtcuDIGs2IN0Z9lI0zGobfesDauyEhI1+owMLTPCCiEv01rpYXm7g2EQ==", + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "jsdom": "^20.0.1" + } + }, "node_modules/fast-diff": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", @@ -1537,6 +1901,36 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "optional": true + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1559,6 +1953,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1605,6 +2020,27 @@ "node": ">= 0.4" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -1659,6 +2095,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -1671,6 +2113,74 @@ "node": ">= 0.4" } }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "optional": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "optional": true + }, "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", @@ -1680,6 +2190,12 @@ "node": ">=8" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "optional": true + }, "node_modules/jiti": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", @@ -1695,6 +2211,51 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "peer": true }, + "node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "optional": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/laravel-vite-plugin": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.2.0.tgz", @@ -1976,6 +2537,30 @@ "loose-envify": "cli.js" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -2006,6 +2591,88 @@ "node": ">= 0.6" } }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "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==", + "optional": true + }, + "node_modules/nan": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", + "optional": true + }, "node_modules/nanoid": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", @@ -2024,12 +2691,69 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "optional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "optional": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "optional": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "optional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", @@ -2039,20 +2763,89 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.22", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", + "integrity": "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==", + "optional": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "peer": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/parchment": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz", "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==" }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "optional": true, + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pdf-lib": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", + "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==", + "dependencies": { + "@pdf-lib/standard-fonts": "^1.0.0", + "@pdf-lib/upng": "^1.0.1", + "pako": "^1.0.11", + "tslib": "^1.11.1" + } + }, + "node_modules/pdf-lib/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "node_modules/pdfjs-dist": { "version": "5.2.133", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.2.133.tgz", @@ -2133,6 +2926,33 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "optional": true, + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "optional": true + }, "node_modules/quill": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz", @@ -2187,6 +3007,20 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "peer": true }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2196,6 +3030,28 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "optional": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rollup": { "version": "4.40.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", @@ -2255,12 +3111,68 @@ "tslib": "^2.1.0" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "optional": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "optional": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", "peer": true }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "optional": true + }, "node_modules/shell-quote": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz", @@ -2273,6 +3185,52 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "optional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2282,6 +3240,15 @@ "node": ">=0.10.0" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2323,6 +3290,12 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "optional": true + }, "node_modules/tailwindcss": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.8.tgz", @@ -2338,6 +3311,23 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tinyglobby": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", @@ -2377,6 +3367,33 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "optional": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "optional": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -2392,6 +3409,15 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", @@ -2422,6 +3448,22 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "optional": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "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==", + "optional": true + }, "node_modules/vite": { "version": "6.3.5", "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", @@ -2529,6 +3571,70 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "optional": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "optional": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "optional": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -2546,6 +3652,48 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "optional": true + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "optional": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "optional": true + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -2555,6 +3703,12 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index fd03503..861d860 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ "autoprefixer": "^10.4.20", "axios": "^1.7.4", "concurrently": "^9.0.1", + "fabric": "^6.7.1", "laravel-vite-plugin": "^1.0", + "pdf-lib": "^1.17.1", "pdfjs-dist": "^5.2.133", "quill": "^2.0.3", "tailwindcss": "^4.0.7", diff --git a/resources/js/pdfjs-5.2.133-dist/pdfjs-annotation-extension.js b/resources/js/pdfjs-5.2.133-dist/pdfjs-annotation-extension.js new file mode 100644 index 0000000..9e32f64 --- /dev/null +++ b/resources/js/pdfjs-5.2.133-dist/pdfjs-annotation-extension.js @@ -0,0 +1,2 @@ +/*! For license information please see pdfjs-annotation-extension.js.LICENSE.txt */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.PdfjsAnnotationExtension=t():e.PdfjsAnnotationExtension=t()}(self,(()=>(()=>{var e,t,r={289:(e,t,r)=>{"use strict";r.d(t,{A:()=>s});var n=r(1601),o=r.n(n),i=r(6314),a=r.n(i)()(o());a.push([e.id,".EditorFreeText-Modal{margin:0 auto}.EditorFreeText-Modal-Toolbar{border-top:0;display:flex;justify-content:space-between;margin:0 auto}.EditorFreeText-Modal-Toolbar .colorPalette{display:flex;margin:8px}.EditorFreeText-Modal-Toolbar .colorPalette .cell{cursor:pointer;width:22px;height:22px;margin-right:5px;border-radius:100px;display:flex;align-items:center;justify-content:center;border:1px solid #fff}.EditorFreeText-Modal-Toolbar .colorPalette .cell span{width:12px;height:12px;display:inline-block;border-radius:100px}.EditorFreeText-Modal-Toolbar .colorPalette .active{border:1px solid #bbb}",""]);const s=a},445:function(e){e.exports=function(){"use strict";var e={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},t=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,r=/\d/,n=/\d\d/,o=/\d\d?/,i=/\d*[^-_:/,()\s\d]+/,a={},s=function(e){return(e=+e)+(e>68?1900:2e3)},l=function(e){return function(t){this[e]=+t}},c=[/[+-]\d\d:?(\d\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if("Z"===e)return 0;var t=e.match(/([+-]|\d\d)/g),r=60*t[1]+(+t[2]||0);return 0===r?0:"+"===t[0]?-r:r}(e)}],u=function(e){var t=a[e];return t&&(t.indexOf?t:t.s.concat(t.f))},d=function(e,t){var r,n=a.meridiem;if(n){for(var o=1;o<=24;o+=1)if(e.indexOf(n(o,0,t))>-1){r=o>12;break}}else r=e===(t?"pm":"PM");return r},f={A:[i,function(e){this.afternoon=d(e,!1)}],a:[i,function(e){this.afternoon=d(e,!0)}],Q:[r,function(e){this.month=3*(e-1)+1}],S:[r,function(e){this.milliseconds=100*+e}],SS:[n,function(e){this.milliseconds=10*+e}],SSS:[/\d{3}/,function(e){this.milliseconds=+e}],s:[o,l("seconds")],ss:[o,l("seconds")],m:[o,l("minutes")],mm:[o,l("minutes")],H:[o,l("hours")],h:[o,l("hours")],HH:[o,l("hours")],hh:[o,l("hours")],D:[o,l("day")],DD:[n,l("day")],Do:[i,function(e){var t=a.ordinal,r=e.match(/\d+/);if(this.day=r[0],t)for(var n=1;n<=31;n+=1)t(n).replace(/\[|\]/g,"")===e&&(this.day=n)}],w:[o,l("week")],ww:[n,l("week")],M:[o,l("month")],MM:[n,l("month")],MMM:[i,function(e){var t=u("months"),r=(u("monthsShort")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(r<1)throw new Error;this.month=r%12||r}],MMMM:[i,function(e){var t=u("months").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\d+/,l("year")],YY:[n,function(e){this.year=s(e)}],YYYY:[/\d{4}/,l("year")],Z:c,ZZ:c};function h(r){var n,o;n=r,o=a&&a.formats;for(var i=(r=n.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,r,n){var i=n&&n.toUpperCase();return r||o[n]||e[n]||o[i].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,r){return t||r.slice(1)}))}))).match(t),s=i.length,l=0;l-1)return new Date(("X"===t?1e3:1)*e);var o=h(t)(e),i=o.year,a=o.month,s=o.day,l=o.hours,c=o.minutes,u=o.seconds,d=o.milliseconds,f=o.zone,p=o.week,m=new Date,g=s||(i||a?1:m.getDate()),v=i||m.getFullYear(),b=0;i&&!a||(b=a>0?a-1:m.getMonth());var y,w=l||0,x=c||0,S=u||0,C=d||0;return f?new Date(Date.UTC(v,b,g,w,x,S,C+60*f.offset*1e3)):r?new Date(Date.UTC(v,b,g,w,x,S,C)):(y=new Date(v,b,g,w,x,S,C),p&&(y=n(y).week(p).toDate()),y)}catch(e){return new Date("")}}(t,s,n,r),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(s)&&(this.$d=new Date("")),a={}}else if(s instanceof Array)for(var f=s.length,p=1;p<=f;p+=1){i[1]=s[p-1];var m=r.apply(this,i);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}p===f&&(this.$d=new Date(""))}else o.call(this,e)}}}()},517:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Solarize=void 0,t.Solarize=function(e){const t=e.data,r=e.width,n=4*r;let o=e.height;do{const e=(o-1)*n;let i=r;do{const r=e+4*(i-1);let n=t[r],o=t[r+1],a=t[r+2];n>127&&(n=255-n),o>127&&(o=255-o),a>127&&(a=255-a),t[r]=n,t[r+1]=o,t[r+2]=a}while(--i)}while(--o)}},540:e=>{"use strict";e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},661:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Threshold=void 0;const n=r(4892),o=r(6536),i=r(5483);t.Threshold=function(e){const t=255*this.threshold(),r=e.data,n=r.length;for(let e=0;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Konva=void 0;const n=r(8871),o=r(4060),i=r(6536),a=r(4473),s=r(7324),l=r(6267),c=r(7457),u=r(7949),d=r(1268),f=r(4723),h=r(9696),p=r(8665),m=r(9869),g=r(8604);t.Konva=o.Util._assign(n.Konva,{Util:o.Util,Transform:o.Transform,Node:i.Node,Container:a.Container,Stage:s.Stage,stages:s.stages,Layer:l.Layer,FastLayer:c.FastLayer,Group:u.Group,DD:d.DD,Shape:f.Shape,shapes:f.shapes,Animation:h.Animation,Tween:p.Tween,Easings:p.Easings,Context:m.Context,Canvas:g.Canvas}),t.default=t.Konva},961:(e,t,r)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=r(2551)},983:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Emboss=void 0;const n=r(4892),o=r(6536),i=r(4060),a=r(5483);t.Emboss=function(e){const t=10*this.embossStrength(),r=255*this.embossWhiteLevel(),n=this.embossDirection(),o=this.embossBlend(),a=e.data,s=e.width,l=e.height,c=4*s;let u=0,d=0,f=l;switch(n){case"top-left":u=-1,d=-1;break;case"top":u=-1,d=0;break;case"top-right":u=-1,d=1;break;case"right":u=0,d=1;break;case"bottom-right":u=1,d=1;break;case"bottom":u=1,d=0;break;case"bottom-left":u=1,d=-1;break;case"left":u=0,d=-1;break;default:i.Util.error("Unknown emboss direction: "+n)}do{const e=(f-1)*c;let n=u;f+n<1&&(n=0),f+n>l&&(n=0);const i=(f-1+n)*s*4;let h=s;do{const n=e+4*(h-1);let l=d;h+l<1&&(l=0),h+l>s&&(l=0);const c=i+4*(h-1+l),u=a[n]-a[c],f=a[n+1]-a[c+1],p=a[n+2]-a[c+2];let m=u;const g=m>0?m:-m;if((f>0?f:-f)>g&&(m=f),(p>0?p:-p)>g&&(m=p),m*=t,o){const e=a[n]+m,t=a[n+1]+m,r=a[n+2]+m;a[n]=e>255?255:e<0?0:e,a[n+1]=t>255?255:t<0?0:t,a[n+2]=r>255?255:r<0?0:r}else{let e=r-m;e<0?e=0:e>255&&(e=255),a[n]=a[n+1]=a[n+2]=e}}while(--h)}while(--f)},n.Factory.addGetterSetter(o.Node,"embossStrength",.5,(0,a.getNumberValidator)(),n.Factory.afterSetFilter),n.Factory.addGetterSetter(o.Node,"embossWhiteLevel",.5,(0,a.getNumberValidator)(),n.Factory.afterSetFilter),n.Factory.addGetterSetter(o.Node,"embossDirection","top-left",void 0,n.Factory.afterSetFilter),n.Factory.addGetterSetter(o.Node,"embossBlend",!1,void 0,n.Factory.afterSetFilter)},1020:(e,t,r)=>{"use strict";var n=r(6540),o=Symbol.for("react.element"),i=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,i={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)a.call(t,n)&&!l.hasOwnProperty(n)&&(i[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===i[n]&&(i[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:i,_owner:s.current}}t.Fragment=i,t.jsx=c,t.jsxs=c},1113:e=>{"use strict";e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},1268:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DD=void 0;const n=r(8871),o=r(4060);t.DD={get isDragging(){let e=!1;return t.DD._dragElements.forEach((t=>{"dragging"===t.dragStatus&&(e=!0)})),e},justDragged:!1,get node(){let e;return t.DD._dragElements.forEach((t=>{e=t.node})),e},_dragElements:new Map,_drag(e){const r=[];t.DD._dragElements.forEach(((t,n)=>{const{node:i}=t,a=i.getStage();a.setPointersPositions(e),void 0===t.pointerId&&(t.pointerId=o.Util._getFirstPointerId(e));const s=a._changedPointerPositions.find((e=>e.id===t.pointerId));if(s){if("dragging"!==t.dragStatus){const r=i.dragDistance();if(Math.max(Math.abs(s.x-t.startPointerPos.x),Math.abs(s.y-t.startPointerPos.y)){t.fire("dragmove",{type:"dragmove",target:t,evt:e},!0)}))},_endDragBefore(e){const r=[];t.DD._dragElements.forEach((o=>{const{node:i}=o,a=i.getStage();if(e&&a.setPointersPositions(e),!a._changedPointerPositions.find((e=>e.id===o.pointerId)))return;"dragging"!==o.dragStatus&&"stopped"!==o.dragStatus||(t.DD.justDragged=!0,n.Konva._mouseListenClick=!1,n.Konva._touchListenClick=!1,n.Konva._pointerListenClick=!1,o.dragStatus="stopped");const s=o.node.getLayer()||o.node instanceof n.Konva.Stage&&o.node;s&&-1===r.indexOf(s)&&r.push(s)})),r.forEach((e=>{e.draw()}))},_endDragAfter(e){t.DD._dragElements.forEach(((r,n)=>{"stopped"===r.dragStatus&&r.node.fire("dragend",{type:"dragend",target:r.node,evt:e},!0),"dragging"!==r.dragStatus&&t.DD._dragElements.delete(n)}))}},n.Konva.isBrowser&&(window.addEventListener("mouseup",t.DD._endDragBefore,!0),window.addEventListener("touchend",t.DD._endDragBefore,!0),window.addEventListener("touchcancel",t.DD._endDragBefore,!0),window.addEventListener("mousemove",t.DD._drag),window.addEventListener("touchmove",t.DD._drag),window.addEventListener("mouseup",t.DD._endDragAfter,!1),window.addEventListener("touchend",t.DD._endDragAfter,!1),window.addEventListener("touchcancel",t.DD._endDragAfter,!1))},1447:(e,t,r)=>{"use strict";var n=r(9805),o=r(3269),i=r(4823),a=r(7293),s=r(1998),l=-2,c=12,u=30;function d(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function f(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new n.Buf16(320),this.work=new n.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function h(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=1,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new n.Buf32(852),t.distcode=t.distdyn=new n.Buf32(592),t.sane=1,t.back=-1,0):l}function p(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,h(e)):l}function m(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?l:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=r,n.wbits=t,p(e))):l}function g(e,t){var r,n;return e?(n=new f,e.state=n,n.window=null,0!==(r=m(e,t))&&(e.state=null),r):l}var v,b,y=!0;function w(e){if(y){var t;for(v=new n.Buf32(512),b=new n.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(s(1,e.lens,0,288,v,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;s(2,e.lens,0,32,b,0,e.work,{bits:5}),y=!1}e.lencode=v,e.lenbits=9,e.distcode=b,e.distbits=5}function x(e,t,r,o){var i,a=e.state;return null===a.window&&(a.wsize=1<=a.wsize?(n.arraySet(a.window,t,r-a.wsize,a.wsize,0),a.wnext=0,a.whave=a.wsize):((i=a.wsize-a.wnext)>o&&(i=o),n.arraySet(a.window,t,r-o,i,a.wnext),(o-=i)?(n.arraySet(a.window,t,r-o,o,0),a.wnext=o,a.whave=a.wsize):(a.wnext+=i,a.wnext===a.wsize&&(a.wnext=0),a.whave>>8&255,r.check=i(r.check,B,2,0),b=0,y=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&b)<<8)+(b>>8))%31){e.msg="incorrect header check",r.mode=u;break}if(8!=(15&b)){e.msg="unknown compression method",r.mode=u;break}if(y-=4,_=8+(15&(b>>>=4)),0===r.wbits)r.wbits=_;else if(_>r.wbits){e.msg="invalid window size",r.mode=u;break}r.dmax=1<<_,e.adler=r.check=1,r.mode=512&b?10:c,b=0,y=0;break;case 2:for(;y<16;){if(0===g)break e;g--,b+=f[p++]<>8&1),512&r.flags&&(B[0]=255&b,B[1]=b>>>8&255,r.check=i(r.check,B,2,0)),b=0,y=0,r.mode=3;case 3:for(;y<32;){if(0===g)break e;g--,b+=f[p++]<>>8&255,B[2]=b>>>16&255,B[3]=b>>>24&255,r.check=i(r.check,B,4,0)),b=0,y=0,r.mode=4;case 4:for(;y<16;){if(0===g)break e;g--,b+=f[p++]<>8),512&r.flags&&(B[0]=255&b,B[1]=b>>>8&255,r.check=i(r.check,B,2,0)),b=0,y=0,r.mode=5;case 5:if(1024&r.flags){for(;y<16;){if(0===g)break e;g--,b+=f[p++]<>>8&255,r.check=i(r.check,B,2,0)),b=0,y=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&((k=r.length)>g&&(k=g),k&&(r.head&&(_=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),n.arraySet(r.head.extra,f,p,k,_)),512&r.flags&&(r.check=i(r.check,f,k,p)),g-=k,p+=k,r.length-=k),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===g)break e;k=0;do{_=f[p+k++],r.head&&_&&r.length<65536&&(r.head.name+=String.fromCharCode(_))}while(_&&k>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=c;break;case 10:for(;y<32;){if(0===g)break e;g--,b+=f[p++]<>>=7&y,y-=7&y,r.mode=27;break}for(;y<3;){if(0===g)break e;g--,b+=f[p++]<>>=1)){case 0:r.mode=14;break;case 1:if(w(r),r.mode=20,6===t){b>>>=2,y-=2;break e}break;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=u}b>>>=2,y-=2;break;case 14:for(b>>>=7&y,y-=7&y;y<32;){if(0===g)break e;g--,b+=f[p++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=u;break}if(r.length=65535&b,b=0,y=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(k=r.length){if(k>g&&(k=g),k>v&&(k=v),0===k)break e;n.arraySet(h,f,p,k,m),g-=k,p+=k,v-=k,m+=k,r.length-=k;break}r.mode=c;break;case 17:for(;y<14;){if(0===g)break e;g--,b+=f[p++]<>>=5,y-=5,r.ndist=1+(31&b),b>>>=5,y-=5,r.ncode=4+(15&b),b>>>=4,y-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=u;break}r.have=0,r.mode=18;case 18:for(;r.have>>=3,y-=3}for(;r.have<19;)r.lens[L[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,N={bits:r.lenbits},I=s(0,r.lens,0,19,r.lencode,0,r.work,N),r.lenbits=N.bits,I){e.msg="invalid code lengths set",r.mode=u;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,j=65535&D,!((A=D>>>24)<=y);){if(0===g)break e;g--,b+=f[p++]<>>=A,y-=A,r.lens[r.have++]=j;else{if(16===j){for(F=A+2;y>>=A,y-=A,0===r.have){e.msg="invalid bit length repeat",r.mode=u;break}_=r.lens[r.have-1],k=3+(3&b),b>>>=2,y-=2}else if(17===j){for(F=A+3;y>>=A)),b>>>=3,y-=3}else{for(F=A+7;y>>=A)),b>>>=7,y-=7}if(r.have+k>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=u;break}for(;k--;)r.lens[r.have++]=_}}if(r.mode===u)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=u;break}if(r.lenbits=9,N={bits:r.lenbits},I=s(1,r.lens,0,r.nlen,r.lencode,0,r.work,N),r.lenbits=N.bits,I){e.msg="invalid literal/lengths set",r.mode=u;break}if(r.distbits=6,r.distcode=r.distdyn,N={bits:r.distbits},I=s(2,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,N),r.distbits=N.bits,I){e.msg="invalid distances set",r.mode=u;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(g>=6&&v>=258){e.next_out=m,e.avail_out=v,e.next_in=p,e.avail_in=g,r.hold=b,r.bits=y,a(e,C),m=e.next_out,h=e.output,v=e.avail_out,p=e.next_in,f=e.input,g=e.avail_in,b=r.hold,y=r.bits,r.mode===c&&(r.back=-1);break}for(r.back=0;T=(D=r.lencode[b&(1<>>16&255,j=65535&D,!((A=D>>>24)<=y);){if(0===g)break e;g--,b+=f[p++]<>P)])>>>16&255,j=65535&D,!(P+(A=D>>>24)<=y);){if(0===g)break e;g--,b+=f[p++]<>>=P,y-=P,r.back+=P}if(b>>>=A,y-=A,r.back+=A,r.length=j,0===T){r.mode=26;break}if(32&T){r.back=-1,r.mode=c;break}if(64&T){e.msg="invalid literal/length code",r.mode=u;break}r.extra=15&T,r.mode=22;case 22:if(r.extra){for(F=r.extra;y>>=r.extra,y-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;T=(D=r.distcode[b&(1<>>16&255,j=65535&D,!((A=D>>>24)<=y);){if(0===g)break e;g--,b+=f[p++]<>P)])>>>16&255,j=65535&D,!(P+(A=D>>>24)<=y);){if(0===g)break e;g--,b+=f[p++]<>>=P,y-=P,r.back+=P}if(b>>>=A,y-=A,r.back+=A,64&T){e.msg="invalid distance code",r.mode=u;break}r.offset=j,r.extra=15&T,r.mode=24;case 24:if(r.extra){for(F=r.extra;y>>=r.extra,y-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=u;break}r.mode=25;case 25:if(0===v)break e;if(k=C-v,r.offset>k){if((k=r.offset-k)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=u;break}k>r.wnext?(k-=r.wnext,E=r.wsize-k):E=r.wnext-k,k>r.length&&(k=r.length),O=r.window}else O=h,E=m-r.offset,k=r.length;k>v&&(k=v),v-=k,r.length-=k;do{h[m++]=O[E++]}while(--k);0===r.length&&(r.mode=21);break;case 26:if(0===v)break e;h[m++]=r.length,v--,r.mode=21;break;case 27:if(r.wrap){for(;y<32;){if(0===g)break e;g--,b|=f[p++]<{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Path=void 0;const n=r(4892),o=r(4723),i=r(8871),a=r(5570);class s extends o.Shape{constructor(e){super(e),this.dataArray=[],this.pathLength=0,this._readDataAttribute(),this.on("dataChange.konva",(function(){this._readDataAttribute()}))}_readDataAttribute(){this.dataArray=s.parsePathData(this.data()),this.pathLength=s.getPathLength(this.dataArray)}_sceneFunc(e){const t=this.dataArray;e.beginPath();let r=!1;for(let p=0;pa?i:a,f=i>a?1:i/a,h=i>a?a/i:1;e.translate(n,o),e.rotate(c),e.scale(f,h),e.arc(0,0,d,s,s+l,1-u),e.scale(1/f,1/h),e.rotate(-c),e.translate(-n,-o);break;case"z":r=!0,e.closePath()}}r||this.hasFill()?e.fillStrokeShape(this):e.strokeShape(this)}getSelfRect(){let e=[];this.dataArray.forEach((function(t){if("A"===t.command){const r=t.points[4],n=t.points[5],o=t.points[4]+n;let i=Math.PI/180;if(Math.abs(r-o)o;n-=i){const r=s.getPointOnEllipticalArc(t.points[0],t.points[1],t.points[2],t.points[3],n,0);e.push(r.x,r.y)}else for(let n=r+i;nt[n].pathLength;)e-=t[n].pathLength,++n;if(n===o)return r=t[n-1].points.slice(-2),{x:r[0],y:r[1]};if(e<.01)return r=t[n].points.slice(0,2),{x:r[0],y:r[1]};const i=t[n],l=i.points;switch(i.command){case"L":return s.getPointOnLine(e,i.start.x,i.start.y,l[0],l[1]);case"C":return s.getPointOnCubicBezier((0,a.t2length)(e,s.getPathLength(t),(e=>(0,a.getCubicArcLength)([i.start.x,l[0],l[2],l[4]],[i.start.y,l[1],l[3],l[5]],e))),i.start.x,i.start.y,l[0],l[1],l[2],l[3],l[4],l[5]);case"Q":return s.getPointOnQuadraticBezier((0,a.t2length)(e,s.getPathLength(t),(e=>(0,a.getQuadraticArcLength)([i.start.x,l[0],l[2]],[i.start.y,l[1],l[3]],e))),i.start.x,i.start.y,l[0],l[1],l[2],l[3]);case"A":var c=l[0],u=l[1],d=l[2],f=l[3],h=l[4],p=l[5],m=l[6];return h+=p*e/i.pathLength,s.getPointOnEllipticalArc(c,u,d,f,h,m)}return null}static getPointOnLine(e,t,r,n,o,i,a){i=null!=i?i:t,a=null!=a?a:r;const s=this.getLineLength(t,r,n,o);if(s<1e-10)return{x:t,y:r};if(n===t)return{x:i,y:a+(o>r?e:-e)};const l=(o-r)/(n-t),c=Math.sqrt(e*e/(1+l*l))*(n0&&!isNaN(r[0]);){let e="",n=[];const o=s,a=l;var d,f,h,p,m,g,v,b,y,w;switch(t){case"l":s+=r.shift(),l+=r.shift(),e="L",n.push(s,l);break;case"L":s=r.shift(),l=r.shift(),n.push(s,l);break;case"m":var x=r.shift(),S=r.shift();if(s+=x,l+=S,e="M",i.length>2&&"z"===i[i.length-1].command)for(let e=i.length-2;e>=0;e--)if("M"===i[e].command){s=i[e].points[0]+x,l=i[e].points[1]+S;break}n.push(s,l),t="l";break;case"M":s=r.shift(),l=r.shift(),e="M",n.push(s,l),t="L";break;case"h":s+=r.shift(),e="L",n.push(s,l);break;case"H":s=r.shift(),e="L",n.push(s,l);break;case"v":l+=r.shift(),e="L",n.push(s,l);break;case"V":l=r.shift(),e="L",n.push(s,l);break;case"C":n.push(r.shift(),r.shift(),r.shift(),r.shift()),s=r.shift(),l=r.shift(),n.push(s,l);break;case"c":n.push(s+r.shift(),l+r.shift(),s+r.shift(),l+r.shift()),s+=r.shift(),l+=r.shift(),e="C",n.push(s,l);break;case"S":f=s,h=l,"C"===(d=i[i.length-1]).command&&(f=s+(s-d.points[2]),h=l+(l-d.points[3])),n.push(f,h,r.shift(),r.shift()),s=r.shift(),l=r.shift(),e="C",n.push(s,l);break;case"s":f=s,h=l,"C"===(d=i[i.length-1]).command&&(f=s+(s-d.points[2]),h=l+(l-d.points[3])),n.push(f,h,s+r.shift(),l+r.shift()),s+=r.shift(),l+=r.shift(),e="C",n.push(s,l);break;case"Q":n.push(r.shift(),r.shift()),s=r.shift(),l=r.shift(),n.push(s,l);break;case"q":n.push(s+r.shift(),l+r.shift()),s+=r.shift(),l+=r.shift(),e="Q",n.push(s,l);break;case"T":f=s,h=l,"Q"===(d=i[i.length-1]).command&&(f=s+(s-d.points[0]),h=l+(l-d.points[1])),s=r.shift(),l=r.shift(),e="Q",n.push(f,h,s,l);break;case"t":f=s,h=l,"Q"===(d=i[i.length-1]).command&&(f=s+(s-d.points[0]),h=l+(l-d.points[1])),s+=r.shift(),l+=r.shift(),e="Q",n.push(f,h,s,l);break;case"A":p=r.shift(),m=r.shift(),g=r.shift(),v=r.shift(),b=r.shift(),y=s,w=l,s=r.shift(),l=r.shift(),e="A",n=this.convertEndpointToCenterParameterization(y,w,s,l,v,b,p,m,g);break;case"a":p=r.shift(),m=r.shift(),g=r.shift(),v=r.shift(),b=r.shift(),y=s,w=l,s+=r.shift(),l+=r.shift(),e="A",n=this.convertEndpointToCenterParameterization(y,w,s,l,v,b,p,m,g)}i.push({command:e||t,points:n,start:{x:o,y:a},pathLength:this.calcLength(o,a,e||t,n)})}"z"!==t&&"Z"!==t||i.push({command:"z",points:[],start:void 0,pathLength:0})}return i}static calcLength(e,t,r,n){let o,i,l,c;const u=s;switch(r){case"L":return u.getLineLength(e,t,n[0],n[1]);case"C":return(0,a.getCubicArcLength)([e,n[0],n[2],n[4]],[t,n[1],n[3],n[5]],1);case"Q":return(0,a.getQuadraticArcLength)([e,n[0],n[2]],[t,n[1],n[3]],1);case"A":o=0;var d=n[4],f=n[5],h=n[4]+f,p=Math.PI/180;if(Math.abs(d-h)h;c-=p)l=u.getPointOnEllipticalArc(n[0],n[1],n[2],n[3],c,0),o+=u.getLineLength(i.x,i.y,l.x,l.y),i=l;else for(c=d+p;c1&&(a*=Math.sqrt(f),s*=Math.sqrt(f));let h=Math.sqrt((a*a*(s*s)-a*a*(d*d)-s*s*(u*u))/(a*a*(d*d)+s*s*(u*u)));o===i&&(h*=-1),isNaN(h)&&(h=0);const p=h*a*d/s,m=h*-s*u/a,g=(e+r)/2+Math.cos(c)*p-Math.sin(c)*m,v=(t+n)/2+Math.sin(c)*p+Math.cos(c)*m,b=function(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1])},y=function(e,t){return(e[0]*t[0]+e[1]*t[1])/(b(e)*b(t))},w=function(e,t){return(e[0]*t[1]=1&&(k=0),0===i&&k>0&&(k-=2*Math.PI),1===i&&k<0&&(k+=2*Math.PI),[g,v,a,s,x,k,c,i]}}t.Path=s,s.prototype.className="Path",s.prototype._attrsAffectingSize=["data"],(0,i._registerNode)(s),n.Factory.addGetterSetter(s,"data")},1601:e=>{"use strict";e.exports=function(e){return e[1]}},1665:(e,t,r)=>{"use strict";r.d(t,{A:()=>s});var n=r(1601),o=r.n(n),i=r(6314),a=r.n(i)()(o());a.push([e.id,".PdfjsAnnotationExtension_painter_wrapper{position:absolute;text-align:initial;top:0;inset:0;overflow:hidden;line-height:1;text-size-adjust:none;forced-color-adjust:none;transform-origin:0 0;z-index:1}.PdfjsAnnotationExtension_selector_hover .PdfjsAnnotationExtension_painter_wrapper{cursor:pointer !important}.PdfjsAnnotationExtension_is_painting .PdfjsAnnotationExtension_painter_wrapper{z-index:999}.PdfjsAnnotationExtension_painting_type_1 .textLayer:not(.free) span,.PdfjsAnnotationExtension_painting_type_2 .textLayer:not(.free) span,.PdfjsAnnotationExtension_painting_type_3 .textLayer:not(.free) span{cursor:var(--editorHighlight-editing-cursor)}.PdfjsAnnotationExtension_painting_type_4 .PdfjsAnnotationExtension_painter_wrapper,.PdfjsAnnotationExtension_painting_type_5 .PdfjsAnnotationExtension_painter_wrapper,.PdfjsAnnotationExtension_painting_type_6 .PdfjsAnnotationExtension_painter_wrapper,.PdfjsAnnotationExtension_painting_type_11 .PdfjsAnnotationExtension_painter_wrapper,.PdfjsAnnotationExtension_painting_type_12 .PdfjsAnnotationExtension_painter_wrapper,.PdfjsAnnotationExtension_painting_type_13 .PdfjsAnnotationExtension_painter_wrapper{cursor:crosshair}.PdfjsAnnotationExtension_painting_type_7 .PdfjsAnnotationExtension_painter_wrapper{cursor:var(--editorInk-editing-cursor)}.PdfjsAnnotationExtension_painting_type_8 .PdfjsAnnotationExtension_painter_wrapper{cursor:var(--editorFreeHighlight-editing-cursor)}.PdfjsAnnotationExtension_painting_type_9 .PdfjsAnnotationExtension_painter_wrapper,.PdfjsAnnotationExtension_painting_type_10 .PdfjsAnnotationExtension_painter_wrapper{cursor:var(--PdfjsAnnotationExtension-image-cursor)}",""]);const s=a},1668:(e,t,r)=>{"use strict";var n={};(0,r(9805).assign)(n,r(3303),r(7083),r(9681)),e.exports=n},1958:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Text=void 0,t.stringToArray=c;const n=r(4060),o=r(4892),i=r(4723),a=r(8871),s=r(5483),l=r(8871);function c(e){return[...e].reduce(((e,t,r,n)=>{if(/\p{Emoji}/u.test(t)){const o=n[r+1];o&&/\p{Emoji_Modifier}|\u200D/u.test(o)?(e.push(t+o),n[r+1]=""):e.push(t)}else/\p{Regional_Indicator}{2}/u.test(t+(n[r+1]||""))?e.push(t+n[r+1]):r>0&&/\p{Mn}|\p{Me}|\p{Mc}/u.test(t)?e[e.length-1]+=t:t&&e.push(t);return e}),[])}const u="auto",d="inherit",f="justify",h="left",p="middle",m="normal",g=" ",v="none",b=["direction","fontFamily","fontSize","fontStyle","fontVariant","padding","align","verticalAlign","lineHeight","text","width","height","wrap","ellipsis","letterSpacing"],y=b.length;let w;function x(){return w||(w=n.Util.createCanvasElement().getContext("2d"),w)}class S extends i.Shape{constructor(e){super(function(e){return(e=e||{}).fillLinearGradientColorStops||e.fillRadialGradientColorStops||e.fillPatternImage||(e.fill=e.fill||"black"),e}(e)),this._partialTextX=0,this._partialTextY=0;for(let e=0;e1&&(C+=s)}}_hitFunc(e){const t=this.getWidth(),r=this.getHeight();e.beginPath(),e.rect(0,0,t,r),e.closePath(),e.fillStrokeShape(this)}setText(e){const t=n.Util._isString(e)?e:null==e?"":e+"";return this._setAttr("text",t),this}getWidth(){return this.attrs.width===u||void 0===this.attrs.width?this.getTextWidth()+2*this.padding():this.attrs.width}getHeight(){return this.attrs.height===u||void 0===this.attrs.height?this.fontSize()*this.textArr.length*this.lineHeight()+2*this.padding():this.attrs.height}getTextWidth(){return this.textWidth}getTextHeight(){return n.Util.warn("text.getTextHeight() method is deprecated. Use text.height() - for full height and text.fontSize() - for one line height."),this.textHeight}measureSize(e){var t,r,n,o,i,a,s,l,c,u,d;let f,h=x(),p=this.fontSize();h.save(),h.font=this._getContextFont(),f=h.measureText(e),h.restore();const m=p/100;return{actualBoundingBoxAscent:null!==(t=f.actualBoundingBoxAscent)&&void 0!==t?t:71.58203125*m,actualBoundingBoxDescent:null!==(r=f.actualBoundingBoxDescent)&&void 0!==r?r:0,actualBoundingBoxLeft:null!==(n=f.actualBoundingBoxLeft)&&void 0!==n?n:-7.421875*m,actualBoundingBoxRight:null!==(o=f.actualBoundingBoxRight)&&void 0!==o?o:75.732421875*m,alphabeticBaseline:null!==(i=f.alphabeticBaseline)&&void 0!==i?i:0,emHeightAscent:null!==(a=f.emHeightAscent)&&void 0!==a?a:100*m,emHeightDescent:null!==(s=f.emHeightDescent)&&void 0!==s?s:-20*m,fontBoundingBoxAscent:null!==(l=f.fontBoundingBoxAscent)&&void 0!==l?l:91*m,fontBoundingBoxDescent:null!==(c=f.fontBoundingBoxDescent)&&void 0!==c?c:21*m,hangingBaseline:null!==(u=f.hangingBaseline)&&void 0!==u?u:72.80000305175781*m,ideographicBaseline:null!==(d=f.ideographicBaseline)&&void 0!==d?d:-21*m,width:f.width,height:p}}_getContextFont(){return this.fontStyle()+g+this.fontVariant()+g+(this.fontSize()+"px ")+this.fontFamily().split(",").map((e=>{const t=(e=e.trim()).indexOf(" ")>=0,r=e.indexOf('"')>=0||e.indexOf("'")>=0;return t&&!r&&(e=`"${e}"`),e})).join(", ")}_addTextLine(e){this.align()===f&&(e=e.trim());const t=this._getTextWidth(e);return this.textArr.push({text:e,width:t,lastInParagraph:!1})}_getTextWidth(e){const t=this.letterSpacing(),r=e.length;return x().measureText(e).width+t*r}_setTextData(){let e=this.text().split("\n"),t=+this.fontSize(),r=0,n=this.lineHeight()*t,o=this.attrs.width,i=this.attrs.height,a=o!==u&&void 0!==o,s=i!==u&&void 0!==i,l=this.padding(),d=o-2*l,f=i-2*l,h=0,p=this.wrap(),m="char"!==p&&p!==v,b=this.ellipsis();this.textArr=[],x().font=this._getContextFont();const y=b?this._getTextWidth("…"):0;for(let t=0,o=e.length;td)for(;i.length>0;){let e=0,t=c(i).length,o="",a=0;for(;e>>1,l=c(i).slice(0,r+1).join(""),u=this._getTextWidth(l);(b&&s&&h+n>f?u+y:u)<=d?(e=r+1,o=l,a=u):t=r}if(!o)break;if(m){const t=c(i),r=c(o),n=t[r.length];let s;if((n===g||"-"===n)&&a<=d)s=r.length;else{const e=r.lastIndexOf(g),t=r.lastIndexOf("-");s=Math.max(e,t)+1}s>0&&(e=s,o=t.slice(0,e).join(""),a=this._getTextWidth(o))}if(o=o.trimRight(),this._addTextLine(o),r=Math.max(r,a),h+=n,this._shouldHandleEllipsis(h)){this._tryToAddEllipsisToLastLine();break}if(i=c(i).slice(e).join("").trimLeft(),i.length>0&&(l=this._getTextWidth(i),l<=d)){this._addTextLine(i),h+=n,r=Math.max(r,l);break}}else this._addTextLine(i),h+=n,r=Math.max(r,l),this._shouldHandleEllipsis(h)&&tf)break}this.textHeight=t,this.textWidth=r}_shouldHandleEllipsis(e){const t=+this.fontSize(),r=this.lineHeight()*t,n=this.attrs.height,o=n!==u&&void 0!==n,i=n-2*this.padding();return!(this.wrap()!==v)||o&&e+r>i}_tryToAddEllipsisToLastLine(){const e=this.attrs.width,t=e!==u&&void 0!==e,r=e-2*this.padding(),n=this.ellipsis(),o=this.textArr[this.textArr.length-1];o&&n&&(t&&(this._getTextWidth(o.text+"…"){"use strict";var n=r(9805),o=!0,i=!0;try{String.fromCharCode.apply(null,[0])}catch(e){o=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(e){i=!1}for(var a=new n.Buf8(256),s=0;s<256;s++)a[s]=s>=252?6:s>=248?5:s>=240?4:s>=224?3:s>=192?2:1;function l(e,t){if(t<65534&&(e.subarray&&i||!e.subarray&&o))return String.fromCharCode.apply(null,n.shrinkBuf(e,t));for(var r="",a=0;a>>6,t[a++]=128|63&r):r<65536?(t[a++]=224|r>>>12,t[a++]=128|r>>>6&63,t[a++]=128|63&r):(t[a++]=240|r>>>18,t[a++]=128|r>>>12&63,t[a++]=128|r>>>6&63,t[a++]=128|63&r);return t},t.buf2binstring=function(e){return l(e,e.length)},t.binstring2buf=function(e){for(var t=new n.Buf8(e.length),r=0,o=t.length;r4)c[n++]=65533,r+=i-1;else{for(o&=2===i?31:3===i?15:7;i>1&&r1?c[n++]=65533:o<65536?c[n++]=o:(o-=65536,c[n++]=55296|o>>10&1023,c[n++]=56320|1023&o)}return l(c,n)},t.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;r>=0&&128==(192&e[r]);)r--;return r<0||0===r?t:r+a[e[r]]>t?r:t}},1998:(e,t,r)=>{"use strict";var n=r(9805),o=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],i=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],a=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],s=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(e,t,r,l,c,u,d,f){var h,p,m,g,v,b,y,w,x,S=f.bits,C=0,k=0,E=0,O=0,A=0,T=0,j=0,P=0,M=0,R=0,_=null,I=0,N=new n.Buf16(16),F=new n.Buf16(16),D=null,B=0;for(C=0;C<=15;C++)N[C]=0;for(k=0;k=1&&0===N[O];O--);if(A>O&&(A=O),0===O)return c[u++]=20971520,c[u++]=20971520,f.bits=1,0;for(E=1;E0&&(0===e||1!==O))return-1;for(F[1]=0,C=1;C<15;C++)F[C+1]=F[C]+N[C];for(k=0;k852||2===e&&M>592)return 1;for(;;){y=C-j,d[k]b?(w=D[B+d[k]],x=_[I+d[k]]):(w=96,x=0),h=1<>j)+(p-=h)]=y<<24|w<<16|x}while(0!==p);for(h=1<>=1;if(0!==h?(R&=h-1,R+=h):R=0,k++,0===--N[C]){if(C===O)break;C=t[r+d[k]]}if(C>A&&(R&g)!==m){for(0===j&&(j=A),v+=E,P=1<<(T=C-j);T+j852||2===e&&M>592)return 1;c[m=R&g]=A<<24|T<<16|v-u}}return 0!==R&&(c[v+R]=C-j<<24|64<<16),f.bits=A,0}},2512:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Sepia=void 0,t.Sepia=function(e){const t=e.data,r=t.length;for(let e=0;e{"use strict";var n=r(6540),o=r(9982);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=1;r