import { expandConversionPresets } from "./conversion-presets.js"; import { AUDIO_INPUTS, IMAGE_INPUTS, SUBTITLE_INPUTS, VIDEO_INPUTS } from "./modality.js"; import { toolSection } from "./section.js"; import type { CategoryInfo, SocialMediaPreset, Tool } from "./types.js"; export const CATEGORIES: CategoryInfo[] = [ // Image { id: "essentials", name: "Essentials", icon: "Layers", color: "#3B82F6" }, { id: "adjustments", name: "Adjustments", icon: "SlidersHorizontal", color: "#8B5CF6" }, { id: "enhance", name: "Enhance & AI", icon: "Sparkles", color: "#F59E0B" }, { id: "watermark", name: "Watermark & Overlay", icon: "Stamp", color: "#EF4444" }, { id: "layout", name: "Layout & Composition", icon: "LayoutGrid", color: "#EC4899" }, { id: "utilities", name: "Utilities", icon: "Wrench", color: "#6366F1" }, { id: "optimization", name: "Optimization", icon: "Zap", color: "#10B981" }, { id: "format", name: "Format & Conversion", icon: "FileType", color: "#14B8A6" }, // Video { id: "video-edit", name: "Edit", icon: "Video", color: "#EF4444" }, { id: "video-convert", name: "Convert", icon: "FileVideo", color: "#F97316" }, { id: "video-effects", name: "Effects & Compose", icon: "Wand2", color: "#EC4899" }, { id: "video-subtitles", name: "Subtitles", icon: "Captions", color: "#8B5CF6" }, { id: "video-metadata", name: "Metadata", icon: "Tags", color: "#6366F1" }, // Audio { id: "audio-edit", name: "Edit", icon: "AudioLines", color: "#10B981" }, { id: "audio-convert", name: "Convert", icon: "FileAudio", color: "#14B8A6" }, { id: "audio-effects", name: "Effects & Compose", icon: "Waves", color: "#06B6D4" }, { id: "audio-metadata", name: "Metadata", icon: "Tags", color: "#6366F1" }, // Documents { id: "pdf-organize", name: "Organize", icon: "FolderOpen", color: "#8B5CF6" }, { id: "pdf-edit", name: "Edit & Annotate", icon: "PenLine", color: "#3B82F6" }, { id: "pdf-security", name: "Security", icon: "Lock", color: "#EF4444" }, { id: "pdf-optimize", name: "Optimize", icon: "Zap", color: "#10B981" }, { id: "doc-convert", name: "Convert", icon: "FileType", color: "#14B8A6" }, // Data & Files { id: "data", name: "Files", icon: "Table", color: "#F59E0B" }, { id: "archives", name: "Archives", icon: "FolderArchive", color: "#6366F1" }, ]; const BASE_TOOLS: Tool[] = [ // Essentials { id: "resize", name: "Resize Image", description: "Resize by pixels, percentage, or social media presets", category: "essentials", icon: "Maximize2", route: "/resize", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "crop", name: "Crop Image", description: "Freeform crop, aspect ratio presets, shape crop", category: "essentials", icon: "Crop", route: "/crop", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "rotate", name: "Rotate & Flip Image", description: "Rotate, flip, and straighten images", category: "essentials", icon: "RotateCw", route: "/rotate", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "convert", name: "Convert Image", description: "Convert between image formats", category: "essentials", icon: "FileOutput", route: "/convert", modality: "image", acceptedInputs: IMAGE_INPUTS, keywords: [ "image converter", "jpg to png", "png to jpg", "heic to jpg", "webp to png", "convert image format", ], executionHint: "fast", }, { id: "compress", name: "Compress Image", description: "Reduce file size by quality or target size", category: "essentials", icon: "Minimize2", route: "/compress", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, // Optimization { id: "optimize-for-web", name: "Optimize for Web", description: "Optimize images for web with format conversion, quality control, and live preview", category: "optimization", icon: "Globe", route: "/optimize-for-web", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "strip-metadata", name: "Remove Image Metadata", description: "Remove EXIF, GPS, and camera info", category: "optimization", icon: "ShieldOff", route: "/strip-metadata", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "edit-metadata", name: "Edit Image Metadata", description: "Edit EXIF, GPS, and camera info", category: "optimization", icon: "PenLine", route: "/edit-metadata", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "bulk-rename", name: "Bulk Rename", description: "Rename multiple files with patterns", category: "optimization", icon: "FilePen", route: "/bulk-rename", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "image-to-pdf", name: "Image to PDF", description: "Combine images into a PDF document", category: "optimization", icon: "FileText", route: "/image-to-pdf", modality: "image", acceptedInputs: IMAGE_INPUTS, outputModality: "document", executionHint: "fast", }, { id: "favicon", name: "Favicon Generator", description: "Generate all favicon and app icon sizes", category: "optimization", icon: "AppWindow", route: "/favicon", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, // Adjustments { id: "adjust-colors", name: "Adjust Colors", description: "Brightness, contrast, exposure, saturation, temperature, sharpness, and effects", category: "adjustments", icon: "SlidersHorizontal", route: "/adjust-colors", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "sharpening", name: "Sharpen Image", description: "Adaptive, unsharp mask, and high-pass sharpening with presets", keywords: ["sharpen", "sharpening", "unsharp", "clarity"], category: "adjustments", icon: "Focus", route: "/sharpening", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "replace-color", name: "Replace & Invert Color", description: "Replace specific colors or invert", category: "adjustments", icon: "Pipette", route: "/replace-color", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "color-blindness", name: "Color Blindness Simulation", description: "Simulate how images appear with color vision deficiency", category: "adjustments", icon: "Eye", route: "/color-blindness", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, // Enhance & AI { id: "remove-background", name: "Remove Background", description: "AI-powered background removal", category: "enhance", icon: "Eraser", route: "/remove-background", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "remove-gif-background", name: "Remove GIF Background", description: "AI background removal for animated GIFs, WebP, and APNG", category: "enhance", icon: "Film", route: "/remove-gif-background", modality: "image", acceptedInputs: [".gif", ".webp", ".apng", ".png"], executionHint: "long", keywords: [ "gif", "animated", "transparent gif", "animated webp", "apng", "remove gif background", "gif background", "animated background removal", "transparent background gif", "gif cutout", ], }, { id: "upscale", name: "Image Upscaling", description: "AI super-resolution enhancement", category: "enhance", icon: "ZoomIn", route: "/upscale", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "erase-object", name: "Object Eraser", description: "Remove unwanted objects with AI", category: "enhance", icon: "Wand", route: "/erase-object", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "ocr", name: "Extract Text from Image (OCR)", description: "Extract text from images", category: "doc-convert", icon: "ScanText", route: "/ocr", modality: "image", acceptedInputs: IMAGE_INPUTS, outputModality: "file", executionHint: "long", }, { id: "ocr-pdf", name: "PDF OCR", description: "Extract text from PDF documents using AI-powered OCR", category: "doc-convert", icon: "ScanText", route: "/ocr-pdf", modality: "document", acceptedInputs: [".pdf"], outputModality: "file", executionHint: "long", }, { id: "blur-faces", name: "Blur Faces & PII", description: "Auto-detect and blur faces and sensitive info", keywords: ["blur faces", "pii", "redact face", "anonymize"], category: "enhance", icon: "EyeOff", route: "/blur-faces", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "smart-crop", name: "Smart Crop", description: "Smart subject, face, or trim-based cropping", category: "enhance", icon: "Crosshair", route: "/smart-crop", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "image-enhancement", name: "Image Enhancement", description: "One-click auto-improve with smart analysis", category: "enhance", icon: "Sparkles", route: "/image-enhancement", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", // pure sharp/CV; optional deepEnhance defers to noise-removal }, { id: "enhance-faces", name: "Face Enhancement", description: "Restore and enhance faces with AI", category: "enhance", icon: "ScanFace", route: "/enhance-faces", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "colorize", name: "AI Colorization", description: "Convert B&W photos to full color with AI", category: "enhance", icon: "Palette", route: "/colorize", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "noise-removal", name: "Noise Removal", description: "AI-powered noise and grain removal", category: "enhance", icon: "AudioLines", route: "/noise-removal", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "red-eye-removal", name: "Red Eye Removal", description: "AI-detect and fix red eye in flash photos", category: "enhance", icon: "ScanEye", route: "/red-eye-removal", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "restore-photo", name: "Photo Restoration", description: "Fix scratches, tears, and damage on old photos with AI", category: "enhance", icon: "Undo2", route: "/restore-photo", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "passport-photo", name: "Passport Photo", description: "AI-powered passport and ID photo generator", category: "utilities", icon: "UserCheck", route: "/passport-photo", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "content-aware-resize", name: "Content-Aware Resize", description: "Seam carving resize that preserves important content with face protection", category: "enhance", icon: "Scaling", route: "/content-aware-resize", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "ai-canvas-expand", name: "AI Canvas Expand", description: "Expand canvas with AI-powered fill", category: "enhance", icon: "Expand", route: "/ai-canvas-expand", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "transcribe-audio", name: "Transcribe Audio", description: "Convert speech to text with AI-powered transcription", category: "audio-convert", icon: "MicVocal", route: "/transcribe-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, outputModality: "file", executionHint: "long", }, { id: "auto-subtitles", name: "Auto Subtitles", description: "Generate subtitle files from video audio tracks", category: "video-subtitles", icon: "Captions", route: "/auto-subtitles", modality: "video", acceptedInputs: VIDEO_INPUTS, outputModality: "file", executionHint: "long", }, { id: "transparency-fixer", name: "PNG Transparency Fixer", description: "Fix fake transparent PNGs in one click", category: "enhance", icon: "ShieldCheck", route: "/transparency-fixer", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "background-replace", name: "Background Replace", description: "Replace image background with a solid color", category: "enhance", icon: "PaintBucket", route: "/background-replace", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, { id: "blur-background", name: "Blur Background", description: "Blur the background while keeping the subject sharp", category: "enhance", icon: "Focus", route: "/blur-background", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "long", }, // Watermark & Overlay { id: "watermark-text", name: "Text Watermark", description: "Add text watermark overlay", category: "watermark", icon: "Type", route: "/watermark-text", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "watermark-image", name: "Image Watermark", description: "Overlay a logo as watermark", category: "watermark", icon: "Image", route: "/watermark-image", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "text-overlay", name: "Text Overlay", description: "Add styled text to images", category: "watermark", icon: "TextCursorInput", route: "/text-overlay", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "compose", name: "Image Composition", description: "Layer images with position and opacity", category: "watermark", icon: "Layers", route: "/compose", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "meme-generator", name: "Meme Generator", description: "Create memes with templates and custom text", category: "watermark", icon: "Laugh", route: "/meme-generator", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, // Utilities { id: "info", name: "Image Info", description: "View all metadata and image properties", category: "utilities", icon: "Info", route: "/info", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "compare", name: "Image Compare", description: "Side-by-side comparison of two images", category: "utilities", icon: "Columns2", route: "/compare", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "find-duplicates", name: "Find Duplicates", description: "Detect duplicate and near-duplicate images", category: "utilities", icon: "Copy", route: "/find-duplicates", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "color-palette", name: "Color Palette", description: "Extract dominant colors from image", category: "utilities", icon: "Droplets", route: "/color-palette", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "qr-generate", name: "QR Code Generator", description: "Generate styled QR codes with custom colors, patterns, and logos", category: "utilities", icon: "QrCode", route: "/qr-generate", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "html-to-image", name: "HTML to Image", description: "Capture webpages as high-quality images", category: "utilities", icon: "Globe", route: "/html-to-image", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "barcode-read", name: "Barcode Reader", description: "Scan images for QR codes, barcodes, and 2D codes", category: "utilities", icon: "ScanLine", route: "/barcode-read", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "image-to-base64", name: "Image to Base64", description: "Convert images to base64 strings for embedding in HTML, CSS, and more", category: "utilities", icon: "Code", route: "/image-to-base64", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "barcode-generate", name: "Barcode Generator", description: "Generate barcodes in Code 128, EAN-13, UPC-A, Code 39, ITF-14, and Data Matrix", category: "utilities", icon: "Barcode", route: "/barcode-generate", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, // Layout & Composition { id: "collage", name: "Collage & Grid", description: "Combine images into beautiful grid collages with 25+ templates", category: "layout", icon: "LayoutGrid", route: "/collage", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "stitch", name: "Stitch Images", description: "Join images side by side, stacked, or in a grid", category: "layout", icon: "Columns2", route: "/stitch", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "split", name: "Split Image", description: "Split images into grid tiles or by pixel size with live preview", category: "layout", icon: "Grid3x3", route: "/split", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "border", name: "Border & Frame", description: "Add borders, rounded corners, shadows", category: "layout", icon: "Frame", route: "/border", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "beautify", name: "Beautify Screenshot", description: "Add gradient backgrounds, device frames, shadows, and social media sizing", category: "layout", icon: "ImagePlus", route: "/beautify", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "circle-crop", name: "Circle Crop", description: "Crop image to a centered circle with transparent corners", category: "layout", icon: "Circle", route: "/circle-crop", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "rounded-crop", name: "Rounded Crop", description: "Crop image to a rounded square or squircle with transparent corners", category: "layout", icon: "Squircle", route: "/rounded-crop", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", keywords: [ "rounded corners", "rounded square", "squircle", "favicon", "app icon", "logo", "avatar", "corner radius", ], }, { id: "duotone", name: "Duotone", description: "Apply a two-color duotone effect with custom shadow and highlight colors", category: "adjustments", icon: "Palette", route: "/duotone", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "image-pad", name: "Image Pad", description: "Pad image to a target aspect ratio with a solid color background", category: "layout", icon: "RectangleHorizontal", route: "/image-pad", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "pixelate", name: "Pixelate", description: "Apply a pixelation effect to the full image or a specific region", category: "adjustments", icon: "Grid2x2", route: "/pixelate", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "vignette", name: "Vignette", description: "Add a vignette effect with adjustable strength and color", category: "adjustments", icon: "Aperture", route: "/vignette", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "gif-webp", name: "GIF/WebP Converter", description: "Convert animated GIF to WebP and vice versa, preserving all frames", category: "format", icon: "Repeat", route: "/gif-webp", modality: "image", acceptedInputs: [".gif", ".webp"], executionHint: "fast", }, { id: "histogram", name: "Histogram", description: "Generate an RGB histogram chart from an image", category: "utilities", icon: "BarChart3", route: "/histogram", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "lqip-placeholder", name: "LQIP Placeholder", description: "Generate a tiny low-quality image placeholder with base64 data URI", category: "utilities", icon: "ImageDown", route: "/lqip-placeholder", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "sprite-sheet", name: "Sprite Sheet", description: "Combine multiple images into a single sprite sheet grid", category: "layout", icon: "Grid3x3", route: "/sprite-sheet", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, // Format & Conversion { id: "svg-to-raster", name: "SVG to Raster", description: "Convert SVG to PNG, JPEG, WebP, AVIF, TIFF, GIF, or HEIF at custom scale and DPI", category: "format", icon: "FileImage", route: "/svg-to-raster", modality: "image", acceptedInputs: [".svg", ".svgz"], executionHint: "fast", }, { id: "vectorize", name: "Image to SVG", description: "Vectorize images using tracing", category: "format", icon: "PenTool", route: "/vectorize", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "gif-tools", name: "GIF Tools", description: "Resize, optimize, change speed, reverse, extract frames, and rotate animated GIFs", category: "format", icon: "Film", route: "/gif-tools", modality: "image", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "pdf-to-image", name: "PDF to Image", description: "Convert PDF pages to images", category: "pdf-organize", icon: "BookImage", route: "/pdf-to-image", modality: "document", acceptedInputs: [".pdf"], outputModality: "image", executionHint: "fast", }, // Video { id: "convert-video", name: "Convert Video", description: "Convert videos between MP4, MOV, and WebM", category: "video-convert", icon: "Video", route: "/convert-video", modality: "video", acceptedInputs: VIDEO_INPUTS, keywords: ["video converter", "mov to mp4", "mkv to mp4", "avi to mp4", "webm to mp4"], executionHint: "long", }, { id: "compress-video", name: "Compress Video", description: "Shrink video file size with quality control", category: "video-convert", icon: "FileVideo", route: "/compress-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "long", }, { id: "trim-video", name: "Trim Video", description: "Cut a clip out of a video", category: "video-edit", icon: "Scissors", route: "/trim-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "mute-video", name: "Mute Video", description: "Remove the audio track from a video", category: "video-edit", icon: "VolumeX", route: "/mute-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "video-to-gif", name: "Video to GIF", description: "Turn a video clip into an animated GIF", category: "video-convert", icon: "Film", route: "/video-to-gif", modality: "video", acceptedInputs: VIDEO_INPUTS, outputModality: "image", executionHint: "long", }, { id: "resize-video", name: "Resize Video", description: "Scale a video to a new resolution or preset size", category: "video-edit", icon: "Scaling", route: "/resize-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "crop-video", name: "Crop Video", description: "Crop a region out of a video", category: "video-edit", icon: "Crop", route: "/crop-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "rotate-video", name: "Rotate Video", description: "Rotate or flip a video", category: "video-edit", icon: "RotateCw", route: "/rotate-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "change-fps", name: "Change FPS", description: "Change the frame rate of a video", category: "video-edit", icon: "Gauge", route: "/change-fps", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "video-color", name: "Video Color", description: "Adjust brightness, contrast, saturation, and gamma", category: "video-edit", icon: "SlidersHorizontal", route: "/video-color", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "video-speed", name: "Video Speed", description: "Speed up or slow down a video", category: "video-edit", icon: "FastForward", route: "/video-speed", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "reverse-video", name: "Reverse Video", description: "Play a video clip backwards", category: "video-edit", icon: "Rewind", route: "/reverse-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "video-loudnorm", name: "Normalize Video Audio", description: "Normalize video audio volume to broadcast standard", keywords: ["loudness", "loudnorm", "normalize audio", "broadcast"], category: "video-edit", icon: "Volume2", route: "/video-loudnorm", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "aspect-pad", name: "Aspect Pad", description: "Add solid-color bars to fit a target aspect ratio", category: "video-effects", icon: "RectangleHorizontal", route: "/aspect-pad", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "blur-pad", name: "Blur Pad", description: "Fill bars with a blurred copy of the video", category: "video-effects", icon: "GalleryHorizontalEnd", route: "/blur-pad", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "watermark-video", name: "Watermark Video", description: "Burn a text watermark onto video frames", category: "video-effects", icon: "Stamp", route: "/watermark-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, { id: "stabilize-video", name: "Stabilize Video", description: "Reduce camera shake with two-pass stabilization", category: "video-effects", icon: "Anchor", route: "/stabilize-video", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "long", }, { id: "gif-to-video", name: "GIF to Video", description: "Convert an animated GIF into an MP4 or WebM video", category: "video-convert", icon: "Film", route: "/gif-to-video", modality: "video", acceptedInputs: [".gif"], executionHint: "fast", }, { id: "video-to-webp", name: "Video to WebP", description: "Convert a video clip into an animated WebP image", category: "video-convert", icon: "Image", route: "/video-to-webp", modality: "video", acceptedInputs: VIDEO_INPUTS, outputModality: "image", executionHint: "fast", }, { id: "video-to-frames", name: "Video to Frames", description: "Extract frames from a video as a ZIP of images", category: "video-convert", icon: "Images", route: "/video-to-frames", modality: "video", acceptedInputs: VIDEO_INPUTS, outputModality: "file", executionHint: "fast", }, { id: "merge-videos", name: "Merge Videos", description: "Join multiple video clips into one file", category: "video-effects", icon: "Combine", route: "/merge-videos", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "long", }, { id: "replace-audio", name: "Replace Audio", description: "Swap the audio track of a video with another file", category: "video-effects", icon: "MicVocal", route: "/replace-audio", modality: "video", acceptedInputs: [...VIDEO_INPUTS, ...AUDIO_INPUTS], executionHint: "fast", }, { id: "burn-subtitles", name: "Burn Subtitles", description: "Permanently render subtitles onto video frames", category: "video-subtitles", icon: "Captions", route: "/burn-subtitles", modality: "video", acceptedInputs: [...VIDEO_INPUTS, ...SUBTITLE_INPUTS], executionHint: "long", }, { id: "embed-subtitles", name: "Embed Subtitles", description: "Mux a subtitle track into the video container", category: "video-subtitles", icon: "MessageSquareText", route: "/embed-subtitles", modality: "video", acceptedInputs: [...VIDEO_INPUTS, ...SUBTITLE_INPUTS], executionHint: "fast", }, { id: "extract-subtitles", name: "Extract Subtitles", description: "Pull the subtitle track out of a video as an SRT file", category: "video-subtitles", icon: "FileText", route: "/extract-subtitles", modality: "video", acceptedInputs: VIDEO_INPUTS, outputModality: "file", executionHint: "fast", }, { id: "images-to-video", name: "Images to Video", description: "Turn a set of images into a slideshow video", category: "video-effects", icon: "GalleryThumbnails", route: "/images-to-video", modality: "video", acceptedInputs: IMAGE_INPUTS, executionHint: "fast", }, { id: "video-metadata", name: "Clean Video Metadata", description: "Strip metadata from a video and report what was found", category: "video-metadata", icon: "Tags", route: "/video-metadata", modality: "video", acceptedInputs: VIDEO_INPUTS, executionHint: "fast", }, // Audio { id: "convert-audio", name: "Convert Audio", description: "Convert audio between MP3, WAV, OGG, and more", category: "audio-convert", icon: "AudioLines", route: "/convert-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, keywords: ["audio converter", "m4a to mp3", "aac to mp3", "wav to mp3", "ogg to mp3"], executionHint: "fast", }, { id: "trim-audio", name: "Trim Audio", description: "Cut a section out of an audio file", category: "audio-edit", icon: "Scissors", route: "/trim-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "extract-audio", name: "Extract Audio", description: "Pull the audio track out of a video", category: "audio-edit", icon: "FileAudio", route: "/extract-audio", modality: "video", acceptedInputs: VIDEO_INPUTS, outputModality: "audio", executionHint: "fast", }, { id: "volume-adjust", name: "Adjust Volume", description: "Increase or decrease audio volume by a fixed gain", category: "audio-edit", icon: "Volume2", route: "/volume-adjust", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "normalize-audio", name: "Normalize Audio", description: "Even out loudness to broadcast standard levels", category: "audio-edit", icon: "AudioWaveform", route: "/normalize-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "fade-audio", name: "Fade Audio", description: "Add fade-in and fade-out effects to audio", category: "audio-edit", icon: "Waves", route: "/fade-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "reverse-audio", name: "Reverse Audio", description: "Play audio backwards", category: "audio-edit", icon: "Rewind", route: "/reverse-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "audio-speed", name: "Audio Speed", description: "Speed up or slow down audio playback", category: "audio-edit", icon: "FastForward", route: "/audio-speed", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "pitch-shift", name: "Pitch Shift", description: "Raise or lower pitch by semitones without changing speed", category: "audio-edit", icon: "Music", route: "/pitch-shift", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "audio-channels", name: "Audio Channels", description: "Convert between mono, stereo, or swap left and right channels", category: "audio-edit", icon: "Split", route: "/audio-channels", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "silence-removal", name: "Silence Removal", description: "Strip silent sections from audio", category: "audio-edit", icon: "VolumeX", route: "/silence-removal", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "noise-reduction", name: "Noise Reduction", description: "Reduce background noise with FFT-based denoising", category: "audio-edit", icon: "Sparkles", route: "/noise-reduction", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "merge-audio", name: "Merge Audio", description: "Combine multiple audio files into one", category: "audio-effects", icon: "Combine", route: "/merge-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "split-audio", name: "Split Audio", description: "Split audio by time, equal parts, or silence detection", category: "audio-effects", icon: "Scissors", route: "/split-audio", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "ringtone-maker", name: "Ringtone Maker", description: "Create a ringtone clip from any audio file", category: "audio-convert", icon: "BellRing", route: "/ringtone-maker", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, { id: "waveform-image", name: "Waveform Image", description: "Generate a waveform visualization as a PNG image", category: "audio-effects", icon: "Activity", route: "/waveform-image", modality: "audio", acceptedInputs: AUDIO_INPUTS, outputModality: "image", executionHint: "fast", }, { id: "audio-metadata", name: "Audio Metadata", description: "View, edit, or strip audio tags (ID3)", category: "audio-metadata", icon: "Tags", route: "/audio-metadata", modality: "audio", acceptedInputs: AUDIO_INPUTS, executionHint: "fast", }, // PDF & Documents { id: "merge-pdf", name: "Merge PDFs", description: "Combine multiple PDFs into one", category: "pdf-organize", icon: "Combine", route: "/merge-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "split-pdf", name: "Split PDF", description: "Extract pages or split into parts", category: "pdf-organize", icon: "Split", route: "/split-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "compress-pdf", name: "Compress PDF", description: "Shrink PDF file size", category: "pdf-optimize", icon: "FileArchive", route: "/compress-pdf", modality: "document", acceptedInputs: [".pdf"], // "long": the target-size mode runs several ghostscript passes; async keeps // the request off the sync window and surfaces a real progress bar. executionHint: "long", }, { id: "rotate-pdf", name: "Rotate PDF", description: "Rotate pages in a PDF", category: "pdf-edit", icon: "RotateCw", route: "/rotate-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "convert-document", name: "Convert Document", description: "Convert between Word, OpenDocument, RTF, and plain text formats", category: "doc-convert", icon: "FileType2", route: "/convert-document", modality: "document", acceptedInputs: [".docx", ".doc", ".odt", ".rtf", ".txt"], executionHint: "long", }, { id: "convert-presentation", name: "Convert Presentation", description: "Convert between PowerPoint and OpenDocument presentation formats", category: "doc-convert", icon: "Presentation", route: "/convert-presentation", modality: "document", acceptedInputs: [".pptx", ".ppt", ".odp"], executionHint: "long", }, { id: "convert-spreadsheet", name: "Convert Spreadsheet", description: "Convert between Excel, OpenDocument, and CSV formats. Multi-sheet workbooks export the first sheet to CSV.", category: "doc-convert", icon: "Grid3x3", route: "/convert-spreadsheet", modality: "document", acceptedInputs: [".xlsx", ".xls", ".ods", ".csv"], keywords: ["excel to csv", "xlsx to csv", "spreadsheet converter"], executionHint: "long", }, { id: "excel-to-pdf", name: "Excel to PDF", description: "Convert spreadsheets to PDF. Wide sheets may paginate across multiple pages.", category: "doc-convert", icon: "Table", route: "/excel-to-pdf", modality: "document", acceptedInputs: [".xlsx", ".xls", ".ods", ".csv"], executionHint: "long", }, { id: "word-to-pdf", name: "Word to PDF", description: "Convert Word documents to PDF", category: "doc-convert", icon: "FileText", route: "/word-to-pdf", modality: "document", acceptedInputs: [".docx", ".doc", ".odt", ".rtf", ".txt"], executionHint: "long", }, { id: "extract-pages", name: "Extract Pages", description: "Pull selected pages into a new PDF", category: "pdf-organize", icon: "FileOutput", route: "/extract-pages", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "remove-pages", name: "Remove Pages", description: "Delete specific pages from a PDF", category: "pdf-organize", icon: "FileX", route: "/remove-pages", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "organize-pdf", name: "Organize PDF", description: "Reorder pages with an explicit page order", category: "pdf-organize", icon: "ListOrdered", route: "/organize-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "protect-pdf", name: "Protect PDF", description: "Add password protection (AES-256 encryption)", category: "pdf-security", icon: "Lock", route: "/protect-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "unlock-pdf", name: "Unlock PDF", description: "Remove password protection from a PDF", category: "pdf-security", icon: "LockOpen", route: "/unlock-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "repair-pdf", name: "Repair PDF", description: "Attempt to repair a damaged or corrupted PDF", category: "pdf-optimize", icon: "Wrench", route: "/repair-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "linearize-pdf", name: "Web-Optimize PDF", description: "Linearize a PDF for fast web viewing", category: "pdf-optimize", icon: "Zap", route: "/linearize-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "grayscale-pdf", name: "Grayscale PDF", description: "Convert all colors to grayscale", category: "pdf-optimize", icon: "Contrast", route: "/grayscale-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "pdfa-convert", name: "PDF/A Converter", description: "Convert to archival PDF/A-2", category: "pdf-optimize", icon: "Archive", route: "/pdfa-convert", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "crop-pdf", name: "Crop PDF", description: "Crop all pages with a uniform margin", category: "pdf-optimize", icon: "Crop", route: "/crop-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "nup-pdf", name: "Pages Per Sheet (N-up)", description: "Arrange multiple pages per sheet", keywords: ["nup", "n-up", "pages per sheet", "impose", "2-up", "4-up"], category: "pdf-optimize", icon: "LayoutGrid", route: "/nup-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "booklet-pdf", name: "Booklet PDF", description: "Arrange pages for folding into a booklet", category: "pdf-optimize", icon: "BookOpen", route: "/booklet-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "watermark-pdf", name: "Watermark PDF", description: "Add a text watermark to every page", category: "pdf-edit", icon: "Stamp", route: "/watermark-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "pdf-page-numbers", name: "PDF Page Numbers", description: "Add page numbers to every page", category: "pdf-edit", icon: "Hash", route: "/pdf-page-numbers", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "flatten-pdf", name: "Flatten PDF", description: "Bake forms and annotations into page content", category: "pdf-edit", icon: "Layers2", route: "/flatten-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "redact-pdf", name: "Redact PDF", description: "Permanently remove text occurrences (verified true redaction)", category: "pdf-edit", icon: "EyeOff", route: "/redact-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "sign-pdf", name: "Sign PDF", description: "Draw, type, or upload a signature and place it anywhere on a PDF", category: "pdf-edit", icon: "Signature", route: "/sign-pdf", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", keywords: ["sign", "signature", "e-sign", "esign", "fill and sign", "autograph"], }, { id: "pdf-to-text", name: "PDF to Text", description: "Extract plain text from a PDF", category: "doc-convert", icon: "FileText", route: "/pdf-to-text", modality: "document", acceptedInputs: [".pdf"], outputModality: "file", executionHint: "fast", }, { id: "pdf-to-word", name: "PDF to Word", description: "Best for text-based PDFs; scanned pages need OCR", category: "doc-convert", icon: "FileType", route: "/pdf-to-word", modality: "document", acceptedInputs: [".pdf"], executionHint: "long", }, { id: "pdf-metadata", name: "PDF Metadata", description: "Read and write PDF document metadata", category: "doc-convert", icon: "Tags", route: "/pdf-metadata", modality: "document", acceptedInputs: [".pdf"], executionHint: "fast", }, { id: "powerpoint-to-pdf", name: "PowerPoint to PDF", description: "Convert presentations to PDF", category: "doc-convert", icon: "Presentation", route: "/powerpoint-to-pdf", modality: "document", acceptedInputs: [".pptx", ".ppt", ".odp"], executionHint: "long", }, { id: "html-to-pdf", name: "HTML to PDF", description: "Convert an HTML file to PDF. Remote resources are disabled for privacy.", category: "doc-convert", icon: "FileCode", route: "/html-to-pdf", modality: "document", acceptedInputs: [".html", ".htm"], executionHint: "long", }, { id: "markdown-to-docx", name: "Markdown to Word", description: "Convert a Markdown file to a Word document (DOCX)", category: "doc-convert", icon: "FileType", route: "/markdown-to-docx", modality: "document", acceptedInputs: [".md", ".markdown"], executionHint: "fast", }, { id: "markdown-to-html", name: "Markdown to HTML", description: "Convert a Markdown file to a standalone HTML page. Remote images in the source are left as-is in the output.", category: "doc-convert", icon: "FileCode", route: "/markdown-to-html", modality: "document", acceptedInputs: [".md", ".markdown"], executionHint: "fast", }, { id: "markdown-to-pdf", name: "Markdown to PDF", description: "Convert a Markdown file to a styled PDF. Remote resources are disabled for privacy.", category: "doc-convert", icon: "FileCode2", route: "/markdown-to-pdf", modality: "document", acceptedInputs: [".md", ".markdown"], executionHint: "long", }, { id: "epub-convert", name: "Convert from EPUB", description: "Convert an EPUB to PDF, DOCX, HTML, or Markdown. Remote resources inside the book are not fetched.", category: "doc-convert", icon: "BookOpen", route: "/epub-convert", modality: "document", acceptedInputs: [".epub"], executionHint: "long", }, { id: "to-epub", name: "Convert to EPUB", description: "Convert Word, Markdown, HTML, or plain text files to EPUB", category: "doc-convert", icon: "Book", route: "/to-epub", modality: "document", acceptedInputs: [".docx", ".md", ".html", ".txt"], executionHint: "long", }, // Data Files { id: "chart-maker", name: "Chart Maker", description: "Create bar, line, or pie charts from CSV or JSON data", category: "data", icon: "BarChart3", route: "/chart-maker", modality: "file", acceptedInputs: [".csv", ".json"], outputModality: "image", executionHint: "fast", }, { id: "csv-excel", name: "CSV to Excel", description: "Convert between CSV and Excel (XLSX), both directions", category: "data", icon: "Table", route: "/csv-excel", modality: "file", acceptedInputs: [".csv", ".tsv", ".xlsx"], executionHint: "fast", }, { id: "csv-json", name: "CSV to JSON", description: "Convert between CSV and JSON, both directions", category: "data", icon: "Braces", route: "/csv-json", modality: "file", acceptedInputs: [".csv", ".tsv", ".json"], executionHint: "fast", }, { id: "json-xml", name: "JSON to XML", description: "Convert between JSON and XML, both directions", category: "data", icon: "Code", route: "/json-xml", modality: "file", acceptedInputs: [".json", ".xml"], executionHint: "fast", }, { id: "split-csv", name: "Split CSV", description: "Split a CSV into smaller files by row count", category: "data", icon: "Split", route: "/split-csv", modality: "file", acceptedInputs: [".csv", ".tsv"], executionHint: "fast", }, { id: "merge-csvs", name: "Merge CSVs", description: "Combine multiple CSV or TSV files with matching columns into one", category: "data", icon: "Combine", route: "/merge-csvs", modality: "file", acceptedInputs: [".csv", ".tsv"], executionHint: "fast", }, { id: "yaml-json", name: "Convert YAML / JSON", description: "Convert between YAML and JSON, both directions", category: "data", icon: "Braces", route: "/yaml-json", modality: "file", acceptedInputs: [".yaml", ".yml", ".json"], executionHint: "fast", }, { id: "xml-to-csv", name: "XML to CSV", description: "Extract repeating elements from XML into a CSV table", category: "data", icon: "Grid3x3", route: "/xml-to-csv", modality: "file", acceptedInputs: [".xml"], executionHint: "fast", }, // Archives { id: "create-zip", name: "Create ZIP", description: "Bundle multiple files into a single ZIP archive", category: "archives", icon: "FolderArchive", route: "/create-zip", modality: "file", acceptedInputs: [], executionHint: "fast", }, { id: "extract-zip", name: "Extract ZIP", description: "Safely extract files from a ZIP archive with bomb protection. Single-file archives return the file directly.", category: "archives", icon: "FolderOpen", route: "/extract-zip", modality: "file", acceptedInputs: [".zip"], executionHint: "fast", }, ]; export const TOOLS: Tool[] = [...BASE_TOOLS, ...expandConversionPresets(BASE_TOOLS)]; for (const tool of TOOLS) { const slug = `/${toolSection(tool)}`; if (!tool.route.startsWith(`${slug}/`)) { tool.route = `${slug}${tool.route}`; } } export function apiToolPath( toolOrId: string | Pick, ): string { const tool = typeof toolOrId === "string" ? TOOLS.find((t) => t.id === toolOrId) : toolOrId; if (!tool) throw new Error(`apiToolPath: unknown tool "${String(toolOrId)}"`); return `/api/v1/tools/${toolSection(tool)}/${tool.id}`; } export const SOCIAL_MEDIA_PRESETS: SocialMediaPreset[] = [ { platform: "Instagram", name: "Post (Square)", width: 1080, height: 1080 }, { platform: "Instagram", name: "Story / Reel", width: 1080, height: 1920 }, { platform: "Instagram", name: "Profile Picture", width: 320, height: 320 }, { platform: "Instagram", name: "Landscape Post", width: 1080, height: 566 }, { platform: "Instagram", name: "Portrait Post", width: 1080, height: 1350 }, { platform: "Twitter/X", name: "Post Image", width: 1200, height: 675 }, { platform: "Twitter/X", name: "Header", width: 1500, height: 500 }, { platform: "Twitter/X", name: "Profile Picture", width: 400, height: 400 }, { platform: "Facebook", name: "Post Image", width: 1200, height: 630 }, { platform: "Facebook", name: "Cover Photo", width: 820, height: 312 }, { platform: "Facebook", name: "Profile Picture", width: 170, height: 170 }, { platform: "Facebook", name: "Event Cover", width: 1920, height: 1005 }, { platform: "YouTube", name: "Thumbnail", width: 1280, height: 720 }, { platform: "YouTube", name: "Channel Banner", width: 2560, height: 1440 }, { platform: "YouTube", name: "Profile Picture", width: 800, height: 800 }, { platform: "LinkedIn", name: "Post Image", width: 1200, height: 627 }, { platform: "LinkedIn", name: "Banner", width: 1584, height: 396 }, { platform: "LinkedIn", name: "Profile Picture", width: 400, height: 400 }, { platform: "TikTok", name: "Video Cover", width: 1080, height: 1920 }, { platform: "TikTok", name: "Profile Picture", width: 200, height: 200 }, { platform: "WhatsApp", name: "Profile Picture", width: 500, height: 500 }, { platform: "Pinterest", name: "Pin", width: 1000, height: 1500 }, { platform: "Threads", name: "Post Image", width: 1080, height: 1080 }, ]; export interface SmartCropFacePreset { id: string; label: string; multiplier: number; } export const SMART_CROP_FACE_PRESETS: SmartCropFacePreset[] = [ { id: "closeup", label: "Close-up", multiplier: 1.8 }, { id: "head-shoulders", label: "Head & Shoulders", multiplier: 2.8 }, { id: "upper-body", label: "Upper Body", multiplier: 4.5 }, { id: "half-body", label: "Half Body", multiplier: 7.0 }, ]; // --------------------------------------------------------------------------- // Passport / ID Photo Specs // --------------------------------------------------------------------------- export type PassportRegion = "americas" | "europe" | "asia" | "africa" | "oceania" | "middle-east"; export interface PassportDocumentSpec { type: string; label: string; width: number; // mm height: number; // mm dpi: number; headHeightMin: number; // fraction of photo height headHeightMax: number; // fraction of photo height eyeLineFromBottom: number; // fraction of photo height bgColor: string; // default background hex bgColors: string[]; // allowed background colors } export interface PassportSpec { code: string; name: string; flag: string; region: PassportRegion; documents: PassportDocumentSpec[]; } export const PASSPORT_SPECS: PassportSpec[] = [ // Americas { code: "US", name: "United States", flag: "🇺🇸", region: "americas", documents: [ { type: "passport", label: "US Passport", width: 51, height: 51, dpi: 300, headHeightMin: 0.5, headHeightMax: 0.69, eyeLineFromBottom: 0.56, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "CA", name: "Canada", flag: "🇨🇦", region: "americas", documents: [ { type: "passport", label: "Canadian Passport", width: 50, height: 70, dpi: 300, headHeightMin: 0.44, headHeightMax: 0.51, eyeLineFromBottom: 0.55, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "BR", name: "Brazil", flag: "🇧🇷", region: "americas", documents: [ { type: "passport", label: "Brazilian Passport", width: 50, height: 70, dpi: 300, headHeightMin: 0.5, headHeightMax: 0.69, eyeLineFromBottom: 0.56, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "MX", name: "Mexico", flag: "🇲🇽", region: "americas", documents: [ { type: "passport", label: "Mexican Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, // Europe { code: "GB", name: "United Kingdom", flag: "🇬🇧", region: "europe", documents: [ { type: "passport", label: "UK Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#D4D4D4", bgColors: ["#D4D4D4"], }, ], }, { code: "EU", name: "European Union", flag: "🇪🇺", region: "europe", documents: [ { type: "passport", label: "EU Passport (ICAO)", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF", "#D4D4D4"], }, ], }, { code: "DE", name: "Germany", flag: "🇩🇪", region: "europe", documents: [ { type: "passport", label: "German Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#D4D4D4", bgColors: ["#D4D4D4"], }, ], }, { code: "FR", name: "France", flag: "🇫🇷", region: "europe", documents: [ { type: "passport", label: "French Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#D4D4D4", bgColors: ["#D4D4D4", "#BFDBFE"], }, ], }, { code: "RU", name: "Russia", flag: "🇷🇺", region: "europe", documents: [ { type: "passport", label: "Russian Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "TR", name: "Turkey", flag: "🇹🇷", region: "europe", documents: [ { type: "passport", label: "Turkish Passport", width: 50, height: 60, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "IE", name: "Ireland", flag: "\u{1F1EE}\u{1F1EA}", region: "europe", documents: [ { type: "passport", label: "Irish Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "IT", name: "Italy", flag: "\u{1F1EE}\u{1F1F9}", region: "europe", documents: [ { type: "passport", label: "Italian Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "ES", name: "Spain", flag: "\u{1F1EA}\u{1F1F8}", region: "europe", documents: [ { type: "passport", label: "Spanish Passport", width: 26, height: 32, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "NL", name: "Netherlands", flag: "\u{1F1F3}\u{1F1F1}", region: "europe", documents: [ { type: "passport", label: "Dutch Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "PL", name: "Poland", flag: "\u{1F1F5}\u{1F1F1}", region: "europe", documents: [ { type: "passport", label: "Polish Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "SE", name: "Sweden", flag: "\u{1F1F8}\u{1F1EA}", region: "europe", documents: [ { type: "passport", label: "Swedish Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, // Asia { code: "IN", name: "India", flag: "🇮🇳", region: "asia", documents: [ { type: "passport", label: "Indian Passport", width: 51, height: 51, dpi: 300, headHeightMin: 0.5, headHeightMax: 0.69, eyeLineFromBottom: 0.56, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "CN", name: "China", flag: "🇨🇳", region: "asia", documents: [ { type: "passport", label: "Chinese Passport", width: 33, height: 48, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "JP", name: "Japan", flag: "🇯🇵", region: "asia", documents: [ { type: "passport", label: "Japanese Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "KR", name: "South Korea", flag: "🇰🇷", region: "asia", documents: [ { type: "passport", label: "Korean Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "TH", name: "Thailand", flag: "🇹🇭", region: "asia", documents: [ { type: "passport", label: "Thai Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "PH", name: "Philippines", flag: "🇵🇭", region: "asia", documents: [ { type: "passport", label: "Philippine Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "ID", name: "Indonesia", flag: "🇮🇩", region: "asia", documents: [ { type: "passport", label: "Indonesian Passport", width: 30, height: 40, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#EF4444", bgColors: ["#EF4444"], }, ], }, { code: "SG", name: "Singapore", flag: "\u{1F1F8}\u{1F1EC}", region: "asia", documents: [ { type: "passport", label: "Singapore Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "MY", name: "Malaysia", flag: "\u{1F1F2}\u{1F1FE}", region: "asia", documents: [ { type: "passport", label: "Malaysian Passport", width: 35, height: 50, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "VN", name: "Vietnam", flag: "\u{1F1FB}\u{1F1F3}", region: "asia", documents: [ { type: "passport", label: "Vietnamese Passport", width: 40, height: 60, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "PK", name: "Pakistan", flag: "\u{1F1F5}\u{1F1F0}", region: "asia", documents: [ { type: "passport", label: "Pakistani Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF", "#BFDBFE"], }, ], }, { code: "BD", name: "Bangladesh", flag: "\u{1F1E7}\u{1F1E9}", region: "asia", documents: [ { type: "passport", label: "Bangladeshi Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, // Oceania { code: "AU", name: "Australia", flag: "🇦🇺", region: "oceania", documents: [ { type: "passport", label: "Australian Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "NZ", name: "New Zealand", flag: "\u{1F1F3}\u{1F1FF}", region: "oceania", documents: [ { type: "passport", label: "New Zealand Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, // Middle East { code: "SA", name: "Saudi Arabia", flag: "🇸🇦", region: "middle-east", documents: [ { type: "passport", label: "Saudi Passport", width: 40, height: 60, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "AE", name: "United Arab Emirates", flag: "\u{1F1E6}\u{1F1EA}", region: "middle-east", documents: [ { type: "passport", label: "UAE Passport", width: 43, height: 55, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, // Africa { code: "NG", name: "Nigeria", flag: "🇳🇬", region: "africa", documents: [ { type: "passport", label: "Nigerian Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "EG", name: "Egypt", flag: "\u{1F1EA}\u{1F1EC}", region: "africa", documents: [ { type: "passport", label: "Egyptian Passport", width: 40, height: 60, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, { code: "ZA", name: "South Africa", flag: "\u{1F1FF}\u{1F1E6}", region: "africa", documents: [ { type: "passport", label: "South African Passport", width: 35, height: 45, dpi: 300, headHeightMin: 0.7, headHeightMax: 0.8, eyeLineFromBottom: 0.63, bgColor: "#FFFFFF", bgColors: ["#FFFFFF"], }, ], }, ]; export interface PrintLayout { id: string; label: string; width: number; // mm height: number; // mm } export const PRINT_LAYOUTS: PrintLayout[] = [ { id: "4x6", label: "4x6 inch", width: 102, height: 152 }, { id: "a4", label: "A4", width: 210, height: 297 }, { id: "none", label: "None", width: 0, height: 0 }, ]; export const APP_VERSION = "2.1.0"; /** * Tool IDs that require the Python sidecar (AI/ML tools). * Used by the frontend for progress/timeout behavior. */ export const PYTHON_SIDECAR_TOOLS = [ "remove-background", "remove-gif-background", "upscale", "blur-faces", "erase-object", "ocr", "ocr-pdf", "colorize", "enhance-faces", "noise-removal", "smart-crop", "red-eye-removal", "restore-photo", "passport-photo", "transparency-fixer", "ai-canvas-expand", "transcribe-audio", "auto-subtitles", "background-replace", "blur-background", ] as const;