diff --git a/.replit b/.replit index adcfadc..01c9710 100644 --- a/.replit +++ b/.replit @@ -37,3 +37,6 @@ author = "agent" task = "shell.exec" args = "npm run dev" waitForPort = 5000 + +[agent] +integrations = ["javascript_object_storage==1.0.0"] diff --git a/client/src/components/thumbnail-generator.tsx b/client/src/components/thumbnail-generator.tsx new file mode 100644 index 0000000..05b9713 --- /dev/null +++ b/client/src/components/thumbnail-generator.tsx @@ -0,0 +1,336 @@ +import { useRef, useState, useEffect } from "react"; +import { X, Download, Upload, Check, RotateCcw } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Slider } from "@/components/ui/slider"; +import Hls from "hls.js"; + +interface ThumbnailGeneratorProps { + videoUrl: string; + videoTitle: string; + isOpen: boolean; + onClose: () => void; + onThumbnailSelect: (thumbnailDataUrl: string) => void; +} + +export default function ThumbnailGenerator({ + videoUrl, + videoTitle, + isOpen, + onClose, + onThumbnailSelect +}: ThumbnailGeneratorProps) { + const videoRef = useRef(null); + const canvasRef = useRef(null); + const hlsRef = useRef(null); + const fileInputRef = useRef(null); + + const [duration, setDuration] = useState(0); + const [currentTime, setCurrentTime] = useState(0); + const [isVideoLoaded, setIsVideoLoaded] = useState(false); + const [selectedThumbnail, setSelectedThumbnail] = useState(null); + const [customThumbnail, setCustomThumbnail] = useState(null); + const [isGenerating, setIsGenerating] = useState(false); + + // Initialize video when modal opens + useEffect(() => { + if (isOpen && videoRef.current && videoUrl) { + initializeVideo(); + } + + return () => { + if (hlsRef.current) { + hlsRef.current.destroy(); + hlsRef.current = null; + } + }; + }, [isOpen, videoUrl]); + + const initializeVideo = () => { + const videoElement = videoRef.current; + if (!videoElement) return; + + // Clean up previous HLS instance + if (hlsRef.current) { + hlsRef.current.destroy(); + hlsRef.current = null; + } + + if (videoUrl.includes('.m3u8')) { + if (Hls.isSupported()) { + const hls = new Hls({ + debug: false, + enableWorker: false, + lowLatencyMode: false + }); + + hls.loadSource(videoUrl); + hls.attachMedia(videoElement); + + hls.on(Hls.Events.MANIFEST_PARSED, () => { + console.log('Video loaded for thumbnail generation'); + setIsVideoLoaded(true); + }); + + hlsRef.current = hls; + } else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) { + videoElement.src = videoUrl; + setIsVideoLoaded(true); + } + } else { + videoElement.src = videoUrl; + setIsVideoLoaded(true); + } + + // Video event listeners + videoElement.addEventListener('loadedmetadata', () => { + setDuration(videoElement.duration); + setCurrentTime(0); + }); + + videoElement.addEventListener('timeupdate', () => { + setCurrentTime(videoElement.currentTime); + }); + }; + + const generateThumbnail = async () => { + const videoElement = videoRef.current; + const canvas = canvasRef.current; + + if (!videoElement || !canvas) return; + + setIsGenerating(true); + + try { + const ctx = canvas.getContext('2d'); + if (!ctx) return; + + // Set canvas dimensions to match video + canvas.width = videoElement.videoWidth || 1280; + canvas.height = videoElement.videoHeight || 720; + + // Draw current video frame to canvas + ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height); + + // Convert to data URL + const thumbnailDataUrl = canvas.toDataURL('image/jpeg', 0.9); + setSelectedThumbnail(thumbnailDataUrl); + setCustomThumbnail(null); + + } catch (error) { + console.error('Error generating thumbnail:', error); + } finally { + setIsGenerating(false); + } + }; + + const handleTimeSliderChange = (value: number[]) => { + const newTime = value[0]; + setCurrentTime(newTime); + + if (videoRef.current) { + videoRef.current.currentTime = newTime; + } + }; + + const handleCustomImageUpload = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = (e) => { + const result = e.target?.result as string; + setCustomThumbnail(result); + setSelectedThumbnail(null); + }; + reader.readAsDataURL(file); + }; + + const handleSaveThumbnail = () => { + const thumbnail = selectedThumbnail || customThumbnail; + if (thumbnail) { + onThumbnailSelect(thumbnail); + onClose(); + } + }; + + const formatTime = (seconds: number) => { + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins}:${secs.toString().padStart(2, '0')}`; + }; + + if (!isOpen) return null; + + return ( +
+
+
+ {/* Header */} +
+

+ Generiraj thumbnail sliko +

+ +
+ +
+ {/* Video Player Section */} +
+

+ Video predogled +

+ +
+ + + {!isVideoLoaded && ( +
+
+
+ )} +
+ + {/* Time Slider */} + {isVideoLoaded && duration > 0 && ( +
+
+ {formatTime(currentTime)} + {formatTime(duration)} +
+ +
+ )} + + {/* Generate Button */} + +
+ + {/* Thumbnail Preview Section */} +
+

+ Predogled thumbnail +

+ + {/* Thumbnail Preview */} +
+ {selectedThumbnail || customThumbnail ? ( +
+ Thumbnail predogled +

+ {selectedThumbnail ? 'Generirano iz videoposnetka' : 'Naložena slika'} +

+
+ ) : ( +
+
+ 📷 +
+

Generirajte thumbnail iz videoposnetka ali naložite svojo sliko

+
+ )} +
+ + {/* Custom Upload */} +
+

+ Ali naložite svojo sliko +

+ + +
+ + {/* Action Buttons */} +
+ + +
+
+
+ + {/* Hidden canvas for thumbnail generation */} + +
+
+
+ ); +} \ No newline at end of file diff --git a/client/src/components/ui/slider.tsx b/client/src/components/ui/slider.tsx index e161dae..3eb2e57 100644 --- a/client/src/components/ui/slider.tsx +++ b/client/src/components/ui/slider.tsx @@ -23,4 +23,4 @@ const Slider = React.forwardRef< )) Slider.displayName = SliderPrimitive.Root.displayName -export { Slider } +export { Slider } \ No newline at end of file diff --git a/client/src/components/video-edit-modal.tsx b/client/src/components/video-edit-modal.tsx index 9f41b95..5937416 100644 --- a/client/src/components/video-edit-modal.tsx +++ b/client/src/components/video-edit-modal.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { X, Upload, Save } from "lucide-react"; +import { X, Upload, Save, Camera } from "lucide-react"; import { type Video, type UpdateVideo, updateVideoSchema } from "@shared/schema"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -8,6 +8,7 @@ import { Label } from "@/components/ui/label"; import { apiRequest, queryClient } from "@/lib/queryClient"; import { useToast } from "@/hooks/use-toast"; import { useMutation } from "@tanstack/react-query"; +import ThumbnailGenerator from "./thumbnail-generator"; interface VideoEditModalProps { video: Video; @@ -23,6 +24,7 @@ export default function VideoEditModal({ video, isOpen, onClose }: VideoEditModa const [isPublic, setIsPublic] = useState(video.isPublic); const [customThumbnail, setCustomThumbnail] = useState(null); const [thumbnailPreview, setThumbnailPreview] = useState(video.customThumbnailUrl); + const [showThumbnailGenerator, setShowThumbnailGenerator] = useState(false); const { toast } = useToast(); @@ -57,6 +59,13 @@ export default function VideoEditModal({ video, isOpen, onClose }: VideoEditModa } }; + const handleThumbnailFromVideo = (thumbnailDataUrl: string) => { + setThumbnailPreview(thumbnailDataUrl); + setCustomThumbnail(null); // Clear file input since we're using generated thumbnail + setShowThumbnailGenerator(false); + toast({ title: "Thumbnail ustvarjen iz videoposnetka!" }); + }; + const handleSave = () => { try { const tagsArray = tags.split(",").map(tag => tag.trim()).filter(tag => tag.length > 0); @@ -175,29 +184,43 @@ export default function VideoEditModal({ video, isOpen, onClose }: VideoEditModa -
+
{thumbnailPreview && ( -
+
Predogled
)} - + +
+ + + +
@@ -247,6 +270,15 @@ export default function VideoEditModal({ video, isOpen, onClose }: VideoEditModa
+ + {/* Thumbnail Generator Modal */} + setShowThumbnailGenerator(false)} + onThumbnailSelect={handleThumbnailFromVideo} + /> ); } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 77a5826..2d0508f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@google-cloud/storage": "^7.16.0", "@google-cloud/video-intelligence": "^6.2.0", "@hookform/resolvers": "^3.10.0", "@jridgewell/trace-mapping": "^0.3.25", @@ -32,7 +33,7 @@ "@radix-ui/react-scroll-area": "^1.2.4", "@radix-ui/react-select": "^2.1.7", "@radix-ui/react-separator": "^1.1.3", - "@radix-ui/react-slider": "^1.2.4", + "@radix-ui/react-slider": "^1.3.5", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-switch": "^1.1.4", "@radix-ui/react-tabs": "^1.1.4", @@ -42,6 +43,13 @@ "@radix-ui/react-tooltip": "^1.2.0", "@tanstack/react-query": "^5.60.5", "@types/video.js": "^7.3.58", + "@uppy/aws-s3": "^4.3.2", + "@uppy/core": "^4.5.2", + "@uppy/dashboard": "^4.4.3", + "@uppy/drag-drop": "^4.2.2", + "@uppy/file-input": "^4.2.2", + "@uppy/progress-bar": "^4.3.2", + "@uppy/react": "^4.5.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -53,6 +61,7 @@ "express": "^4.21.2", "express-session": "^1.18.1", "framer-motion": "^11.13.1", + "google-auth-library": "^10.2.1", "hls.js": "^1.6.7", "input-otp": "^1.4.2", "lucide-react": "^0.453.0", @@ -1314,6 +1323,245 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.16.0.tgz", + "integrity": "sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==", + "license": "Apache-2.0", + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "<4.1.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "duplexify": "^4.1.3", + "fast-xml-parser": "^4.4.1", + "gaxios": "^6.0.2", + "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", + "mime": "^3.0.0", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/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==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@google-cloud/storage/node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/storage/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@google-cloud/storage/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==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@google-cloud/storage/node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/teeny-request/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==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@google-cloud/storage/node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@google-cloud/video-intelligence": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@google-cloud/video-intelligence/-/video-intelligence-6.2.0.tgz", @@ -2488,18 +2736,19 @@ } }, "node_modules/@radix-ui/react-slider": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.2.4.tgz", - "integrity": "sha512-Vr/OgNejNJPAghIhjS7Mf/2F/EXGDT0qgtiHf2BHz71+KqgN+jndFLKq5xAB9JOGejGzejfJLIvT04Do+yzhcg==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.5.tgz", + "integrity": "sha512-rkfe2pU2NBAYfGaxa3Mqosi7VZEWX5CxKaanRv0vZd4Zhl9fvQrg0VM93dv3xGLGfrHuoTRF3JXH8nb9g+B3fw==", + "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.0.3", - "@radix-ui/react-use-controllable-state": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" @@ -2519,6 +2768,92 @@ } } }, + "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.0.tgz", @@ -2743,6 +3078,24 @@ } } }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-escape-keydown": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", @@ -3433,6 +3786,12 @@ "node": ">= 10" } }, + "node_modules/@transloadit/prettier-bytes": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@transloadit/prettier-bytes/-/prettier-bytes-0.3.5.tgz", + "integrity": "sha512-xF4A3d/ZyX2LJWeQZREZQw+qFX4TGQ8bGVP97OLRt6sPO6T0TNHBFTuRHOJh7RNmYOBmQ9MHxpolD9bXihpuVA==", + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3744,6 +4103,12 @@ "form-data": "^2.5.5" } }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "license": "MIT" + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -3789,6 +4154,530 @@ "@types/node": "*" } }, + "node_modules/@uppy/audio": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@uppy/audio/-/audio-2.2.2.tgz", + "integrity": "sha512-63pwCo+JbJyxB1V/YK59cMSMFi8+g9Mfew6awfJFeu4tAK0HHfZtUk5+fUdZJRdCf4eIwBAiwixBL8Q4BOes+Q==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/aws-s3": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/aws-s3/-/aws-s3-4.3.2.tgz", + "integrity": "sha512-w3LrMUEI9pXVcn5LZ5oNL92hyocMu8mxfDSVVQIAQKxR+TPi57FfusDBqBB5T33UvxJH8EUGt9a04tuU/LpKqw==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/utils": "^6.2.2" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/box": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@uppy/box/-/box-3.3.2.tgz", + "integrity": "sha512-4hRXPWy48Gpgyegd7lBPMYQTplfFEq1uaHe9ZltHu53LBeXasuGeZuprMbhIQ/7Sl/7UQwiAU0te9uv/ypoXGg==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/companion-client": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-4.5.2.tgz", + "integrity": "sha512-hfUsReHM5COhn+5d7CdZgZaG8BtDvtwj7vjXzg8qmgKI901mYUm/Zh420iOKT7eHiofKVTNoa7oijeGrqUEnyg==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "namespace-emitter": "^2.0.1", + "p-retry": "^6.1.0" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/components": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@uppy/components/-/components-0.3.2.tgz", + "integrity": "sha512-RHEV2Ru/SU1J8EoLabUX8GXQ59Q5+/FhSL5vIpicaVj++Neei58WYKj4iNWsigE4xE45jtHfYTV9IlXc+fJXaQ==", + "license": "MIT", + "dependencies": { + "@uppy/audio": "^2.2.2", + "@uppy/core": "^4.5.2", + "@uppy/image-editor": "^3.4.2", + "@uppy/remote-sources": "^2.4.2", + "@uppy/screen-capture": "^4.4.2", + "@uppy/webcam": "^4.3.2", + "clsx": "^2.1.1", + "dequal": "^2.0.3", + "preact": "^10.5.13", + "pretty-bytes": "^6.1.1" + } + }, + "node_modules/@uppy/core": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@uppy/core/-/core-4.5.2.tgz", + "integrity": "sha512-5XoPJNcqEXtxtw+vg8EyqUFe11JSbG3/aln83Y7+CLbs7WOovYdfwwKEt1aTbfg1+ijsxudLchya5yh72jaLqw==", + "license": "MIT", + "dependencies": { + "@transloadit/prettier-bytes": "^0.3.4", + "@uppy/store-default": "^4.3.2", + "@uppy/utils": "^6.2.2", + "lodash": "^4.17.21", + "mime-match": "^1.0.2", + "namespace-emitter": "^2.0.1", + "nanoid": "^5.0.9", + "preact": "^10.5.13" + } + }, + "node_modules/@uppy/core/node_modules/nanoid": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@uppy/dashboard": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@uppy/dashboard/-/dashboard-4.4.3.tgz", + "integrity": "sha512-IwgDDTbk9p4OoAJvvvx6sQSemKTIJq9IDSryNVgbbC6NiR9HSyRcu0+WdOZLiR9DOhDg2oYcoNgv7DMlrktI6g==", + "license": "MIT", + "dependencies": { + "@transloadit/prettier-bytes": "^0.3.4", + "@uppy/informer": "^4.3.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/status-bar": "^4.2.3", + "@uppy/thumbnail-generator": "^4.2.2", + "@uppy/utils": "^6.2.2", + "classnames": "^2.2.6", + "lodash": "^4.17.21", + "nanoid": "^5.0.9", + "preact": "^10.5.13", + "shallow-equal": "^3.0.0" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/dashboard/node_modules/nanoid": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@uppy/drag-drop": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@uppy/drag-drop/-/drag-drop-4.2.2.tgz", + "integrity": "sha512-SlVl+lHC8TvCKW4B9L4pdb0n8mEVgACHjKXGWcy7EUsTrRphv3ugmkbIFL57XpmFR+AFMuPblOsKq/9nkPkHOQ==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/dropbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/dropbox/-/dropbox-4.3.2.tgz", + "integrity": "sha512-Kj/QX8KFomlbf5mUpoCwxZ8dGH9XiN3RMKqT6zJgUk2bW7JfV2eMV6F9XvrVhz1TCtHZNl81Cv5rhu9io3UQ0w==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/facebook": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/facebook/-/facebook-4.3.2.tgz", + "integrity": "sha512-fHwFN8ZlRuNyxmuL7zwMLIegU+ARxegIlM3yJdY7RbRWgod/lUi5ouzTHjFgvLaFbuDtYWWRbZgF3GxCsXbmhA==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/file-input": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@uppy/file-input/-/file-input-4.2.2.tgz", + "integrity": "sha512-tQklK5C1slZWQlMQYQPBJuhfs0e5w1sRb0VwYMt8P297rB1BUcyOjkVH79DAYHkkgXo9aQKUiZSuVoN89tlLjQ==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/google-drive": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@uppy/google-drive/-/google-drive-4.4.2.tgz", + "integrity": "sha512-hIxnWZ7WMW1jrRecL+VnMVt9TwY+V3uEpy7KmNxASraQFwS2oYgYUfO5R8MVcmL654wymQgEsRY7Kzp9NQvZGw==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/image-editor": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@uppy/image-editor/-/image-editor-3.4.2.tgz", + "integrity": "sha512-cQD/oDa/0xCuZAtdi4P2uLIxgrG/YR24KgKAxQYPzQHQtNB8KzCdl3TPV5ZWF9kjT4mSlUsoB4RfPQl34GbFhA==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "cropperjs": "^1.6.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/informer": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/informer/-/informer-4.3.2.tgz", + "integrity": "sha512-7A9X8BfxR/GPtG0MGbQlmj1+G1o9fqeF3qtRh37ZvmZpapnEGtbstQ6Ao2vFm0uxYxOolLOMzFs/xCD27NKAvg==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/instagram": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/instagram/-/instagram-4.3.2.tgz", + "integrity": "sha512-LHGroKn8uRcRs94v6DM8SPXIMWubZb/aZr5B4FP7TvTzf3vnGaKE63oOen1yAoCEYbsJfSdo2p974qHbSdPEbw==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/onedrive": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/onedrive/-/onedrive-4.3.2.tgz", + "integrity": "sha512-dfJAl9qsoQsL1LdIrDPKEKmAj82VNA63BInsJ80nF8bx3tf67AvlMz4O1I9fDW2zctfgOiFlGz47kamz01eSPQ==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/progress-bar": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/progress-bar/-/progress-bar-4.3.2.tgz", + "integrity": "sha512-5BOhq49xPpBTlEVsEIRLkV+Hgb0qTuey8XKyrmrSetcgtolKLwtlDjrOWmUcxGYI3bkMbdeJulF9aiR8sSqQ6A==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/provider-views": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@uppy/provider-views/-/provider-views-4.5.2.tgz", + "integrity": "sha512-ik54ZHwZNE8czcoWiH0WLzFc/5zHIWAesiqsjZ/MjDpK/6Oun/BhQpUXpXe6629IeIXY+gDo5Uktf6vXtXfosg==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "classnames": "^2.2.6", + "nanoid": "^5.0.9", + "p-queue": "^8.0.0", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/provider-views/node_modules/nanoid": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@uppy/react": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@uppy/react/-/react-4.5.2.tgz", + "integrity": "sha512-M2RTC8APz0pbzvAwyBIQEw9pwxlR9gFXII4dU7yUJ/Jb0iLkGuvYrltb9ai4GyPsxOGfdWiFX8e5s8f6Z+Ao1g==", + "license": "MIT", + "dependencies": { + "@uppy/components": "^0.3.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13", + "use-sync-external-store": "^1.2.2" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2", + "@uppy/dashboard": "^4.4.2", + "@uppy/drag-drop": "^4.2.2", + "@uppy/file-input": "^4.2.2", + "@uppy/progress-bar": "^4.3.2", + "@uppy/screen-capture": "^4.4.2", + "@uppy/status-bar": "^4.2.2", + "@uppy/webcam": "^4.3.2", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@uppy/dashboard": { + "optional": true + }, + "@uppy/drag-drop": { + "optional": true + }, + "@uppy/file-input": { + "optional": true + }, + "@uppy/progress-bar": { + "optional": true + }, + "@uppy/screen-capture": { + "optional": true + }, + "@uppy/status-bar": { + "optional": true + }, + "@uppy/webcam": { + "optional": true + } + } + }, + "node_modules/@uppy/remote-sources": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@uppy/remote-sources/-/remote-sources-2.4.2.tgz", + "integrity": "sha512-b8VVlriQWi/xU/LBuoLaQ3y2yMMLqXXJQpkG43tzBQG2R/sYz2qOm593BX9R4HjPQ891Vt4INjzfDTFziaA/4w==", + "license": "MIT", + "dependencies": { + "@uppy/box": "^3.3.2", + "@uppy/dashboard": "^4.4.2", + "@uppy/dropbox": "^4.3.2", + "@uppy/facebook": "^4.3.2", + "@uppy/google-drive": "^4.4.2", + "@uppy/instagram": "^4.3.2", + "@uppy/onedrive": "^4.3.2", + "@uppy/unsplash": "^4.4.2", + "@uppy/url": "^4.3.2", + "@uppy/zoom": "^3.3.2" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/screen-capture": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@uppy/screen-capture/-/screen-capture-4.4.2.tgz", + "integrity": "sha512-z2+Y34V8hs1lCeMB+culySW9WMBIL/19Z8OEkc0u6aHj3i6iCu0lwelPEaiUMdKHOXMyQTgn6Ubv+C3/OZlOpw==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/status-bar": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@uppy/status-bar/-/status-bar-4.2.3.tgz", + "integrity": "sha512-0AtKdvNm3HHobuE4N0V8SrC3uWB9MQnjqMEL/gachW/1mi7iZ22V4veHd6Wub/tCBQAQbEklvz7d0hxcz/Fh9g==", + "license": "MIT", + "dependencies": { + "@transloadit/prettier-bytes": "^0.3.4", + "@uppy/utils": "^6.2.2", + "classnames": "^2.2.6", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/store-default": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/store-default/-/store-default-4.3.2.tgz", + "integrity": "sha512-dnY9R2o8fwmO1bF89D0b5jijD7DGED2qVST5hI/j18JreLWzLKH7u6HuNmOvzok8msrQ/qWzQd5Gx4LDQKhBbw==", + "license": "MIT" + }, + "node_modules/@uppy/thumbnail-generator": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@uppy/thumbnail-generator/-/thumbnail-generator-4.2.2.tgz", + "integrity": "sha512-cHVhrtqqy4j++UxtkwguKSSA/h9PR9UXSar0gr/uGHWsQbXNDzoT23EAFOsVr9ZFkIhtLU7M0x+iCq2hUlX5Tw==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "exifr": "^7.0.0" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/unsplash": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@uppy/unsplash/-/unsplash-4.4.2.tgz", + "integrity": "sha512-1hO7ND/ROrRgZ8urCX38Q/o5rYs2uFGS7djxlNj/cz9xvRdkBagAzj3qp5FUsnPnJzJrRpifXcelvn3tICQjZg==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/url": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/url/-/url-4.3.2.tgz", + "integrity": "sha512-SREfvV9IJxOg2MuzSVQBr2e9LTle8N0dsyUpsHddaSbbPku9KhkoilOiKuDMhPmvw9pnkYWBZhbw9+4UWnrQtQ==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/utils": "^6.2.2", + "nanoid": "^5.0.9", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/url/node_modules/nanoid": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", + "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@uppy/utils": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/@uppy/utils/-/utils-6.2.2.tgz", + "integrity": "sha512-9mYJtbcngv2HOJIECkyfmdXTI5dW/ObCyvWP1Iti3E5bKtsa4sMmbx5Yh/tGCj8k/lBNhfvWyZuYnvnjmzNLSQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "preact": "^10.5.13" + } + }, + "node_modules/@uppy/webcam": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@uppy/webcam/-/webcam-4.3.2.tgz", + "integrity": "sha512-x0qhTWb7AjkfS9Q12J2xhnTdccZ6sMuBh14LpXtXjaFe4Q1Uf191YmFwT7SCKn7lcasZYw3Tug0G5yQkqvg9uQ==", + "license": "MIT", + "dependencies": { + "@uppy/utils": "^6.2.2", + "is-mobile": "^4.0.0", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, + "node_modules/@uppy/zoom": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@uppy/zoom/-/zoom-3.3.2.tgz", + "integrity": "sha512-e/yP3itmWh2U/A8SBLymVngDSIzmbq08eX0QzBrI5wIA1r38lD5tGlO2V9D70ujY8hNX7HQUqF+nK4OEgdUxJA==", + "license": "MIT", + "dependencies": { + "@uppy/companion-client": "^4.5.2", + "@uppy/provider-views": "^4.5.2", + "@uppy/utils": "^6.2.2", + "preact": "^10.5.13" + }, + "peerDependencies": { + "@uppy/core": "^4.5.2" + } + }, "node_modules/@videojs/http-streaming": { "version": "3.17.2", "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.2.tgz", @@ -3979,6 +4868,24 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "dependencies": { + "retry": "0.13.1" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -4524,6 +5431,12 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, + "node_modules/cropperjs": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.6.2.tgz", + "integrity": "sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4753,6 +5666,15 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -5638,6 +6560,12 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/exifr": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/exifr/-/exifr-7.1.3.tgz", + "integrity": "sha512-g/aje2noHivrRSLbAUtBPWFbxKdKhgj/xr1vATDdUXPOFYJlQ62Ft0oy+72V6XLIpDJfHs6gXLbBLAolqOXYRw==", + "license": "MIT" + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -5790,6 +6718,24 @@ "node": ">= 6" } }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -6288,6 +7234,22 @@ "integrity": "sha512-QW2fnwDGKGc9DwQUGLbmMOz8G48UZK7PVNJPcOUql1b8jubKx4/eMHNP5mGqr6tYlJNDG1g10Lx2U/qPzL6zwQ==", "license": "Apache-2.0" }, + "node_modules/html-entities": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -6451,6 +7413,24 @@ "node": ">=0.10.0" } }, + "node_modules/is-mobile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-4.0.0.tgz", + "integrity": "sha512-mlcHZA84t1qLSuWkt2v0I2l61PYdyQDt4aG1mLIXF5FDMm4+haBCxCPYSr/uwqQNRk1MiTizn0ypEuRAOLRAew==", + "license": "MIT" + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -6460,6 +7440,18 @@ "node": ">=0.12.0" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -7017,6 +8009,15 @@ "node": ">= 0.6" } }, + "node_modules/mime-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-match/-/mime-match-1.0.2.tgz", + "integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==", + "license": "ISC", + "dependencies": { + "wildcard": "^1.1.0" + } + }, "node_modules/mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", @@ -7132,6 +8133,12 @@ "thenify-all": "^1.0.0" } }, + "node_modules/namespace-emitter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz", + "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", @@ -7309,6 +8316,72 @@ "wrappy": "1" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.0.tgz", + "integrity": "sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -7800,6 +8873,28 @@ "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", "license": "MIT" }, + "node_modules/preact": { + "version": "10.27.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.0.tgz", + "integrity": "sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/pretty-bytes": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", + "license": "MIT", + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -8258,6 +9353,15 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/retry-request": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-8.0.0.tgz", @@ -8474,6 +9578,12 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/shallow-equal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz", + "integrity": "sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8693,6 +9803,18 @@ "node": ">=8" } }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", @@ -8883,6 +10005,12 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -9521,6 +10649,15 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -10148,6 +11285,22 @@ "node": ">= 8" } }, + "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==", + "license": "BSD-2-Clause" + }, + "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==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -10163,6 +11316,12 @@ "node": ">= 8" } }, + "node_modules/wildcard": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-1.1.2.tgz", + "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==", + "license": "MIT" + }, "node_modules/wouter": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/wouter/-/wouter-3.3.5.tgz", @@ -10400,6 +11559,18 @@ "node": ">=8" } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "3.24.2", "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", diff --git a/package.json b/package.json index f60cccc..d9f2409 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "db:push": "drizzle-kit push" }, "dependencies": { + "@google-cloud/storage": "^7.16.0", "@google-cloud/video-intelligence": "^6.2.0", "@hookform/resolvers": "^3.10.0", "@jridgewell/trace-mapping": "^0.3.25", @@ -34,7 +35,7 @@ "@radix-ui/react-scroll-area": "^1.2.4", "@radix-ui/react-select": "^2.1.7", "@radix-ui/react-separator": "^1.1.3", - "@radix-ui/react-slider": "^1.2.4", + "@radix-ui/react-slider": "^1.3.5", "@radix-ui/react-slot": "^1.2.0", "@radix-ui/react-switch": "^1.1.4", "@radix-ui/react-tabs": "^1.1.4", @@ -44,6 +45,13 @@ "@radix-ui/react-tooltip": "^1.2.0", "@tanstack/react-query": "^5.60.5", "@types/video.js": "^7.3.58", + "@uppy/aws-s3": "^4.3.2", + "@uppy/core": "^4.5.2", + "@uppy/dashboard": "^4.4.3", + "@uppy/drag-drop": "^4.2.2", + "@uppy/file-input": "^4.2.2", + "@uppy/progress-bar": "^4.3.2", + "@uppy/react": "^4.5.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -55,6 +63,7 @@ "express": "^4.21.2", "express-session": "^1.18.1", "framer-motion": "^11.13.1", + "google-auth-library": "^10.2.1", "hls.js": "^1.6.7", "input-otp": "^1.4.2", "lucide-react": "^0.453.0", diff --git a/replit.md b/replit.md index 3998aee..5df808f 100644 --- a/replit.md +++ b/replit.md @@ -14,7 +14,8 @@ VideoStream is a fully functional video streaming platform that integrates direc - ✅ **Error Handling**: Robust error handling with Video.js fallback mechanisms - ✅ **Performance**: Optimized video loading with adaptive bitrate streaming and proper buffering - ✅ **Social Media Sharing**: Implemented direct social sharing for Facebook, Twitter, WhatsApp with custom popup windows and automatic video thumbnail capture -- ✅ **Monetization Ready**: Professional advertising framework ready for revenue generation +- ✅ **YouTube-Style Editing**: Complete video editing interface with title, description, category, tags, and privacy controls +- ✅ **Interactive Thumbnail Generator**: Advanced thumbnail creation from any video frame with timeline scrubbing and custom image upload - ✅ **Copy Link Feature**: Easy link copying with visual feedback notifications ## User Preferences