import { useState, useEffect, useCallback, useRef } from 'react'; import type { ExampleImage } from '../types'; import { fetchExamples, exampleImageUrl } from '../api'; interface Props { onFile: (file: File) => void; onExample: (name: string, hasCached: boolean) => void; } export default function ImageUpload({ onFile, onExample }: Props) { const [examples, setExamples] = useState([]); const [dragOver, setDragOver] = useState(false); const inputRef = useRef(null); useEffect(() => { fetchExamples() .then(setExamples) .catch(() => {}); }, []); const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); setDragOver(false); const file = e.dataTransfer.files[0]; if (file && file.type === 'image/png') { onFile(file); } }, [onFile], ); const handleFileSelect = useCallback( (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) onFile(file); }, [onFile], ); return (

Tesseract Floorplan Analyzer

Tesseract turns an annotated building floor plan into a navigable graph. It detects text labels, segments rooms and corridors, finds and classifies doors, and assembles a typed graph of rooms, corridors, doors, and floor transitions connected by walkable edges. Upload a floor plan or open an example to watch the pipeline run, explore the graph, route between any two rooms, and refine the result by hand.

{ e.preventDefault(); setDragOver(true); }} onDragLeave={() => setDragOver(false)} onDrop={handleDrop} onClick={() => inputRef.current?.click()} >
Drop a floorplan PNG here, or click to select
Maximum file size: 10 MB
{examples.length > 0 && (

Or try an example

{examples.map((ex) => (
onExample(ex.name, ex.has_cached_result)} > {ex.display_name}
{ex.display_name}
{ex.size_kb.toFixed(0)} KB {ex.has_cached_result && ( Instant )}
))}
)}
); }