diff --git a/package.json b/package.json index f3ddef2d9..fabd50e13 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "clamscan": "^2.0.1", "cookies": "^0.8.0", "dgram": "^1.0.1", - "docx": "^9.5.0", + "docx": "^9.5.1", "dompurify": "^3.2.4", "dotenv": "^8.2.0", "eslint-config-next": "13", @@ -50,8 +50,7 @@ "hamburger-react": "^2.4.1", "jsonwebtoken": "^9.0.0", "jszip": "^3.10.1", - "lodash": "^4.17.23", - "mammoth": "^1.11.0", + "lodash": "^4.17.21", "memory-cache": "^0.2.0", "moment": "^2.29.1", "music-metadata": "^11.2.3", @@ -60,7 +59,6 @@ "next-share": "^0.18.1", "pdf-lib": "^1.17.1", "pdfjs-dist": "4.2.67", - "pptxgenjs": "^4.0.0", "prettysize": "^2.0.0", "random-words": "^2.0.0", "react": "^18.2.0", @@ -74,13 +72,12 @@ "react-loading-skeleton": "^3.3.1", "react-markdown": "6.0.3", "react-parallax": "^3.3.0", - "react-pdftotext": "^1.2.0", + "react-pdftotext": "^1.3.4", "react-select": "^5.7.0", "react-toastify": "^9.1.1", "react-tooltip": "^5.27.0", - "tesseract.js": "^5.0.5", + "tesseract.js": "^7.0.0", "useragent": "^2.3.0", - "xlsx": "^0.18.5", "zxcvbn": "^4.4.2" }, "devDependencies": { diff --git a/src/components/file-compressor/ConverterSection.tsx b/src/components/file-compressor/ConverterSection.tsx index 57e7c3401..c7c44505d 100644 --- a/src/components/file-compressor/ConverterSection.tsx +++ b/src/components/file-compressor/ConverterSection.tsx @@ -1,4 +1,6 @@ -import { createRef, useCallback, useState } from 'react'; +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { createRef, useCallback, useState, useMemo } from 'react'; +import { useRouter } from 'next/navigation'; import { Errors, MAX_FILE_SIZE, extensionName, compressionTypes, fileMimeTypes } from './types'; import InitialState from './states/InitialState'; @@ -17,30 +19,26 @@ interface ConverterSectionProps { pathname: string; } -interface ConverterStatesProps { - state: ConverterStates; -} - type ConverterStates = 'initialState' | 'selectedFileState' | 'compressingState' | 'downloadFileState' | 'errorState'; export const ConverterSection = ({ textContent, converterText, errorContent, pathname }: ConverterSectionProps) => { + const router = useRouter(); const [files, setFiles] = useState(null); const [converterStates, setConverterStates] = useState('initialState'); const [error, setError] = useState(null); const [isDragging, setIsDragging] = useState(false); const uploadFileRef = createRef(); - const borderStyle = isDragging - ? 'border border-dashed border-primary' - : 'border-4 border-dashed border-primary/8 bg-primary/2'; - const pathnameSegments = pathname.split('-'); - const fileType = pathnameSegments[1]; + const fileType = useMemo(() => { + const segments = pathname.split('-'); + return segments[1] || 'pdf'; + }, [pathname]); - const urlToFileExtensionsMap = { - jpg: ['jpg'], + const urlToFileExtensionsMap: Record = { + jpg: ['jpg', 'jpeg'], png: ['png'], pdf: ['pdf'], - mov: ['mov'], + mov: ['mov', 'mp4'], zip: ['zip'], word: ['doc', 'docx'], excel: ['xls', 'xlsx'], @@ -48,16 +46,27 @@ export const ConverterSection = ({ textContent, converterText, errorContent, pat }; const allowedExtensionsForPath = urlToFileExtensionsMap[fileType] || []; - const allowedUploadedFilesExtension = fileMimeTypes[fileType]; - const formattedConverterText = formatText(converterText, { - pathFrom: extensionName[fileType], - }); + const formattedConverterText = useMemo( + () => + formatText(converterText, { + pathFrom: extensionName[fileType], + }), + [converterText, fileType], + ); + + const formattedErrorText = useMemo( + () => + formatText(errorContent, { + pathFrom: extensionName[fileType], + }), + [errorContent, fileType], + ); - const formattedErrorText = formatText(errorContent, { - pathFrom: extensionName[fileType], - }); + const borderStyle = isDragging + ? 'border border-dashed border-primary' + : 'border-4 border-dashed border-primary/8 bg-primary/2'; const resetViewToInitialState = useCallback(() => { setError(null); @@ -65,140 +74,132 @@ export const ConverterSection = ({ textContent, converterText, errorContent, pat setConverterStates('initialState'); setIsDragging(false); - setTimeout(() => { - if (uploadFileRef.current) { - uploadFileRef.current.value = ''; - } - }, 100); - }, []); + if (uploadFileRef.current) { + uploadFileRef.current.value = ''; + } + }, [uploadFileRef]); - const handleDroppedFiles = (files: FileList) => { - const file = files.length > 0 ? files.item(files.length - 1) : null; + const validateAndSetFiles = (incomingFiles: FileList) => { + const file = incomingFiles.length > 0 ? incomingFiles.item(0) : null; if (!file) return; - const fileExtension = file.name.split('.').pop()?.toLowerCase() || ''; + const filesSize = Array.from(incomingFiles).reduce((acc, f) => acc + f.size, 0); + if (filesSize > MAX_FILE_SIZE) { + setError('bigFile'); + setConverterStates('errorState'); + return; + } + const fileExtension = file.name.split('.').pop()?.toLowerCase() || ''; if (!allowedExtensionsForPath.includes(fileExtension)) { setError('unsupportedFormat'); setConverterStates('errorState'); return; } - setFiles(files); + setFiles(incomingFiles); setConverterStates('selectedFileState'); }; + const handleDroppedFiles = (droppedFiles: FileList) => { + validateAndSetFiles(droppedFiles); + }; + const handleOpenFileExplorer = () => { - if (uploadFileRef.current) { - uploadFileRef.current.click(); - } + uploadFileRef.current?.click(); }; const handleFileInput = () => { - const fileInput = uploadFileRef.current; - if (fileInput?.files && fileInput.files.length > 0) { - const file = fileInput.files[0]; - const filesSize = Array.from(fileInput.files).reduce((accumulator, file) => accumulator + file.size, 0); - - if (filesSize > MAX_FILE_SIZE) { - setError('bigFile'); - setConverterStates('errorState'); - return; - } - - const fileExtension = file.name.split('.').pop()?.toLowerCase() || ''; - - if (!allowedExtensionsForPath.includes(fileExtension)) { - setError('unsupportedFormat'); - setConverterStates('errorState'); - return; - } - - setFiles(fileInput.files); - setConverterStates('selectedFileState'); + if (uploadFileRef.current?.files) { + validateAndSetFiles(uploadFileRef.current.files); } }; const handleCompression = async () => { - if (!fileType || !files) return; + if (!fileType || !files || !files[0]) return; setConverterStates('compressingState'); try { - let compressionType: 'image' | 'document' | 'video' | 'archive' | undefined; const fileExtension = files[0].name.split('.').pop()?.toLowerCase() || ''; + let compressionType: 'image' | 'document' | 'video' | 'archive' | undefined; - if (compressionTypes.imageCompression.includes(fileExtension)) { - compressionType = 'image'; - } else if (compressionTypes.documentCompression.includes(fileExtension)) { - compressionType = 'document'; - } else if (compressionTypes.videoCompression.includes(fileExtension)) { - compressionType = 'video'; - } else if (compressionTypes.archiveCompression.includes(fileExtension)) { - compressionType = 'archive'; - } else { - throw new Error('Unsupported file type for compression'); + const typeEntries = Object.entries(compressionTypes) as [string, string[]][]; + for (const [key, extensions] of typeEntries) { + if (extensions.includes(fileExtension)) { + compressionType = key.replace('Compression', '') as any; + break; + } } + if (!compressionType) throw new Error('Unsupported file type'); + await fileCompressorService.handleFileCompression(files[0], compressionType, fileExtension); setConverterStates('downloadFileState'); } catch (err) { - const error = err as Error; - const filteredError = error.message.includes('File too large') ? 'bigFile' : 'internalError'; - setError(filteredError); + const errorMsg = err as Error; + const filteredError = errorMsg.message.includes('File too large') ? 'bigFile' : 'internalError'; + setError(filteredError as Errors); setConverterStates('errorState'); } }; - const State = (views: ConverterStatesProps) => { - const state = { - initialState: ( - - ), - selectedFileState: files && ( - - ), - compressingState: ( -
-
-
-
+ const renderState = () => { + switch (converterStates) { + case 'initialState': + return ( + + ); + case 'selectedFileState': + return ( + files && ( + + ) + ); + case 'compressingState': + return ( +
+
+
+
+
+
- +

{formattedConverterText.compressing}

-

{formattedConverterText.compressing}

-
- ), - downloadFileState: ( - - ), - errorState: ( - - ), - }; - - return state[views.state]; + ); + case 'downloadFileState': + return ( + + ); + case 'errorState': + return ( + + ); + default: + return null; + } }; return ( @@ -217,14 +218,12 @@ export const ConverterSection = ({ textContent, converterText, errorContent, pat
window.history.back()} + className="absolute left-0 hidden cursor-pointer flex-row items-center justify-end rounded-sm-6 border-[1.5px] border-primary px-4 py-2 pt-2.5 hover:bg-white/50 lg:flex" + onClick={() => router.back()} >

Back

- - {/* Título centrado */}

{formattedConverterText.title}

@@ -235,9 +234,9 @@ export const ConverterSection = ({ textContent, converterText, errorContent, pat
- + {renderState()}
diff --git a/src/services/file-compressor.service.ts b/src/services/file-compressor.service.ts index 81822aeb7..b7b40ef79 100644 --- a/src/services/file-compressor.service.ts +++ b/src/services/file-compressor.service.ts @@ -1,457 +1,268 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { FFmpeg } from '@ffmpeg/ffmpeg'; +import { fetchFile, toBlobURL } from '@ffmpeg/util'; import imageCompression from 'browser-image-compression'; -import { PDFDocument } from 'pdf-lib'; import JSZip from 'jszip'; -import * as XLSX from 'xlsx'; -import mammoth from 'mammoth'; - -function downloadBlob(url: string, fileName: string) { - const link = document.createElement('a'); - link.href = url; - link.download = fileName; - document.body.appendChild(link); - link.click(); - document.body.removeChild(link); -} - -type CompressionType = 'image' | 'document' | 'video' | 'archive'; - -/** - * Compresses an image file using browser-image-compression library - */ -const compressImage = async (file: File): Promise => { - const options = { - maxSizeMB: 1, - maxWidthOrHeight: 1920, - useWebWorker: true, - }; - - try { - const compressedFile = await imageCompression(file, options); - return compressedFile; - } catch (error) { - throw new Error('Image compression failed'); - } -}; - -/** - * Compresses a PDF document using pdf-lib library - */ -const compressPDF = async (file: File): Promise => { - try { - const arrayBuffer = await file.arrayBuffer(); - const pdfDoc = await PDFDocument.load(arrayBuffer); - - // For PDF compression, we'll optimize the document - // This is a basic implementation - you might want to add more optimization - const compressedPdfBytes = await pdfDoc.save({ - useObjectStreams: true, - addDefaultPage: false, - }); +import { PDFDocument } from 'pdf-lib'; +import * as pdfjs from 'pdfjs-dist'; + +pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`; + +class FileCompressorService { + private ffmpeg: FFmpeg | null = null; + + /** + * Main handler that detects the file type and applies the corresponding compression logic. + * @param {File} file - The source file to be compressed. + * @param {'image' | 'document' | 'video' | 'archive'} type - The category of the file. + * @param {string} extension - The specific file extension. + * @returns {Promise} - Initiates a file download once processing is finished. + */ + async handleFileCompression( + file: File, + type: 'image' | 'document' | 'video' | 'archive', + extension: string, + ): Promise { + let compressedBlob: Blob; - return new Blob([compressedPdfBytes], { type: 'application/pdf' }); - } catch (error) { - throw new Error('PDF compression failed'); - } -}; - -/** - * Compresses Excel files using xlsx library - */ -const compressExcelFile = async (file: File): Promise => { - try { - const arrayBuffer = await file.arrayBuffer(); - const workbook = XLSX.read(arrayBuffer, { type: 'array' }); - - // Optimize the workbook by removing unnecessary data - workbook.SheetNames.forEach((sheetName) => { - const worksheet = workbook.Sheets[sheetName]; - - // Remove empty rows and columns - const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1'); - - // Clean up the worksheet by removing empty cells - Object.keys(worksheet).forEach((key) => { - if (key.startsWith('!')) return; // Skip special keys - const cell = worksheet[key]; - if (!cell || !cell.v || cell.v === '') { - delete worksheet[key]; + switch (type) { + case 'image': + compressedBlob = await this.compressImage(file); + break; + case 'video': + compressedBlob = await this.compressVideo(file); + break; + case 'archive': + compressedBlob = await this.compressArchive(file); + break; + case 'document': + if (['docx', 'pptx', 'xlsx'].includes(extension)) { + compressedBlob = await this.compressOfficeDocument(file); + } else { + compressedBlob = await this.compressDocument(file, extension); } - }); - }); - - // Generate optimized Excel file - const optimizedBuffer = XLSX.write(workbook, { - type: 'array', - bookType: 'xlsx', - compression: true, - }); + break; + default: + compressedBlob = file; + } - return new Blob([optimizedBuffer], { - type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - }); - } catch (error) { - throw new Error('Excel compression failed'); - } -}; - -/** - * Compresses Word documents using mammoth library - */ -const compressWordFile = async (file: File): Promise => { - try { - const arrayBuffer = await file.arrayBuffer(); - - // Extract text content from Word document - const result = await mammoth.extractRawText({ arrayBuffer }); - - // Create a simplified document structure - const simplifiedContent = result.value - .split('\n') - .map((line) => line.trim()) - .filter((line) => line.length > 0) - .join('\n'); - - // For now, we'll create a simple text file as compressed version - // In a real implementation, you might want to recreate a Word document - return new Blob([simplifiedContent], { type: 'text/plain' }); - } catch (error) { - throw new Error('Word compression failed'); + this.downloadFile(compressedBlob, file.name); } -}; -/** - * Compresses PowerPoint files using enhanced techniques - */ -const compressPowerPointFile = async (file: File, fileExtension: string): Promise => { - try { - const arrayBuffer = await file.arrayBuffer(); - - if (fileExtension.toLowerCase() === 'pptx') { - // PPTX files are ZIP-based, use enhanced ZIP compression - const zip = new JSZip(); - const zipContent = await zip.loadAsync(arrayBuffer); - - // Create a new ZIP with maximum compression - const newZip = new JSZip(); - - // Process each file in the PowerPoint document - for (const [filename, zipEntry] of Object.entries(zipContent.files)) { - if (!zipEntry.dir) { - const content = await zipEntry.async('uint8array'); - - // Files that should not be compressed (essential metadata) - const skipCompression = [ - '[Content_Types].xml', - '_rels/.rels', - 'docProps/app.xml', - 'docProps/core.xml', - 'ppt/presProps.xml', - 'ppt/viewProps.xml', - ]; - - // Files that can be aggressively compressed - const aggressiveCompression = [ - 'ppt/slides/slide', - 'ppt/slideLayouts/slideLayout', - 'ppt/slideMasters/slideMaster', - 'ppt/theme/theme', - 'ppt/tableStyles.xml', - 'ppt/tags/tag', - ]; - - if (skipCompression.some((skip) => filename.includes(skip))) { - // Store essential files without compression - newZip.file(filename, content, { compression: 'STORE' }); - } else if (aggressiveCompression.some((agg) => filename.includes(agg))) { - // Apply maximum compression to content files - newZip.file(filename, content, { - compression: 'DEFLATE', - compressionOptions: { level: 9 }, - }); - } else { - // Apply standard compression to other files - newZip.file(filename, content, { - compression: 'DEFLATE', - compressionOptions: { level: 6 }, - }); - } - } else { - newZip.folder(filename); - } - } - - // Generate compressed PowerPoint file - const compressedPpt = await newZip.generateAsync({ - type: 'blob', - compression: 'DEFLATE', - compressionOptions: { level: 9 }, + /** + * Processes PDF files using a hybrid approach: first attempts structural optimization, + * then applies rasterization only if it results in a smaller file size. + * @param {File} file - The original PDF file. + * @param {string} extension - The file extension string. + * @returns {Promise} - The smallest version of the PDF found during processing. + */ + private async compressDocument(file: File, extension: string): Promise { + if (extension !== 'pdf') return file; + + try { + const arrayBuffer = await file.arrayBuffer(); + + const structuralPdf = await PDFDocument.load(arrayBuffer); + const structuralBytes = await structuralPdf.save({ + useObjectStreams: true, + addDefaultPage: false, }); + const structuralBlob = new Blob([structuralBytes as any], { type: 'application/pdf' }); + + const loadingTask = pdfjs.getDocument({ data: arrayBuffer }); + const pdf = await loadingTask.promise; + const outPdf = await PDFDocument.create(); + + for (let i = 1; i <= pdf.numPages; i++) { + const page = await pdf.getPage(i); + const scale = 2.0; + const viewport = page.getViewport({ scale }); + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + + if (!context) continue; + canvas.height = viewport.height; + canvas.width = viewport.width; + + await page.render({ canvasContext: context, viewport }).promise; + + const imageData = canvas.toDataURL('image/jpeg', 0.55); + const imageBytes = await fetch(imageData).then((res) => res.arrayBuffer()); + const pdfImage = await outPdf.embedJpg(imageBytes); + + const newPage = outPdf.addPage([viewport.width, viewport.height]); + newPage.drawImage(pdfImage, { + x: 0, + y: 0, + width: viewport.width, + height: viewport.height, + }); + } - return compressedPpt; - } else if (fileExtension.toLowerCase() === 'ppt') { - // For legacy PPT files, use binary optimization - const uint8Array = new Uint8Array(arrayBuffer); + const rasterBytes = await outPdf.save({ useObjectStreams: true }); + const rasterBlob = new Blob([rasterBytes as any], { type: 'application/pdf' }); - // PPT files are OLE compound documents - // We'll try to optimize by removing unnecessary data + const candidates = [ + { blob: file, size: file.size }, + { blob: structuralBlob, size: structuralBlob.size }, + { blob: rasterBlob, size: rasterBlob.size }, + ]; - // Find the end of the actual content - let contentEnd = uint8Array.length; + candidates.sort((a, b) => a.size - b.size); - // Look for common PPT file endings and remove trailing data - const pptEndings = [ - // Common PPT file endings - [0x00, 0x00, 0x00, 0x00], // Null padding - [0xff, 0xff, 0xff, 0xff], // Filled padding - [0x20, 0x20, 0x20, 0x20], // Space padding - ]; + return candidates[0].blob; + } catch (error) { + console.error('Error during PDF compression:', error); + return file; + } + } - // Remove trailing zeros and padding - while (contentEnd > 0) { - const lastByte = uint8Array[contentEnd - 1]; - if (lastByte === 0x00 || lastByte === 0xff || lastByte === 0x20) { - contentEnd--; - } else { - break; - } - } + /** + * Compresses image files using the browser-image-compression utility. + * @param {File} file - The image file. + * @returns {Promise} - The compressed image as a blob. + */ + private async compressImage(file: File): Promise { + const options = { + maxSizeMB: 1, + maxWidthOrHeight: 1920, + useWebWorker: true, + initialQuality: 0.6, + }; + return await imageCompression(file, options); + } - // Also try to find the actual end of PPT content - // Look for PPT file structure markers - const pptMarkers = [ - [0xd0, 0xcf, 0x11, 0xe0], // OLE header - [0x50, 0x50, 0x54], // PPT marker - [0x50, 0x6f, 0x77, 0x65, 0x72, 0x50, 0x6f, 0x69, 0x6e, 0x74], // "PowerPoint" - ]; + /** + * Uses FFmpeg WebAssembly to transcode and reduce video file size without logs. + * @param {File} file - The video file. + * @returns {Promise} - The transcoded MP4 blob. + */ + private async compressVideo(file: File): Promise { + if (!this.ffmpeg) this.ffmpeg = new FFmpeg(); + + if (!this.ffmpeg.loaded) { + const baseURL = 'https://unpkg.com/@ffmpeg/core@0.12.6/dist/umd'; + await this.ffmpeg.load({ + coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, 'text/javascript'), + wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`, 'application/wasm'), + }); + } - // Find the last occurrence of PPT content - for (let i = contentEnd - 1; i >= 0; i--) { - let found = false; - for (const marker of pptMarkers) { - if (i + marker.length <= contentEnd) { - let match = true; - for (let j = 0; j < marker.length; j++) { - if (uint8Array[i + j] !== marker[j]) { - match = false; - break; - } - } - if (match) { - contentEnd = i + marker.length; - found = true; - break; - } - } - } - if (found) break; - } + const inputName = `input_${Date.now()}_${file.name.replaceAll(' ', '_')}`; + const outputName = `output_${Date.now()}.mp4`; + + await this.ffmpeg.writeFile(inputName, await fetchFile(file)); + + await this.ffmpeg.exec([ + '-i', + inputName, + '-vcodec', + 'libx264', + '-crf', + '32', + '-preset', + 'ultrafast', + '-movflags', + 'faststart', + '-acodec', + 'aac', + outputName, + ]); + + const data = await this.ffmpeg.readFile(outputName); + + await this.ffmpeg.deleteFile(inputName); + await this.ffmpeg.deleteFile(outputName); + + return new Blob([data as any], { type: 'video/mp4' }); + } - // Create optimized PPT file - const optimizedArray = uint8Array.slice(0, contentEnd); - - // If the optimization didn't reduce size significantly, try alternative approach - if (optimizedArray.length > uint8Array.length * 0.95) { - // Try to compress the entire file using a different approach - // Create a simple compression by removing redundant data - const compressed = new Uint8Array(Math.ceil(optimizedArray.length * 0.8)); - let compressedIndex = 0; - - for (let i = 0; i < optimizedArray.length; i++) { - // Simple run-length encoding for repeated bytes - let count = 1; - while (i + 1 < optimizedArray.length && optimizedArray[i] === optimizedArray[i + 1] && count < 255) { - count++; - i++; - } - - if (count > 3) { - // Use run-length encoding - compressed[compressedIndex++] = 0xff; // Marker for run-length - compressed[compressedIndex++] = count; - compressed[compressedIndex++] = optimizedArray[i]; - } else { - // Copy bytes directly - for (let j = 0; j < count; j++) { - compressed[compressedIndex++] = optimizedArray[i - j]; + /** + * Deeply compresses Office documents by extracting internal media files, + * optimizing them using canvas-based compression, and rebuilding the archive. + * @param {File} file - The Office document (docx, pptx, xlsx). + * @returns {Promise} - The optimized document with compressed internal assets. + */ + private async compressOfficeDocument(file: File): Promise { + try { + const zip = new JSZip(); + const content = await zip.loadAsync(file); + const imageOptions = { + maxSizeMB: 0.2, + maxWidthOrHeight: 1024, + useWebWorker: true, + initialQuality: 0.5, + fileType: 'image/jpeg' as any, + }; + + const filePromises: Promise[] = []; + + content.forEach((relativePath, zipEntry) => { + const isImage = /\.(jpg|jpeg|png|tif|tiff)$/i.test(relativePath); + + if (isImage) { + const promise = (async () => { + const imageBuffer = await zipEntry.async('blob'); + const originalName = relativePath.split('/').pop() || 'image.jpg'; + const imageFile = new File([imageBuffer], originalName, { type: 'image/jpeg' }); + + try { + const compressedBlob = await imageCompression(imageFile, imageOptions); + content.file(relativePath, compressedBlob); + } catch (e) { + // } - } + })(); + filePromises.push(promise); } + }); - // Trim the compressed array to actual size - const finalCompressed = compressed.slice(0, compressedIndex); - return new Blob([finalCompressed], { type: file.type }); - } - - return new Blob([optimizedArray], { type: file.type }); - } - - // Fallback: return original file - return file; - } catch (error) { - throw new Error(`PowerPoint compression failed: ${error.message}`); - } -}; - -/** - * Compresses Office documents (DOC, PPT, XLS) by optimizing their internal structure - * Note: This is a basic implementation that works with the ZIP-based Office formats - */ -const compressOfficeDocument = async (file: File, fileExtension: string): Promise => { - try { - const arrayBuffer = await file.arrayBuffer(); - - // Handle Excel files with xlsx library - if (['xls', 'xlsx'].includes(fileExtension.toLowerCase())) { - return await compressExcelFile(file); - } + await Promise.all(filePromises); - // Handle Word files with mammoth library - if (['doc', 'docx'].includes(fileExtension.toLowerCase())) { - return await compressWordFile(file); - } + const finalBlob = await content.generateAsync({ + type: 'blob', + compression: 'DEFLATE', + compressionOptions: { level: 9 }, + }); - // Handle PowerPoint files with enhanced compression - if (['ppt', 'pptx'].includes(fileExtension.toLowerCase())) { - return await compressPowerPointFile(file, fileExtension); + return finalBlob.size < file.size ? finalBlob : file; + } catch (error) { + return file; } - - // Fallback: return original file - return file; - } catch (error) { - throw new Error(`${fileExtension.toUpperCase()} compression failed`); } -}; -/** - * Compresses a ZIP file using JSZip library - */ -const compressZIP = async (file: File): Promise => { - try { + /** + * Compresses archive files by repackaging them with max DEFLATE level. + * @param {File} file - The ZIP file. + * @returns {Promise} - The newly compressed archive blob. + */ + private async compressArchive(file: File): Promise { const zip = new JSZip(); - const zipContent = await zip.loadAsync(file); - - // Create a new ZIP with compression - const newZip = new JSZip(); - - // Process each file in the ZIP - for (const [filename, zipEntry] of Object.entries(zipContent.files)) { - if (!zipEntry.dir) { - const content = await zipEntry.async('uint8array'); - newZip.file(filename, content, { compression: 'DEFLATE', compressionOptions: { level: 9 } }); - } else { - newZip.folder(filename); - } - } - - // Generate compressed ZIP - const compressedZip = await newZip.generateAsync({ + const content = await zip.loadAsync(file); + return await content.generateAsync({ type: 'blob', compression: 'DEFLATE', compressionOptions: { level: 9 }, }); - - return compressedZip; - } catch (error) { - throw new Error('ZIP compression failed'); } -}; - -/** - * Compresses a video file using Web APIs - * Note: Video compression is limited in browsers, this is a basic implementation - */ -const compressVideo = async (file: File): Promise => { - return new Promise((resolve, reject) => { - const video = document.createElement('video'); - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - - video.onloadedmetadata = () => { - // Set canvas size to a smaller resolution for compression - const scale = 0.5; // Reduce quality by 50% - canvas.width = video.videoWidth * scale; - canvas.height = video.videoHeight * scale; - }; - - video.oncanplay = () => { - if (ctx) { - ctx.drawImage(video, 0, 0, canvas.width, canvas.height); - canvas.toBlob( - (blob) => { - if (blob) { - resolve(blob); - } else { - reject(new Error('Video compression failed')); - } - }, - 'video/webm', - 0.7, - ); // Reduce quality to 70% - } - }; - video.onerror = () => { - reject(new Error('Video compression failed')); - }; - - video.src = URL.createObjectURL(file); - }); -}; - -/** - * Handles file compression based on the file type using client-side libraries - * @param file - The file to compress - * @param compressionType - The type of compression to apply (image, document, video, archive) - * @param fileExtension - The original file extension - */ -const handleFileCompression = async (file: File, compressionType: CompressionType, fileExtension: string) => { - if (!file) { - throw new Error('No file provided'); - } - - try { - let compressedBlob: Blob; - - switch (compressionType) { - case 'image': - compressedBlob = await compressImage(file); - break; - case 'document': - if (fileExtension.toLowerCase() === 'pdf') { - compressedBlob = await compressPDF(file); - } else if (['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx'].includes(fileExtension.toLowerCase())) { - compressedBlob = await compressOfficeDocument(file, fileExtension); - } else { - // For other document types, we'll return the original file - compressedBlob = file; - } - break; - case 'video': - compressedBlob = await compressVideo(file); - break; - case 'archive': - if (fileExtension.toLowerCase() === 'zip') { - compressedBlob = await compressZIP(file); - } else { - compressedBlob = file; - } - break; - default: - throw new Error('Unsupported compression type'); - } - - const url = window.URL.createObjectURL(compressedBlob); - const fileName = `${file.name.split('.')[0]}-compressed.${fileExtension}`; - - downloadBlob(url, fileName); - } catch (err) { - const error = err as Error; - throw new Error(error.message); + /** + * Utility to trigger a file download in the browser. + * @param {Blob} blob - The file data. + * @param {string} originalName - The name to use for the downloaded file. + */ + private downloadFile(blob: Blob, originalName: string): void { + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + const nameWithoutExt = originalName.split('.').slice(0, -1).join('.'); + link.download = `compressed_${nameWithoutExt}.${originalName.split('.').pop()}`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); } -}; - -const fileCompressorService = { - handleFileCompression, -}; +} +const fileCompressorService = new FileCompressorService(); export default fileCompressorService; diff --git a/yarn.lock b/yarn.lock index 19f7326d9..223d255e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1288,6 +1288,11 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@borewit/text-codec@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@borewit/text-codec/-/text-codec-0.2.1.tgz#5d171538907a8cb395fdc2eb5e8f7947d96c7f2f" + integrity sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw== + "@cemalgnlts/mailjs@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@cemalgnlts/mailjs/-/mailjs-3.0.1.tgz#0113e03973a847eca3d4064dc87baf033e5dab85" @@ -2089,6 +2094,78 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@napi-rs/canvas-android-arm64@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.91.tgz#01506c229c65421ca4b6d6bd8e46241280f8b336" + integrity sha512-SLLzXXgSnfct4zy/BVAfweZQkYkPJsNsJ2e5DOE8DFEHC6PufyUrwb12yqeu2So2IOIDpWJJaDAxKY/xpy6MYQ== + +"@napi-rs/canvas-darwin-arm64@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.91.tgz#f134f60321ae617a62ce7a32553b0ad018ac13f9" + integrity sha512-bzdbCjIjw3iRuVFL+uxdSoMra/l09ydGNX9gsBxO/zg+5nlppscIpj6gg+nL6VNG85zwUarDleIrUJ+FWHvmuA== + +"@napi-rs/canvas-darwin-x64@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.91.tgz#298d3e4384db98020df80ac33a64ef72c993e992" + integrity sha512-q3qpkpw0IsG9fAS/dmcGIhCVoNxj8ojbexZKWwz3HwxlEWsLncEQRl4arnxrwbpLc2nTNTyj4WwDn7QR5NDAaA== + +"@napi-rs/canvas-linux-arm-gnueabihf@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.91.tgz#049f9e3876c048bb81572c03cc0aac0468372582" + integrity sha512-Io3g8wJZVhK8G+Fpg1363BE90pIPqg+ZbeehYNxPWDSzbgwU3xV0l8r/JBzODwC7XHi1RpFEk+xyUTMa2POj6w== + +"@napi-rs/canvas-linux-arm64-gnu@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.91.tgz#084478649e2ae594ee47fbc3eb51363f71780b6a" + integrity sha512-HBnto+0rxx1bQSl8bCWA9PyBKtlk2z/AI32r3cu4kcNO+M/5SD4b0v1MWBWZyqMQyxFjWgy3ECyDjDKMC6tY1A== + +"@napi-rs/canvas-linux-arm64-musl@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.91.tgz#8e7fef0fdaeeb873b9dd51f11000ba5529b9cfa1" + integrity sha512-/eJtVe2Xw9A86I4kwXpxxoNagdGclu12/NSMsfoL8q05QmeRCbfjhg1PJS7ENAuAvaiUiALGrbVfeY1KU1gztQ== + +"@napi-rs/canvas-linux-riscv64-gnu@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.91.tgz#6bd786c6d27186e2e3112a6113de5a8f1a38cb52" + integrity sha512-floNK9wQuRWevUhhXRcuis7h0zirdytVxPgkonWO+kQlbvxV7gEUHGUFQyq4n55UHYFwgck1SAfJ1HuXv/+ppQ== + +"@napi-rs/canvas-linux-x64-gnu@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.91.tgz#0af23d7f1387e5942b0d00f627a503230cfa249e" + integrity sha512-c3YDqBdf7KETuZy2AxsHFMsBBX1dWT43yFfWUq+j1IELdgesWtxf/6N7csi3VPf6VA3PmnT9EhMyb+M1wfGtqw== + +"@napi-rs/canvas-linux-x64-musl@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.91.tgz#05eb731dfe0732f54972ace0e39e71c73f246def" + integrity sha512-RpZ3RPIwgEcNBHSHSX98adm+4VP8SMT5FN6250s5jQbWpX/XNUX5aLMfAVJS/YnDjS1QlsCgQxFOPU0aCCWgag== + +"@napi-rs/canvas-win32-arm64-msvc@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.91.tgz#216f67ba1d00ca1e6073d538f2ec81dc05420993" + integrity sha512-gF8MBp4X134AgVurxqlCdDA2qO0WaDdi9o6Sd5rWRVXRhWhYQ6wkdEzXNLIrmmros0Tsp2J0hQzx4ej/9O8trQ== + +"@napi-rs/canvas-win32-x64-msvc@0.1.91": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.91.tgz#aa88cf1d37f23ad403a2065824785350a8884f91" + integrity sha512-++gtW9EV/neKI8TshD8WFxzBYALSPag2kFRahIJV+LYsyt5kBn21b1dBhEUDHf7O+wiZmuFCeUa7QKGHnYRZBA== + +"@napi-rs/canvas@^0.1.65": + version "0.1.91" + resolved "https://registry.yarnpkg.com/@napi-rs/canvas/-/canvas-0.1.91.tgz#379a7b762cc20d74c0bbb04c0e8fac712c66350b" + integrity sha512-eeIe1GoB74P1B0Nkw6pV8BCQ3hfCfvyYr4BntzlCsnFXzVJiPMDnLeIx3gVB0xQMblHYnjK/0nCLvirEhOjr5g== + optionalDependencies: + "@napi-rs/canvas-android-arm64" "0.1.91" + "@napi-rs/canvas-darwin-arm64" "0.1.91" + "@napi-rs/canvas-darwin-x64" "0.1.91" + "@napi-rs/canvas-linux-arm-gnueabihf" "0.1.91" + "@napi-rs/canvas-linux-arm64-gnu" "0.1.91" + "@napi-rs/canvas-linux-arm64-musl" "0.1.91" + "@napi-rs/canvas-linux-riscv64-gnu" "0.1.91" + "@napi-rs/canvas-linux-x64-gnu" "0.1.91" + "@napi-rs/canvas-linux-x64-musl" "0.1.91" + "@napi-rs/canvas-win32-arm64-msvc" "0.1.91" + "@napi-rs/canvas-win32-x64-msvc" "0.1.91" + "@next/env@16.1.5": version "16.1.5" resolved "https://registry.yarnpkg.com/@next/env/-/env-16.1.5.tgz#83740cf3a0e617848c53c154b41cf141f0f536ca" @@ -2366,14 +2443,13 @@ dependencies: tslib "^2.8.0" -"@tokenizer/inflate@^0.2.6": - version "0.2.7" - resolved "https://registry.yarnpkg.com/@tokenizer/inflate/-/inflate-0.2.7.tgz#32dd9dfc9abe457c89b3d9b760fc0690c85a103b" - integrity sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg== +"@tokenizer/inflate@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@tokenizer/inflate/-/inflate-0.4.1.tgz#fa6cdb8366151b3cc8426bf9755c1ea03a2fba08" + integrity sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA== dependencies: - debug "^4.4.0" - fflate "^0.8.2" - token-types "^6.0.0" + debug "^4.4.3" + token-types "^6.1.1" "@tokenizer/token@^0.3.0": version "0.3.0" @@ -2468,19 +2544,12 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-15.14.9.tgz#bc43c990c3c9be7281868bbc7b8fdd6e2b57adfa" integrity sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A== -"@types/node@^22.7.5": - version "22.15.21" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.21.tgz#196ef14fe20d87f7caf1e7b39832767f9a995b77" - integrity sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ== +"@types/node@^24.0.1": + version "24.10.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.9.tgz#1aeb5142e4a92957489cac12b07f9c7fe26057d0" + integrity sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw== dependencies: - undici-types "~6.21.0" - -"@types/node@^22.8.1": - version "22.15.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.32.tgz#c301cc2275b535a5e54bb81d516b1d2e9afe06e5" - integrity sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA== - dependencies: - undici-types "~6.21.0" + undici-types "~7.16.0" "@types/offscreencanvas@^2019.7.3": version "2019.7.3" @@ -2705,11 +2774,6 @@ "@typescript-eslint/types" "6.19.1" eslint-visitor-keys "^3.4.1" -"@xmldom/xmldom@^0.8.6": - version "0.8.10" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" - integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -2725,11 +2789,6 @@ acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -adler-32@~1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2" - integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A== - agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2878,13 +2937,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -argparse@~1.0.3: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - aria-query@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" @@ -3144,7 +3196,7 @@ base64-arraybuffer@^1.0.2: resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc" integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ== -base64-js@^1.3.1, base64-js@^1.5.1: +base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -3171,7 +3223,7 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bl@^4.1.0: +bl@^4.0.3, bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -3195,11 +3247,6 @@ bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bluebird@~3.4.0: - version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== - bmp-js@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" @@ -3382,6 +3429,14 @@ canvas@^2.11.2: nan "^2.17.0" simple-get "^3.0.3" +canvas@^3.0.0-rc2: + version "3.2.1" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-3.2.1.tgz#8f0390569f36b94bffba9c0e7aed6948875aec7b" + integrity sha512-ej1sPFR5+0YWtaVp6S1N1FVz69TQCqmrkGeRvQxZeAB1nAIcjNTHVwrZtYtWFFBmQsF40/uDLehsW5KuYC99mg== + dependencies: + node-addon-api "^7.0.0" + prebuild-install "^7.1.3" + canvg@^3.0.11: version "3.0.11" resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.11.tgz#4b4290a6c7fa36871fac2b14e432eff33b33cf2b" @@ -3402,17 +3457,11 @@ caseless@~0.12.0: integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== centra@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/centra/-/centra-2.6.0.tgz#79117998ee6908642258db263871381aa5d1204a" - integrity sha512-dgh+YleemrT8u85QL11Z6tYhegAs3MMxsaWAq/oXeAmYJ7VxL3SI9TZtnfaEvNDMAPolj25FXIb3S+HCI4wQaQ== - -cfb@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44" - integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA== + version "2.7.0" + resolved "https://registry.yarnpkg.com/centra/-/centra-2.7.0.tgz#4c8312a58436e8a718302011561db7e6a2b0ec18" + integrity sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg== dependencies: - adler-32 "~1.3.0" - crc-32 "~1.2.0" + follow-redirects "^1.15.6" chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" @@ -3481,6 +3530,11 @@ chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chownr@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-3.0.0.tgz#9855e64ecd240a9cc4267ce8a4aa5d24a1da15e4" @@ -3574,11 +3628,6 @@ clsx@^2.0.0, clsx@^2.1.0: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== -codepage@~1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab" - integrity sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -3706,9 +3755,9 @@ core-js-compat@^3.25.1: browserslist "^4.21.5" core-js@^3.6.0, core-js@^3.8.3: - version "3.36.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.36.0.tgz#e752fa0b0b462a0787d56e9d73f80b0f7c0dde68" - integrity sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw== + version "3.48.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.48.0.tgz#1f813220a47bbf0e667e3885c36cd6f0593bf14d" + integrity sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ== core-util-is@1.0.2: version "1.0.2" @@ -3742,11 +3791,6 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" -crc-32@~1.2.0, crc-32@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" @@ -3888,7 +3932,7 @@ dayjs@^1.10.4: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== -debug@4, debug@^4.4.0, debug@^4.4.1: +debug@4: version "4.4.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== @@ -3923,6 +3967,13 @@ debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3 dependencies: ms "2.1.2" +debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -3935,6 +3986,13 @@ decompress-response@^4.2.0: dependencies: mimic-response "^2.0.0" +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -4123,11 +4181,6 @@ diff-sequences@^29.4.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.2.tgz#711fe6bd8a5869fe2539cee4a5152425ff671fda" integrity sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw== -dingbat-to-unicode@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz#5091dd673241453e6b5865e26e5a4452cdef5c83" - integrity sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w== - dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -4154,12 +4207,12 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -docx@^9.5.0: - version "9.5.0" - resolved "https://registry.yarnpkg.com/docx/-/docx-9.5.0.tgz#586990c4ecf1c7e83290529997b33f2c029bbe68" - integrity sha512-WZggg9vVujFcTyyzfIVBBIxlCk51QvhLWl87wtI2zuBdz8C8C0mpRhEVwA2DZd7dXyY0AVejcEVDT9vn7Xm9FA== +docx@^9.5.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/docx/-/docx-9.5.1.tgz#325c9c45dccf052e5780515d6068e80fdee81960" + integrity sha512-ABDI7JEirFD2+bHhOBlsGZxaG1UgZb2M/QMKhLSDGgVNhxDesTCDcP+qoDnDGjZ4EOXTRfUjUgwHVuZ6VSTfWQ== dependencies: - "@types/node" "^22.7.5" + "@types/node" "^24.0.1" hash.js "^1.1.7" jszip "^3.10.1" nanoid "^5.1.3" @@ -4223,13 +4276,6 @@ dotenv@^8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== -duck@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/duck/-/duck-0.1.12.tgz#de7adf758421230b6d7aee799ce42670586b9efa" - integrity sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg== - dependencies: - underscore "^1.13.1" - dunder-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" @@ -4296,6 +4342,13 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +end-of-stream@^1.4.1: + version "1.4.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" + integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== + dependencies: + once "^1.4.0" + enhanced-resolve@^4.0.0: version "4.5.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" @@ -4786,6 +4839,11 @@ exifr@^7.1.3: resolved "https://registry.yarnpkg.com/exifr/-/exifr-7.1.3.tgz#f6218012c36dbb7d843222011b27f065fddbab6f" integrity sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^29.0.0: version "29.4.2" resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.2.tgz#2ae34eb88de797c64a1541ad0f1e2ea8a7a7b492" @@ -4888,7 +4946,7 @@ fdir@^6.5.0: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== -fflate@^0.8.1, fflate@^0.8.2: +fflate@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea" integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A== @@ -4907,14 +4965,14 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-type@^20.5.0: - version "20.5.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-20.5.0.tgz#616e90564e6ffabab22ad9763e28efcc5c95aee0" - integrity sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg== +file-type@^21.3.0: + version "21.3.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-21.3.0.tgz#03334acfe59cc22f72fce2a1327c5a1190f0b7de" + integrity sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA== dependencies: - "@tokenizer/inflate" "^0.2.6" - strtok3 "^10.2.0" - token-types "^6.0.0" + "@tokenizer/inflate" "^0.4.1" + strtok3 "^10.3.4" + token-types "^6.1.1" uint8array-extras "^1.4.0" filing-cabinet@^3.0.1: @@ -4983,7 +5041,7 @@ flatten@^1.0.2: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== -follow-redirects@^1.15.11: +follow-redirects@^1.15.11, follow-redirects@^1.15.6: version "1.15.11" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== @@ -5035,11 +5093,6 @@ form-data@^4.0.4, form-data@^4.0.5, form-data@~2.3.2: hasown "^2.0.2" mime-types "^2.1.12" -frac@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" - integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA== - fraction.js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" @@ -5050,6 +5103,11 @@ fromentries@^1.2.0: resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -5222,6 +5280,11 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -5481,20 +5544,15 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -https@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https/-/https-1.0.0.tgz#3c37c7ae1a8eeb966904a2ad1e975a194b7ed3a4" - integrity sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg== - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== idb-keyval@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" - integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + version "6.2.2" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.2.tgz#b0171b5f73944854a3291a5cdba8e12768c4854a" + integrity sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg== ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" @@ -5511,13 +5569,6 @@ ignore@^5.1.8, ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -image-size@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.2.1.tgz#ee118aedfe666db1a6ee12bed5821cde3740276d" - integrity sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw== - dependencies: - queue "6.0.2" - immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -5694,11 +5745,6 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== -is-electron@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.2.tgz#3778902a2044d76de98036f5dc58089ac4d80bb9" - integrity sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -6173,7 +6219,7 @@ jsprim@^2.0.2: object.assign "^4.1.4" object.values "^1.1.6" -jszip@^3.10.1, jszip@^3.7.1: +jszip@^3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== @@ -6314,7 +6360,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.23: +lodash@^4.17.20, lodash@^4.17.21: version "4.17.23" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== @@ -6344,15 +6390,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lop@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/lop/-/lop-0.4.2.tgz#c9c2f958a39b9da1c2f36ca9ad66891a9fe84640" - integrity sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw== - dependencies: - duck "^0.1.12" - option "~0.2.1" - underscore "^1.13.1" - lru-cache@4.1.x: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -6432,22 +6469,6 @@ make-event-props@^1.6.0: resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.6.2.tgz#c8e0e48eb28b9b808730de38359f6341de7ec5a2" integrity sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA== -mammoth@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/mammoth/-/mammoth-1.11.0.tgz#f6c68624eaffcf56728a792fcccd3495d688bac5" - integrity sha512-BcEqqY/BOwIcI1iR5tqyVlqc3KIaMRa4egSoK83YAVrBf6+yqdAAbtUcFDCWX8Zef8/fgNZ6rl4VUv+vVX8ddQ== - dependencies: - "@xmldom/xmldom" "^0.8.6" - argparse "~1.0.3" - base64-js "^1.5.1" - bluebird "~3.4.0" - dingbat-to-unicode "^1.0.1" - jszip "^3.7.1" - lop "^0.4.2" - path-is-absolute "^1.0.0" - underscore "^1.13.1" - xmlbuilder "^10.0.0" - math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" @@ -6523,7 +6544,7 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -merge-refs@^1.2.1: +merge-refs@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/merge-refs/-/merge-refs-1.3.0.tgz#65d7f8c5058917b9d1fc204ae4b9a727614d0119" integrity sha512-nqXPXbso+1dcKDpPCXvwZyJILz+vSLqGGOnDrYHQYE+B8n9JTCekVLC65AfCpR4ggVyA/45Y0iR9LDyS2iI+zA== @@ -6576,6 +6597,11 @@ mimic-response@^2.0.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -6602,7 +6628,7 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.8: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -6624,6 +6650,11 @@ minizlib@^3.1.0: dependencies: minipass "^7.1.2" +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + module-definition@^3.3.1: version "3.4.0" resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-3.4.0.tgz#953a3861f65df5e43e80487df98bb35b70614c2b" @@ -6664,18 +6695,20 @@ ms@^2.1.1, ms@^2.1.3: integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== music-metadata@^11.2.3: - version "11.2.3" - resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-11.2.3.tgz#2881d8c6fc07cc549eabc9b5138091297cd5da95" - integrity sha512-ReVxFoO12kaRiaNmqxkAdytul1Ntl2ersdIyw/CqWPysvOFpUrr19s8uOHEA4xjK69ETmpP71KezXWEE7r5Myg== + version "11.12.0" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-11.12.0.tgz#ac4dde2a0196c9b793d28abd4cadcd2142b3530e" + integrity sha512-9ChYnmVmyHvFxR2g0MWFSHmJfbssRy07457G4gbb4LA9WYvyZea/8EMbqvg5dcv4oXNCNL01m8HXtymLlhhkYg== dependencies: + "@borewit/text-codec" "^0.2.1" "@tokenizer/token" "^0.3.0" content-type "^1.0.5" - debug "^4.4.1" - file-type "^20.5.0" + debug "^4.4.3" + file-type "^21.3.0" media-typer "^1.1.0" - strtok3 "^10.2.2" - token-types "^6.0.0" - uint8array-extras "^1.4.0" + strtok3 "^10.3.4" + token-types "^6.1.2" + uint8array-extras "^1.5.0" + win-guid "^0.2.1" mz@^2.7.0: version "2.7.0" @@ -6697,9 +6730,14 @@ nanoid@^3.3.6, nanoid@^3.3.7: integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== nanoid@^5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.1.5.tgz#f7597f9d9054eb4da9548cdd53ca70f1790e87de" - integrity sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw== + version "5.1.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.1.6.tgz#30363f664797e7d40429f6c16946d6bd7a3f26c9" + integrity sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg== + +napi-build-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-2.0.0.tgz#13c22c0187fcfccce1461844136372a47ddc027e" + integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA== natural-compare@^1.4.0: version "1.4.0" @@ -6755,6 +6793,18 @@ next@16.1.5: "@next/swc-win32-x64-msvc" "16.1.5" sharp "^0.34.4" +node-abi@^3.3.0: + version "3.87.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.87.0.tgz#423e28fea5c2f195fddd98acded9938c001ae6dd" + integrity sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ== + dependencies: + semver "^7.3.5" + +node-addon-api@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" + integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== + node-fetch@^2.6.7, node-fetch@^2.6.9: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -6969,11 +7019,6 @@ opencollective-postinstall@^2.0.3: resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== -option@~0.2.1: - version "0.2.4" - resolved "https://registry.yarnpkg.com/option/-/option-0.2.4.tgz#fd475cdf98dcabb3cb397a3ba5284feb45edbfe4" - integrity sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A== - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -7136,19 +7181,7 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -path2d-polyfill@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/path2d-polyfill/-/path2d-polyfill-2.1.1.tgz#6098b7bf2fc24c306c6377bcd558b17ba437ea27" - integrity sha512-4Rka5lN+rY/p0CdD8+E+BFv51lFaFvJOrlOhyQ+zjzyQrzyh3ozmxd1vVGGDdIbUFSBtIZLSnspxTgPT0iJhvA== - dependencies: - path2d "0.1.1" - -path2d@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path2d/-/path2d-0.1.1.tgz#d3c3886cd2252fb2a7830c27ea7bb9a862d937ea" - integrity sha512-/+S03c8AGsDYKKBtRDqieTJv2GlkMb0bWjnqOgtF6MkjdUQ9a8ARAtxWf9NgKLGm2+WQr6+/tqJdU8HNGsIDoA== - -path2d@^0.2.0: +path2d@^0.2.0, path2d@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/path2d/-/path2d-0.2.2.tgz#cc85d61ed7827e7863a2ee36713d4b5315a3d85d" integrity sha512-+vnG6S4dYcYxZd+CZxzXCNKdELYZSKfohrk98yajCo1PtRoDgCTrrwOvK1GT0UoAdVszagDVllQc0U1vaX4NUQ== @@ -7163,14 +7196,6 @@ pdf-lib@^1.17.1: pako "^1.0.11" tslib "^1.11.1" -pdfjs-dist@3.11.174: - version "3.11.174" - resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz#5ff47b80f2d58c8dd0d74f615e7c6a7e7e704c4b" - integrity sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA== - optionalDependencies: - canvas "^2.11.2" - path2d-polyfill "^2.0.1" - pdfjs-dist@4.2.67: version "4.2.67" resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-4.2.67.tgz#dd2a65a4b00d95cd4bc2c1f6a27c5e9eb31d512a" @@ -7179,10 +7204,20 @@ pdfjs-dist@4.2.67: canvas "^2.11.2" path2d "^0.2.0" -peek-readable@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-7.0.0.tgz#c6e4e78ec76f7005e5f6b51ffc93fdb91ede6512" - integrity sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ== +pdfjs-dist@4.8.69: + version "4.8.69" + resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-4.8.69.tgz#61ea5d66863d49b40e5eacbd4070341175bdda2e" + integrity sha512-IHZsA4T7YElCKNNXtiLgqScw4zPd3pG9do8UrznC757gMd7UPeHSL2qwNNMJo4r79fl8oj1Xx+1nh2YkzdMpLQ== + optionalDependencies: + canvas "^3.0.0-rc2" + path2d "^0.2.1" + +pdfjs-dist@^4.6.82: + version "4.10.38" + resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-4.10.38.tgz#3ee698003790dc266cc8b55c0e662ccb9ae18f53" + integrity sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ== + optionalDependencies: + "@napi-rs/canvas" "^0.1.65" pend@~1.2.0: version "1.2.0" @@ -7312,15 +7347,23 @@ postcss@^8.1.7, postcss@^8.4.23: picocolors "^1.0.1" source-map-js "^1.2.0" -pptxgenjs@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pptxgenjs/-/pptxgenjs-4.0.0.tgz#a74fdc2b1cf1eb1a59d284268e28227082e6e236" - integrity sha512-iXpmNbivy64cxb4W05nDpUBkhoa73qCmvDZ2CTXYhvvX7LkJKAs6wWEEWlm3OSVJdaZtjY+AAmWgcmwNH8fSkA== +prebuild-install@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec" + integrity sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug== dependencies: - "@types/node" "^22.8.1" - https "^1.0.0" - image-size "^1.1.1" - jszip "^3.10.1" + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^2.0.0" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" precinct@^7.0.0: version "7.1.0" @@ -7512,13 +7555,6 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -queue@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" - integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== - dependencies: - inherits "~2.0.3" - raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" @@ -7676,27 +7712,27 @@ react-parallax@^3.3.0: resolved "https://registry.yarnpkg.com/react-parallax/-/react-parallax-3.5.1.tgz#73071679371b7738e21ffac8daa0bc3cb7e5174d" integrity sha512-p5zPsPsqELlIOGaPS01O0IRx8R2bxcBAtrdF/RHf9nIxxk5hijbM2y89tk4rJQBcNH6ESSLe7J2NV4/ms7FLFw== -react-pdf@^7.7.1: - version "7.7.3" - resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-7.7.3.tgz#eea8104cd165dfec7ae0fa54259cfe7de12b5e81" - integrity sha512-a2VfDl8hiGjugpqezBTUzJHYLNB7IS7a2t7GD52xMI9xHg8LdVaTMsnM9ZlNmKadnStT/tvX5IfV0yLn+JvYmw== +react-pdf@^9.1.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-9.2.1.tgz#35294da1232d310243ffe5e54f39281e6c98d8d4" + integrity sha512-AJt0lAIkItWEZRA5d/mO+Om4nPCuTiQ0saA+qItO967DTjmGjnhmF+Bi2tL286mOTfBlF5CyLzJ35KTMaDoH+A== dependencies: clsx "^2.0.0" dequal "^2.0.3" make-cancellable-promise "^1.3.1" make-event-props "^1.6.0" - merge-refs "^1.2.1" - pdfjs-dist "3.11.174" - prop-types "^15.6.2" + merge-refs "^1.3.0" + pdfjs-dist "4.8.69" tiny-invariant "^1.0.0" warning "^4.0.0" -react-pdftotext@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/react-pdftotext/-/react-pdftotext-1.2.0.tgz#9428076f47f15345b757bbdcdf0c51fac8f20e99" - integrity sha512-RI8PMH+SPWEiMIU7tpvY0EdDNOqUTieyy6R1F7OvsDsVHHhJP6bToCSEVYMLeloXPJVeAhL5xCVUEqHaEr/OwQ== +react-pdftotext@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/react-pdftotext/-/react-pdftotext-1.3.4.tgz#513b706c33f577aebb726bd035fab2463bb574ab" + integrity sha512-WRM41aCYueQn8CikwG9OxAur6DqSn5sE5j1yu3oG+WORTCfJLDH/m0dR9RnggxnKB51tfMeRFyOZuKJQZLtYBQ== dependencies: - react-pdf "^7.7.1" + pdfjs-dist "^4.6.82" + react-pdf "^9.1.1" react-select@^5.7.0: version "5.7.0" @@ -7781,7 +7817,7 @@ readable-stream@^2.0.1, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.4.0, readable-stream@^3.6.0: +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -8082,9 +8118,9 @@ sass@1.41.0: chokidar ">=3.0.0 <4.0.0" sax@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" - integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== + version "1.4.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.4.tgz#f29c2bba80ce5b86f4343b4c2be9f2b96627cf8b" + integrity sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw== scheduler@^0.23.2: version "0.23.2" @@ -8271,6 +8307,15 @@ simple-get@^3.0.3: once "^1.3.1" simple-concat "^1.0.0" +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -8331,18 +8376,6 @@ spawn-wrap@^2.0.0: signal-exit "^3.0.2" which "^2.0.1" -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -ssf@~0.11.2: - version "0.11.2" - resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" - integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g== - dependencies: - frac "~1.1.2" - sshpk@^1.14.1: version "1.17.0" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" @@ -8513,13 +8546,12 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -strtok3@^10.2.0, strtok3@^10.2.2: - version "10.2.2" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.2.2.tgz#a4c6d78d15db02c5eb20d92af3eedf81edaf09d2" - integrity sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg== +strtok3@^10.3.4: + version "10.3.4" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-10.3.4.tgz#793ebd0d59df276a085586134b73a406e60be9c1" + integrity sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg== dependencies: "@tokenizer/token" "^0.3.0" - peek-readable "^7.0.0" style-to-object@^0.3.0: version "0.3.0" @@ -8664,6 +8696,27 @@ tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar-fs@^2.0.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.4.tgz#800824dbf4ef06ded9afea4acafe71c67c76b930" + integrity sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar@^6.1.11, tar@^7.5.7: version "7.5.7" resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.7.tgz#adf99774008ba1c89819f15dbd6019c630539405" @@ -8680,25 +8733,24 @@ temp@~0.4.0: resolved "https://registry.yarnpkg.com/temp/-/temp-0.4.0.tgz#671ad63d57be0fe9d7294664b3fc400636678a60" integrity sha512-IsFisGgDKk7qzK9erMIkQe/XwiSUdac7z3wYOsjcLkhPBy3k1SlvLoIh2dAHIlEpgA971CgguMrx9z8fFg7tSA== -tesseract.js-core@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/tesseract.js-core/-/tesseract.js-core-5.1.0.tgz#4e1d0b9133e92748f9866c7fa76469ec85858f1a" - integrity sha512-D4gc5ET1DF/sDayF/eVmHgVGo7nqVC2e3d7uVgVOSAk4NOcmUqvJRTj8etqEmI/2390ZkXCRiDMxTD1RFYyp1g== +tesseract.js-core@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tesseract.js-core/-/tesseract.js-core-7.0.0.tgz#596aa1ab5c130adab12f21059e6aa1a1cecc0bab" + integrity sha512-WnNH518NzmbSq9zgTPeoF8c+xmilS8rFIl1YKbk/ptuuc7p6cLNELNuPAzcmsYw450ca6bLa8j3t0VAtq435Vw== -tesseract.js@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-5.0.5.tgz#a974f4e1028350ebdcc8b5ebf70cea3ed2bc96de" - integrity sha512-xtTfec4IynE63sl6kAFkGl1mejlNxr9qQXzVGAUHd7IPdQXveopjGO9Eph6xkSuW5sUCC9AT6VdBmODh8ZymGg== +tesseract.js@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-7.0.0.tgz#4106fb6245efab40c57b94bc1798368807526be8" + integrity sha512-exPBkd+z+wM1BuMkx/Bjv43OeLBxhL5kKWsz/9JY+DXcXdiBjiAch0V49QR3oAJqCaL5qURE0vx9Eo+G5YE7mA== dependencies: bmp-js "^0.1.0" idb-keyval "^6.2.0" - is-electron "^2.2.2" is-url "^1.2.4" node-fetch "^2.6.9" opencollective-postinstall "^2.0.3" regenerator-runtime "^0.13.3" - tesseract.js-core "^5.0.0" - wasm-feature-detect "^1.2.11" + tesseract.js-core "^7.0.0" + wasm-feature-detect "^1.8.0" zlibjs "^0.3.1" test-exclude@^6.0.0: @@ -8785,11 +8837,12 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -token-types@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.0.0.tgz#1ab26be1ef9c434853500c071acfe5c8dd6544a3" - integrity sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA== +token-types@^6.1.1, token-types@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.1.2.tgz#18d0fd59b996d421f9f83914d6101c201bd08129" + integrity sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww== dependencies: + "@borewit/text-codec" "^0.2.1" "@tokenizer/token" "^0.3.0" ieee754 "^1.2.1" @@ -8983,10 +9036,10 @@ uid-safe@2.1.5: dependencies: random-bytes "~1.0.0" -uint8array-extras@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.4.0.tgz#e42a678a6dd335ec2d21661333ed42f44ae7cc74" - integrity sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ== +uint8array-extras@^1.4.0, uint8array-extras@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.5.0.tgz#10d2a85213de3ada304fea1c454f635c73839e86" + integrity sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A== unbox-primitive@^1.0.2: version "1.0.2" @@ -9008,15 +9061,10 @@ uncontrollable@^7.2.1: invariant "^2.2.4" react-lifecycles-compat "^3.0.4" -underscore@^1.13.1: - version "1.13.7" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.7.tgz#970e33963af9a7dda228f17ebe8399e5fbe63a10" - integrity sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g== - -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== +undici-types@~7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" + integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" @@ -9240,10 +9288,10 @@ warning@^4.0.0, warning@^4.0.3: dependencies: loose-envify "^1.0.0" -wasm-feature-detect@^1.2.11: - version "1.6.1" - resolved "https://registry.yarnpkg.com/wasm-feature-detect/-/wasm-feature-detect-1.6.1.tgz#21c7c35f9b233d71d2948d4a8b3e2098c452b940" - integrity sha512-R1i9ED8UlLu/foILNB1ck9XS63vdtqU/tP1MCugVekETp/ySCrBZRk5I/zI67cI1wlQYeSonNm1PLjDHZDNg6g== +wasm-feature-detect@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz#4e9f55b0a64d801f372fbb0324ed11ad3abd0c78" + integrity sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ== wcwidth@^1.0.1: version "1.0.1" @@ -9334,21 +9382,16 @@ wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" -wmf@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" - integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw== +win-guid@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/win-guid/-/win-guid-0.2.1.tgz#576915ba5e10bf92ec6a32b71ab06b5f75403fc0" + integrity sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A== word-wrap@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -word@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" - integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA== - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -9400,19 +9443,6 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -xlsx@^0.18.5: - version "0.18.5" - resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0" - integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ== - dependencies: - adler-32 "~1.3.0" - cfb "~1.2.1" - codepage "~1.15.0" - crc-32 "~1.2.1" - ssf "~0.11.2" - wmf "~1.0.1" - word "~0.3.0" - xml-js@^1.6.8: version "1.6.11" resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" @@ -9425,11 +9455,6 @@ xml@^1.0.1: resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw== -xmlbuilder@^10.0.0: - version "10.1.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0" - integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg== - xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"