{"version":3,"sources":["components/Button.tsx","components/FileSelect.tsx","utils.ts","adapters/inpainting.ts","components/Slider.tsx","Editor.tsx","App.tsx","index.tsx"],"names":["Button","props","children","className","disabled","icon","primary","onClick","onDown","onUp","useState","active","setActive","background","role","onKeyDown","onPointerDown","ev","nativeEvent","onPointerUp","tabIndex","join","FileSelect","onSelection","dragHover","setDragHover","Math","random","toString","uploadElemId","onFileSelected","file","type","match","size","Error","e","alert","message","getFile","entry","a","Promise","resolve","getAllFileEntries","items","fileEntries","queue","i","length","push","webkitGetAsEntry","shift","isFile","isDirectory","readAllDirectoryEntries","createReader","directoryReader","entries","readEntriesPromise","readEntries","reject","preventDefault","dataTransfer","htmlFor","onDrop","onDragOver","stopPropagation","onDragLeave","id","name","onChange","currentTarget","files","accept","dataURItoBlob","dataURI","mime","split","binary","atob","array","charCodeAt","Blob","Uint8Array","loadImage","image","src","initSRC","img","onload","onerror","err","resizeImageFile","maxSize","reader","FileReader","Image","canvas","document","createElement","readerEvent","width","height","resized","getContext","drawImage","blob","toDataURL","File","originalWidth","originalHeight","resize","target","result","readAsDataURL","API_ENDPOINT","process","inpaint","imageFile","maskBase64","fd","FormData","append","mask","fetch","method","body","then","r","res","URL","createObjectURL","Slider","value","label","min","max","step","parseInt","BRUSH_COLOR","drawLines","ctx","lines","color","strokeStyle","lineCap","lineJoin","forEach","line","pts","lineWidth","beginPath","moveTo","x","y","pt","lineTo","stroke","Editor","brushSize","setBrushSize","isLoaded","setIsLoaded","useEffect","useImage","original","isOriginalLoaded","renders","setRenders","context","setContext","maskCanvas","setLines","setCoords","showBrush","setShowBrush","showOriginal","setShowOriginal","isInpaintingLoading","setIsInpaintingLoading","showSeparator","setShowSeparator","scale","setScale","windowSize","useWindowSize","draw","useCallback","clearRect","currRender","currentLine","refreshCanvasMask","naturalWidth","naturalHeight","rW","rH","onMouseMove","pageX","pageY","onPaint","px","py","onMouseDrag","offsetX","offsetY","removeEventListener","window","Date","now","newRender","addEventListener","onTouchMove","currLine","coords","getBoundingClientRect","touches","clientX","clientY","onPointerStart","onmouseenter","onmouseleave","onmousedown","undo","l","pop","handler","event","metaKey","ctrlKey","key","style","undefined","transform","transformOrigin","cursor","ref","round","transitionProperty","transitionTimingFunction","transitionDuration","alt","maxWidth","left","top","viewBox","fill","xmlns","d","setTimeout","base64","uri","link","href","download","dispatchEvent","MouseEvent","bubbles","cancelable","view","remove","downloadImage","replace","App","setFile","f","resizedFile","ReactDOM","render","getElementById"],"mappings":"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","file":"static/js/main.56b43b57.chunk.js","sourcesContent":["import React, { ReactNode, useState } from 'react'\n\ninterface ButtonProps {\n children?: ReactNode\n className?: string\n icon?: ReactNode\n primary?: boolean\n disabled?: boolean\n onClick?: () => void\n onDown?: (ev: PointerEvent) => void\n onUp?: (ev: PointerEvent) => void\n}\n\nexport default function Button(props: ButtonProps) {\n const {\n children,\n className,\n disabled,\n icon,\n primary,\n onClick,\n onDown,\n onUp,\n } = props\n const [active, setActive] = useState(false)\n let background = ''\n if (primary && !disabled) {\n background = 'bg-primary hover:bg-black hover:text-white'\n }\n if (active) {\n background = 'bg-black text-white'\n }\n if (!primary && !active) {\n background = 'hover:bg-primary'\n }\n return (\n ) => {\n setActive(true)\n onDown?.(ev.nativeEvent)\n }}\n onPointerUp={(ev: React.PointerEvent) => {\n setActive(false)\n onUp?.(ev.nativeEvent)\n }}\n tabIndex={-1}\n className={[\n 'inline-flex py-3 px-5 rounded-md cursor-pointer',\n children ? 'space-x-3' : '',\n background,\n disabled ? 'pointer-events-none opacity-50' : '',\n className,\n ].join(' ')}\n >\n {icon}\n {children}\n \n )\n}\n","import React, { useState } from 'react'\n\ntype FileSelectProps = {\n onSelection: (file: File) => void\n}\n\nexport default function FileSelect(props: FileSelectProps) {\n const { onSelection } = props\n\n const [dragHover, setDragHover] = useState(false)\n const [uploadElemId] = useState(`file-upload-${Math.random().toString()}`)\n\n function onFileSelected(file: File) {\n if (!file) {\n return\n }\n // Skip non-image files\n const isImage = file.type.match('image.*')\n if (!isImage) {\n return\n }\n try {\n // Check if file is larger than 20mb\n if (file.size > 20 * 1024 * 1024) {\n throw new Error('file too large')\n }\n onSelection(file)\n } catch (e) {\n // eslint-disable-next-line\n alert(`error: ${(e as any).message}`)\n }\n }\n\n async function getFile(entry: any): Promise {\n return new Promise(resolve => {\n entry.file((file: File) => resolve(file))\n })\n }\n\n /* eslint-disable no-await-in-loop */\n\n // Drop handler function to get all files\n async function getAllFileEntries(items: DataTransferItemList) {\n const fileEntries: Array = []\n // Use BFS to traverse entire directory/file structure\n const queue = []\n // Unfortunately items is not iterable i.e. no forEach\n for (let i = 0; i < items.length; i += 1) {\n queue.push(items[i].webkitGetAsEntry())\n }\n while (queue.length > 0) {\n const entry = queue.shift()\n if (entry?.isFile) {\n // Only append images\n const file = await getFile(entry)\n fileEntries.push(file)\n } else if (entry?.isDirectory) {\n queue.push(\n ...(await readAllDirectoryEntries((entry as any).createReader()))\n )\n }\n }\n return fileEntries\n }\n\n // Get all the entries (files or sub-directories) in a directory\n // by calling readEntries until it returns empty array\n async function readAllDirectoryEntries(directoryReader: any) {\n const entries = []\n let readEntries = await readEntriesPromise(directoryReader)\n while (readEntries.length > 0) {\n entries.push(...readEntries)\n readEntries = await readEntriesPromise(directoryReader)\n }\n return entries\n }\n\n /* eslint-enable no-await-in-loop */\n\n // Wrap readEntries in a promise to make working with readEntries easier\n // readEntries will return only some of the entries in a directory\n // e.g. Chrome returns at most 100 entries at a time\n async function readEntriesPromise(directoryReader: any): Promise {\n return new Promise((resolve, reject) => {\n directoryReader.readEntries(resolve, reject)\n })\n }\n\n async function handleDrop(ev: React.DragEvent) {\n ev.preventDefault()\n const items = await getAllFileEntries(ev.dataTransfer.items)\n setDragHover(false)\n onFileSelected(items[0])\n }\n\n return (\n \n {\n ev.stopPropagation()\n ev.preventDefault()\n setDragHover(true)\n }}\n onDragLeave={() => setDragHover(false)}\n >\n {\n const file = ev.currentTarget.files?.[0]\n if (file) {\n onFileSelected(file)\n }\n }}\n accept=\"image/png, image/jpeg\"\n />\n

Click here or drag an image file

\n

Tap here to load your picture

\n \n \n )\n}\n","import { useEffect, useState } from 'react'\n\nexport function dataURItoBlob(dataURI: string) {\n const mime = dataURI.split(',')[0].split(':')[1].split(';')[0]\n const binary = atob(dataURI.split(',')[1])\n const array = []\n for (let i = 0; i < binary.length; i += 1) {\n array.push(binary.charCodeAt(i))\n }\n return new Blob([new Uint8Array(array)], { type: mime })\n}\n\n// const dataURItoBlob = (dataURI: string) => {\n// const bytes =\n// dataURI.split(',')[0].indexOf('base64') >= 0\n// ? atob(dataURI.split(',')[1])\n// : unescape(dataURI.split(',')[1])\n// const mime = dataURI.split(',')[0].split(':')[1].split(';')[0]\n// const max = bytes.length\n// const ia = new Uint8Array(max)\n// for (var i = 0; i < max; i++) ia[i] = bytes.charCodeAt(i)\n// return new Blob([ia], { type: mime })\n// }\n\nexport function downloadImage(uri: string, name: string) {\n const link = document.createElement('a')\n link.href = uri\n link.download = name\n\n // this is necessary as link.click() does not work on the latest firefox\n link.dispatchEvent(\n new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n view: window,\n })\n )\n\n setTimeout(() => {\n // For Firefox it is necessary to delay revoking the ObjectURL\n // window.URL.revokeObjectURL(base64)\n link.remove()\n }, 100)\n}\n\nexport function shareImage(base64: string, name: string) {\n const blob = dataURItoBlob(base64)\n const filesArray = [new File([blob], name, { type: 'image/jpeg' })]\n const shareData = {\n files: filesArray,\n }\n // eslint-disable-nextline\n const nav: any = navigator\n const canShare = nav.canShare && nav.canShare(shareData)\n const userAgent = navigator.userAgent || navigator.vendor\n const isMobile = /android|iPad|iPhone|iPod/i.test(userAgent)\n if (canShare && isMobile) {\n navigator.share(shareData)\n return true\n }\n return false\n}\n\nexport function loadImage(image: HTMLImageElement, src: string) {\n return new Promise((resolve, reject) => {\n const initSRC = image.src\n const img = image\n img.onload = resolve\n img.onerror = err => {\n img.src = initSRC\n reject(err)\n }\n img.src = src\n })\n}\n\nexport function useImage(file: File): [HTMLImageElement, boolean] {\n const [image] = useState(new Image())\n const [isLoaded, setIsLoaded] = useState(false)\n\n useEffect(() => {\n image.onload = () => {\n setIsLoaded(true)\n }\n setIsLoaded(false)\n image.src = URL.createObjectURL(file)\n return () => {\n image.onload = null\n }\n }, [file, image])\n\n return [image, isLoaded]\n}\n\n// https://stackoverflow.com/questions/23945494/use-html5-to-resize-an-image-before-upload\ninterface ResizeImageFileResult {\n file: File\n resized: boolean\n originalWidth?: number\n originalHeight?: number\n}\nexport function resizeImageFile(\n file: File,\n maxSize: number\n): Promise {\n const reader = new FileReader()\n const image = new Image()\n const canvas = document.createElement('canvas')\n\n const resize = (): ResizeImageFileResult => {\n let { width, height } = image\n\n if (width > height) {\n if (width > maxSize) {\n height *= maxSize / width\n width = maxSize\n }\n } else if (height > maxSize) {\n width *= maxSize / height\n height = maxSize\n }\n\n if (width === image.width && height === image.height) {\n return { file, resized: false }\n }\n\n canvas.width = width\n canvas.height = height\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('could not get context')\n }\n canvas.getContext('2d')?.drawImage(image, 0, 0, width, height)\n const dataUrl = canvas.toDataURL('image/jpeg')\n const blob = dataURItoBlob(dataUrl)\n const f = new File([blob], file.name, {\n type: file.type,\n })\n return {\n file: f,\n resized: true,\n originalWidth: image.width,\n originalHeight: image.height,\n }\n }\n\n return new Promise((resolve, reject) => {\n if (!file.type.match(/image.*/)) {\n reject(new Error('Not an image'))\n return\n }\n reader.onload = (readerEvent: any) => {\n image.onload = () => resolve(resize())\n image.src = readerEvent.target.result\n }\n reader.readAsDataURL(file)\n })\n}\n","import { dataURItoBlob } from '../utils'\n\nexport const API_ENDPOINT = `${process.env.REACT_APP_INPAINTING_URL}/inpaint`\n\nexport default async function inpaint(imageFile: File, maskBase64: string) {\n const fd = new FormData()\n fd.append('image', imageFile)\n const mask = dataURItoBlob(maskBase64)\n fd.append('mask', mask)\n\n const res = await fetch(API_ENDPOINT, {\n method: 'POST',\n body: fd,\n }).then(async r => {\n return r.blob()\n })\n\n return URL.createObjectURL(res)\n}\n","import React from 'react'\n\ntype SliderProps = {\n label?: any\n value?: number\n min?: number\n max?: number\n onChange: (value: number) => void\n}\n\nexport default function Slider(props: SliderProps) {\n const { value, onChange, label, min, max } = props\n\n const step = ((max || 100) - (min || 0)) / 100\n\n return (\n
\n {label}\n {\n ev.preventDefault()\n ev.stopPropagation()\n onChange(parseInt(ev.currentTarget.value, 10))\n }}\n />\n
\n )\n}\n","import { DownloadIcon, EyeIcon } from '@heroicons/react/outline'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { useWindowSize } from 'react-use'\nimport inpaint from './adapters/inpainting'\nimport Button from './components/Button'\nimport Slider from './components/Slider'\nimport { downloadImage, loadImage, shareImage, useImage } from './utils'\n\nconst TOOLBAR_SIZE = 200\nconst BRUSH_COLOR = 'rgba(189, 255, 1, 0.75)'\n\ninterface EditorProps {\n file: File\n}\n\ninterface Line {\n size?: number\n pts: { x: number; y: number }[]\n}\n\nfunction drawLines(\n ctx: CanvasRenderingContext2D,\n lines: Line[],\n color = BRUSH_COLOR\n) {\n ctx.strokeStyle = color\n ctx.lineCap = 'round'\n ctx.lineJoin = 'round'\n\n lines.forEach(line => {\n if (!line?.pts.length || !line.size) {\n return\n }\n ctx.lineWidth = line.size\n ctx.beginPath()\n ctx.moveTo(line.pts[0].x, line.pts[0].y)\n line.pts.forEach(pt => ctx.lineTo(pt.x, pt.y))\n ctx.stroke()\n })\n}\n\nexport default function Editor(props: EditorProps) {\n const { file } = props\n const [brushSize, setBrushSize] = useState(40)\n const [original, isOriginalLoaded] = useImage(file)\n const [renders, setRenders] = useState([])\n const [context, setContext] = useState()\n const [maskCanvas] = useState(() => {\n return document.createElement('canvas')\n })\n const [lines, setLines] = useState([{ pts: [] }])\n const [{ x, y }, setCoords] = useState({ x: -1, y: -1 })\n const [showBrush, setShowBrush] = useState(false)\n const [showOriginal, setShowOriginal] = useState(false)\n const [isInpaintingLoading, setIsInpaintingLoading] = useState(false)\n const [showSeparator, setShowSeparator] = useState(false)\n const [scale, setScale] = useState(1)\n const windowSize = useWindowSize()\n\n const draw = useCallback(() => {\n if (!context) {\n return\n }\n context.clearRect(0, 0, context.canvas.width, context.canvas.height)\n const currRender = renders[renders.length - 1]\n if (currRender?.src) {\n context.drawImage(currRender, 0, 0)\n } else {\n context.drawImage(original, 0, 0)\n }\n const currentLine = lines[lines.length - 1]\n drawLines(context, [currentLine])\n }, [context, lines, original, renders])\n\n const refreshCanvasMask = useCallback(() => {\n if (!context?.canvas.width || !context?.canvas.height) {\n throw new Error('canvas has invalid size')\n }\n maskCanvas.width = context?.canvas.width\n maskCanvas.height = context?.canvas.height\n const ctx = maskCanvas.getContext('2d')\n if (!ctx) {\n throw new Error('could not retrieve mask canvas')\n }\n drawLines(ctx, lines, 'white')\n }, [context?.canvas.height, context?.canvas.width, lines, maskCanvas])\n\n // Draw once the original image is loaded\n useEffect(() => {\n if (!context?.canvas) {\n return\n }\n if (isOriginalLoaded) {\n context.canvas.width = original.naturalWidth\n context.canvas.height = original.naturalHeight\n const rW = windowSize.width / original.naturalWidth\n const rH = (windowSize.height - TOOLBAR_SIZE) / original.naturalHeight\n if (rW < 1 || rH < 1) {\n setScale(Math.min(rW, rH))\n } else {\n setScale(1)\n }\n draw()\n }\n }, [context?.canvas, draw, original, isOriginalLoaded, windowSize])\n\n // Handle mouse interactions\n useEffect(() => {\n const canvas = context?.canvas\n if (!canvas) {\n return\n }\n\n const onMouseDown = (ev: MouseEvent) => {\n if (!original.src) {\n return\n }\n const currLine = lines[lines.length - 1]\n currLine.size = brushSize\n canvas.addEventListener('mousemove', onMouseDrag)\n window.addEventListener('mouseup', onPointerUp)\n onPaint(ev.offsetX, ev.offsetY)\n }\n const onMouseMove = (ev: MouseEvent) => {\n setCoords({ x: ev.pageX, y: ev.pageY })\n }\n const onPaint = (px: number, py: number) => {\n const currLine = lines[lines.length - 1]\n currLine.pts.push({ x: px, y: py })\n draw()\n }\n const onMouseDrag = (ev: MouseEvent) => {\n const px = ev.offsetX\n const py = ev.offsetY\n onPaint(px, py)\n }\n\n const onPointerUp = async () => {\n if (!original.src) {\n return\n }\n setIsInpaintingLoading(true)\n canvas.removeEventListener('mousemove', onMouseDrag)\n window.removeEventListener('mouseup', onPointerUp)\n refreshCanvasMask()\n try {\n const start = Date.now()\n const res = await inpaint(file, maskCanvas.toDataURL())\n if (!res) {\n throw new Error('empty response')\n }\n // TODO: fix the render if it failed loading\n const newRender = new Image()\n await loadImage(newRender, res)\n renders.push(newRender)\n lines.push({ pts: [] } as Line)\n\n setRenders([...renders])\n setLines([...lines])\n } catch (e: any) {\n // eslint-disable-next-line\n alert(e.message ? e.message : e.toString())\n }\n setIsInpaintingLoading(false)\n draw()\n }\n window.addEventListener('mousemove', onMouseMove)\n\n const onTouchMove = (ev: TouchEvent) => {\n ev.preventDefault()\n ev.stopPropagation()\n const currLine = lines[lines.length - 1]\n const coords = canvas.getBoundingClientRect()\n currLine.pts.push({\n x: (ev.touches[0].clientX - coords.x) / scale,\n y: (ev.touches[0].clientY - coords.y) / scale,\n })\n draw()\n }\n const onPointerStart = (ev: TouchEvent) => {\n if (!original.src) {\n return\n }\n const currLine = lines[lines.length - 1]\n currLine.size = brushSize\n canvas.addEventListener('mousemove', onMouseDrag)\n window.addEventListener('mouseup', onPointerUp)\n const coords = canvas.getBoundingClientRect()\n const px = (ev.touches[0].clientX - coords.x) / scale\n const py = (ev.touches[0].clientY - coords.y) / scale\n onPaint(px, py)\n }\n canvas.addEventListener('touchstart', onPointerStart)\n canvas.addEventListener('touchmove', onTouchMove)\n canvas.addEventListener('touchend', onPointerUp)\n canvas.onmouseenter = () => setShowBrush(true)\n canvas.onmouseleave = () => setShowBrush(false)\n canvas.onmousedown = onMouseDown\n\n return () => {\n canvas.removeEventListener('mousemove', onMouseDrag)\n window.removeEventListener('mousemove', onMouseMove)\n window.removeEventListener('mouseup', onPointerUp)\n canvas.removeEventListener('touchstart', onPointerStart)\n canvas.removeEventListener('touchmove', onTouchMove)\n canvas.removeEventListener('touchend', onPointerUp)\n canvas.onmouseenter = null\n canvas.onmouseleave = null\n canvas.onmousedown = null\n }\n }, [\n brushSize,\n context,\n file,\n draw,\n lines,\n refreshCanvasMask,\n maskCanvas,\n original.src,\n renders,\n original.naturalHeight,\n original.naturalWidth,\n scale,\n ])\n\n const undo = useCallback(() => {\n const l = lines\n l.pop()\n l.pop()\n setLines([...l, { pts: [] }])\n const r = renders\n r.pop()\n setRenders([...r])\n }, [lines, renders])\n\n // Handle Cmd+Z\n useEffect(() => {\n const handler = (event: KeyboardEvent) => {\n if (!renders.length) {\n return\n }\n const isCmdZ = (event.metaKey || event.ctrlKey) && event.key === 'z'\n if (isCmdZ) {\n event.preventDefault()\n undo()\n }\n }\n window.addEventListener('keydown', handler)\n return () => {\n window.removeEventListener('keydown', handler)\n }\n }, [renders, undo])\n\n function download() {\n const base64 = context?.canvas.toDataURL(file.type)\n if (!base64) {\n throw new Error('could not get canvas data')\n }\n const name = file.name.replace(/(\\.[\\w\\d_-]+)$/i, '_cleanup$1')\n downloadImage(base64, name)\n }\n\n return (\n \n \n {\n if (r && !context) {\n const ctx = r.getContext('2d')\n if (ctx) {\n setContext(ctx)\n }\n }\n }}\n />\n \n \n \n \n\n {showBrush && (\n \n )}\n\n \n \n Brush Size\n \n }\n min={10}\n max={150}\n value={brushSize}\n onChange={setBrushSize}\n />\n {renders.length ? (\n <>\n \n \n \n }\n onClick={undo}\n />\n }\n onDown={ev => {\n ev.preventDefault()\n setShowSeparator(true)\n setShowOriginal(true)\n }}\n onUp={() => {\n setShowOriginal(false)\n setTimeout(() => setShowSeparator(false), 300)\n }}\n >\n {windowSize.width > 640 ? 'Original' : undefined}\n \n \n ) : (\n <>\n )}\n\n }\n disabled={!renders.length}\n onClick={download}\n >\n {windowSize.width > 640 ? 'Download' : undefined}\n \n \n \n )\n}\n","import { ArrowLeftIcon } from '@heroicons/react/outline'\nimport React, { useState } from 'react'\nimport { useWindowSize } from 'react-use'\nimport Button from './components/Button'\nimport FileSelect from './components/FileSelect'\nimport Editor from './Editor'\nimport { resizeImageFile } from './utils'\n\nfunction App() {\n const [file, setFile] = useState()\n const windowSize = useWindowSize()\n\n return (\n
\n
\n {file ? (\n }\n onClick={() => {\n setFile(undefined)\n }}\n >\n {windowSize.width > 640 ? 'Start new' : undefined}\n \n ) : (\n <>\n )}\n
\n\n \n {file ? (\n \n ) : (\n <>\n \n
\n

\n Image inpainting powered by 🦙\n \n LaMa\n \n

\n
\n
\n\n \n {\n const {\n file: resizedFile,\n resized,\n originalWidth,\n originalHeight,\n } = await resizeImageFile(f, 1024)\n setFile(resizedFile)\n }}\n />\n \n \n )}\n \n \n )\n}\n\nexport default App\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport './styles/index.css'\nimport App from './App'\n\nReactDOM.render(, document.getElementById('root'))\n"],"sourceRoot":""}