{"version":3,"file":"69676638855d2e6ef57431ac44fa0b6b80faa336-6c4ed1ef2e1929c2691d.js","mappings":"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","sources":["webpack://fluffle/./src/components/banner.tsx","webpack://fluffle/./src/components/gallery-thumbnail.module.scss","webpack://fluffle/./src/components/gallery-thumbnail.tsx","webpack://fluffle/./src/components/progress-bar-part.module.scss","webpack://fluffle/./src/components/progress-bar-part.tsx","webpack://fluffle/./src/components/progress-bar.tsx","webpack://fluffle/./src/services/gallery.ts","webpack://fluffle/./src/components/search-result-desktop.tsx","webpack://fluffle/./src/services/search-config.ts","webpack://fluffle/./src/components/search-result-mobile.tsx","webpack://fluffle/./src/pages/index.module.scss","webpack://fluffle/./src/pages/index.tsx","webpack://fluffle/./node_modules/@babel/runtime/helpers/esm/createClass.js"],"sourcesContent":["import * as React from 'react'\nimport svg from '../services/svg'\n\nconst Banner = () => {\n return (\n \"Fluffle\n )\n}\n\nexport default Banner","// extracted by mini-css-extract-plugin\nexport var galleryThumbnail = \"gallery-thumbnail-module--gallery-thumbnail--LkmK5\";\nexport var blur = \"gallery-thumbnail-module--blur--qVN0H\";\nexport var skeleton = \"gallery-thumbnail-module--skeleton--PeWDl\";\nexport var Skeleton = \"gallery-thumbnail-module--Skeleton--nver1\";","import * as React from 'react'\nimport { galleryThumbnail, blur, skeleton } from './gallery-thumbnail.module.scss'\nimport { SearchResultThumbnail } from '../services/api'\nimport classNames from 'classnames';\n\ninterface GalleryThumbnailProps {\n thumbnail: SearchResultThumbnail,\n hasBlur: boolean\n}\n\nconst GalleryThumbnail = ({ thumbnail, hasBlur }: GalleryThumbnailProps) => {\n const [hasBeenLoaded, setHasBeenLoaded] = React.useState(false);\n const [error, setError] = React.useState(null);\n\n function load(element: HTMLImageElement) {\n if (element == null) return;\n\n const image = new Image();\n image.onload = () => {\n element.src = image.src;\n setHasBeenLoaded(true);\n setError(null);\n };\n\n image.onerror = () => {\n setError('Fluffle offline');\n };\n\n image.src = thumbnail.location;\n }\n\n return (\n
\n load(element)} />\n
\n {error}\n
\n
\n
\n )\n}\n\nexport default GalleryThumbnail\n","// extracted by mini-css-extract-plugin\nexport var progressBar = \"progress-bar-part-module--progress-bar--7kGtk\";\nexport var progressBarStriped = \"progress-bar-part-module--progress-bar-striped--QRFI4\";\nexport var progressBarAnimated = \"progress-bar-part-module--progress-bar-animated--EaAjm\";\nexport var progressBarStripes = \"progress-bar-part-module--progress-bar-stripes--+d4Bi\";","import classNames from 'classnames'\nimport * as React from 'react'\nimport { progressBar, progressBarStriped, progressBarAnimated } from './progress-bar-part.module.scss'\n\ninterface ProgressBarProps {\n color: string;\n percentage: number;\n isStriped: boolean;\n isAnimated: boolean;\n}\n\nconst ProgressBarPart = ({ color, percentage, isStriped, isAnimated }: ProgressBarProps) => {\n const classes = [\n progressBar,\n ...isStriped ? [progressBarStriped] : [],\n ...isAnimated ? [progressBarAnimated] : [],\n color\n ]\n\n return (\n
\n )\n}\n\nProgressBarPart.defaultProps = {\n isStriped: false,\n isAnimated: false\n}\n\nexport default ProgressBarPart\n","import * as React from 'react'\n\nconst ProgressBar = ({ children }) => {\n return (\n
\n
\n {children}\n
\n
\n )\n}\n\nexport default ProgressBar\n","export class Gallery {\n images: GalleryImage[] = [];\n\n constructor(private _targetHeight: number, private _maximumHeight: number) {\n }\n\n set targetHeight(targetHeight: number) {\n this._targetHeight = targetHeight;\n }\n\n public addImage(width: number, height: number, data: any = null) {\n this.images.push(new GalleryImage(width, height, data));\n }\n\n public clear() {\n this.images = [];\n }\n\n public render(targetWidth: number, targetMargin: number, shouldFit: boolean = true): GalleryRow[] {\n let rows: GalleryRow[] = [];\n\n let row = new GalleryRow(targetWidth, this._targetHeight, this._maximumHeight, targetMargin)\n for (let image of this.images) {\n if (!row.tryAddImage(image)) {\n rows.push(row);\n\n row = new GalleryRow(targetWidth, this._targetHeight, this._maximumHeight, targetMargin);\n row.tryAddImage(image);\n }\n }\n\n // Add the final row if it isn't empty\n if (row.any()) {\n rows.push(row);\n }\n\n if (shouldFit) {\n for (let row of rows) {\n row.fit();\n }\n }\n\n if (rows.length > 0) {\n rows[rows.length - 1].isLast = true;\n }\n\n return rows;\n }\n}\n\nexport class GalleryRow {\n public images: GalleryRowImage[] = [];\n public couldFit: boolean;\n\n constructor(private _targetWidth: number, private _targetHeight: number,\n private _maximumHeight: number, private _targetMargin: number, public isLast: boolean = false) {\n }\n\n public tryAddImage(image: GalleryImage): boolean {\n if (!this.hasSpaceFor(image)) {\n return false;\n }\n\n this.images.push(new GalleryRowImage(this.calculateTheoreticalSpaceTaken(image), this._targetHeight, image.aspectRatio, image.data));\n\n return true;\n }\n\n public calculateTheoreticalSpaceTakenIncludingMargin(image: GalleryImage): number {\n let imageWidth = this.calculateTheoreticalSpaceTaken(image);\n let spaceTakenByImageWithMargin = imageWidth + (this._targetMargin * 2);\n\n if (spaceTakenByImageWithMargin > this._targetWidth) {\n return this._targetWidth;\n }\n\n return spaceTakenByImageWithMargin;\n }\n\n public calculateTheoreticalSpaceTaken(image: GalleryImage): number {\n return Math.round(image.aspectRatio * this._targetHeight);\n }\n\n public any(): boolean {\n return this.images.length > 0;\n }\n\n public hasSpaceFor(image: GalleryImage): boolean {\n let spaceTaken = this.calculateSpaceTaken();\n let spaceTakenByImage = this.calculateTheoreticalSpaceTakenIncludingMargin(image);\n let newWidth = spaceTaken + spaceTakenByImage;\n\n return newWidth <= this._targetWidth\n }\n\n public calculateSpaceLeft(): number {\n let spaceTakenInRow = this.calculateSpaceTaken();\n\n return this._targetWidth - spaceTakenInRow;\n }\n\n public fit() {\n this.couldFit = true;\n\n let spaceLeft = this.calculateSpaceLeft();\n\n let totalAspectRatio = 0;\n for (let image of this.images) {\n totalAspectRatio += image.aspectRatio;\n }\n\n for (let image of this.images) {\n let fractionOfTotalAspectRatio = image.aspectRatio / totalAspectRatio;\n let extraWidth = fractionOfTotalAspectRatio * spaceLeft;\n let widthIncreaseFactor = extraWidth / image.width;\n\n extraWidth = Math.floor(extraWidth)\n let extraHeight = Math.floor(widthIncreaseFactor * image.height);\n\n if (image.height + extraHeight >= this._maximumHeight) {\n this.fitMaximumHeight();\n\n let percentageLeft = this.calculateSpaceLeft() / this._targetWidth * 100;\n this.couldFit = percentageLeft <= 10;\n break;\n }\n\n image.width += extraWidth;\n image.height += extraHeight;\n }\n }\n\n private fitMaximumHeight() {\n let growFactor = this._maximumHeight / this._targetHeight;\n\n for (let image of this.images) {\n image.width = Math.floor(image.width * growFactor);\n image.height = this._maximumHeight;\n }\n }\n\n public calculateSpaceTaken(): number {\n let width = 0;\n\n for (let image of this.images) {\n width += image.width;\n }\n\n if (this.images.length > 1) {\n // The two images on the side don't require any margin from its parent. We need to remove that\n let margin = (this.images.length * 2 - 2) * this._targetMargin;\n\n width += margin\n }\n\n return width;\n }\n}\n\nexport class GalleryImage {\n constructor(public width: number, public height: number, public data: TSrc) {\n }\n\n get aspectRatio(): number {\n return this.width / this.height;\n }\n}\n\nexport class GalleryRowImage {\n constructor(public width: number, public height: number, public aspectRatio: number, public data: TSrc) {\n }\n}\n","import * as React from 'react'\nimport { SearchResult, SearchResultItem } from '../services/api'\nimport { Gallery, GalleryRow, GalleryRowImage } from '../services/gallery'\nimport GalleryThumbnail from './gallery-thumbnail'\nimport Icon from './icon'\n\nconst GalleryDesktopCard = ({ image, shouldBlur }: { image: GalleryRowImage, shouldBlur: boolean }) => {\n const [hasHover, setHasHover] = React.useState(false);\n\n return (\n setHasHover(true)} onMouseLeave={() => setHasHover(false)} className=\"relative rounded overflow-hidden select-none force-light-100\" style={{ width: image.width, height: image.height }}>\n
\n \n \n \n
{(image.data.score * 100).toFixed(2)}%
\n
\n
\n
\n {image.data.credits && By {image.data.credits}}\n {!image.data.credits && Unknown artist}\n
\n \n
\n )\n}\n\nconst GalleryDesktop = ({ data, width, targetHeight, maximumHeight, shouldBlur }: { data: SearchResultItem[], width: number, targetHeight: number, maximumHeight: number, shouldBlur: boolean }) => {\n const gallery = new Gallery(targetHeight, maximumHeight);\n const [render, setRender] = React.useState[]>()\n\n React.useEffect(() => {\n renderGallery();\n }, [width]);\n\n function renderGallery() {\n data.forEach(result => {\n let aspectRatio = result.thumbnail.width / result.thumbnail.height;\n\n let width = result.thumbnail.width;\n let height = result.thumbnail.height;\n\n // Images which are either very tall or wide, can screw with the gallery's\n // ability to fit them nicely in the grid. So, in order to fix that, we\n // force those images to be displayed as squares instead, just like on the mobile UI.\n if (aspectRatio < 0.6 || aspectRatio > 2) {\n width = 250;\n height = 250;\n }\n\n gallery.addImage(width, height, result);\n });\n\n const newRender = gallery.render(width, 6);\n\n const minNumberOfImages = 12;\n const minNumberOfRows = 3;\n let currentNumberOfImages = 0;\n let i = 0;\n for (; i < newRender.length; i++) {\n var currentRow = newRender[i];\n currentNumberOfImages += currentRow.images.length;\n\n if (currentNumberOfImages >= minNumberOfImages && minNumberOfRows <= i + 1) {\n break;\n }\n }\n\n setRender(newRender.slice(0, i + 1));\n }\n\n return (\n
\n {render != null && render.map(row => (\n
i.data.id).join(\"-\")} className={`flex ${row.couldFit ? \"justify-between\" : \"justify-start space-x-3\"}`}>\n {row.images.map(image => (\n \n ))}\n
\n ))}\n
\n )\n}\n\nconst SearchResultDesktop = ({ data }: { data: SearchResult }) => {\n const [hideImprobable, setHideImprobable] = React.useState(true);\n const [width, setWidth] = React.useState(0);\n const containerRef: React.RefObject = React.useRef();\n\n function onResize() {\n setWidth(containerRef.current.clientWidth);\n }\n\n React.useEffect(() => {\n onResize();\n window.addEventListener('resize', onResize);\n\n return () => {\n window.removeEventListener('resize', onResize);\n };\n }, []);\n\n return (\n
\n
\n \n
\n
\n Searched {data.stats.count.toLocaleString()} images in {data.stats.elapsedMilliseconds.toLocaleString()} ms\n
\n
\n {\n {\n 0: \"Looks like we couldn't find what you're looking for\",\n 1: \"We found an image similar to the one you submitted\"\n }[data.probableResults.length] || \"We found images similar to the one you submitted\"\n }\n
\n
\n
\n {width != 0 && data.probableResults.length > 0 &&\n \n }\n {width != 0 && data.improbableResults.length > 0 &&\n
\n
\n \n \n
\n \n
\n }\n
\n )\n}\n\nexport default SearchResultDesktop\n","import * as React from 'react'\n\nconst ImageRating = {\n Safe: 'SAFE',\n Explicit: 'EXPLICIT'\n};\n\nconst SearchConfig = function () {\n if (typeof localStorage === 'undefined') {\n return {}\n }\n\n function readIncludeNsfw() {\n if (localStorage.getItem('rating') != null) {\n return localStorage.getItem('rating') === ImageRating.Explicit;\n }\n\n return false;\n }\n\n const [includeNsfw, setIncludeNsfw] = React.useState(readIncludeNsfw());\n\n return {\n includeNsfw,\n setIncludeNsfw(includeNsfw: boolean) {\n localStorage.setItem('rating', includeNsfw ? ImageRating.Explicit : ImageRating.Safe);\n setIncludeNsfw(includeNsfw);\n }\n }\n};\n\nexport default SearchConfig\n","import * as React from 'react'\nimport { Match, SearchResult, SearchResultItem } from '../services/api';\nimport GalleryThumbnail from './gallery-thumbnail';\nimport Icon from './icon';\n\nconst GalleryCard = ({ data, enableBlur, onClick, seq }: { data: SearchResultItem, enableBlur: boolean, onClick: Function, seq: number }) => {\n const [hasBeenClicked, setHasBeenClicked] = React.useState(false);\n\n React.useEffect(() => {\n setHasBeenClicked(false);\n }, [seq]);\n\n const [hasBlur, setHasBlur] = React.useState(false);\n React.useEffect(() => {\n setHasBlur(enableBlur && !hasBeenClicked);\n }, [hasBeenClicked, enableBlur]);\n\n function handleClick(e: React.MouseEvent) {\n if (!hasBlur) {\n return;\n }\n\n setHasBeenClicked(true);\n e.preventDefault();\n onClick();\n }\n\n return (\n \n
\n
\n
\n \n
\n
\n {data.credits && By {data.credits}}\n {!data.credits && Unknown artist}\n
\n
\n \n
\n
\n
\n
\n )\n}\n\nconst GalleryMobile = ({ results, hideImprobable, onClick, seq }: { results: SearchResultItem[], hideImprobable: boolean, onClick: Function, seq: number }) => {\n return (\n
\n {results.slice(0, 12).map(item => (\n \n ))}\n
\n )\n}\n\nconst SearchResultMobile = ({ data }: { data: SearchResult }) => {\n const [hideImprobable, setHideImprobable] = React.useState(true);\n const [shouldHide, setShouldHide] = React.useState(false);\n const [seq, setSeq] = React.useState(0);\n\n function onClick() {\n setShouldHide(true);\n }\n\n function toggleHide() {\n setHideImprobable(shouldHide);\n setShouldHide(!shouldHide);\n setSeq(seq + 1);\n }\n\n return (\n
\n
\n \n
\n
\n Searched {data.stats.count.toLocaleString()} images in {data.stats.elapsedMilliseconds.toLocaleString()} ms\n
\n
\n {\n {\n 0: \"Couldn't find what you're looking for\",\n 1: \"We found a similar image\"\n }[data.probableResults.length] || \"We found similar images\"\n }\n
\n
\n
\n
\n
\n
\n
\n We've hidden improbable matches to keep you from viewing content you might experience as unpleasant\n
\n \n
\n \n
\n
\n
\n )\n};\n\nexport default SearchResultMobile\n","// extracted by mini-css-extract-plugin\nexport var dropZone = \"index-module--drop-zone--fWn+W\";\nexport var dropZoneActive = \"index-module--drop-zone-active--MIkqx\";","import * as React from 'react'\nimport Layout from '../components/layout'\nimport Banner from '../components/banner'\nimport { Link } from 'gatsby'\nimport ProgressBar from '../components/progress-bar'\nimport ProgressBarPart from '../components/progress-bar-part'\nimport Api, { SearchResult } from '../services/api'\nimport SearchResultDesktop from '../components/search-result-desktop'\nimport { Helmet } from 'react-helmet'\nimport Icon from '../components/icon'\nimport SearchConfig from '../services/search-config'\nimport SearchResultMobile from '../components/search-result-mobile'\nimport classNames from 'classnames'\nimport { dropZone, dropZoneActive } from './index.module.scss'\n\nconst State = {\n ERROR: -1,\n IDLE: 0,\n WAITING_FOR_BROWSER_EXTENSION: 1,\n PREPROCESSING: 2,\n UPLOADING: 3,\n PROCESSING: 4,\n DONE: 5\n};\n\nconst SearchPage = ({ forBrowserExtension }) => {\n let searchConfig = SearchConfig();\n\n const canvasRef: React.RefObject = React.useRef();\n const containerRef: React.RefObject = React.useRef();\n const dataUrlRef: React.RefObject = React.useRef();\n\n const [state, setState] = React.useState(forBrowserExtension ? State.WAITING_FOR_BROWSER_EXTENSION : State.IDLE);\n const [data, setData] = React.useState(null);\n const [errorMessage, setErrorMessage] = React.useState(null);\n const [progress, setProgress] = React.useState(0);\n const [hasDrag, setHasDrag] = React.useState(false);\n\n function setError(message) {\n setErrorMessage(message);\n setState(State.ERROR);\n }\n\n function calculateThumbnailSize(width, height, target) {\n let determineSize = (sizeOne, sizeTwo, sizeOneTarget) => {\n var aspectRatio = sizeOneTarget / sizeOne;\n\n return Math.round(aspectRatio * sizeTwo);\n };\n\n if (width === height) {\n return [target, target];\n }\n\n return width > height\n ? [determineSize(height, width, target), target]\n : [target, determineSize(width, height, target)];\n }\n\n function search(value: FileList | Blob) {\n setState(State.IDLE);\n setData(null);\n setErrorMessage(null);\n setProgress(0);\n\n let file: Blob;\n if (value instanceof FileList) {\n if (value.length > 1) {\n setError('You can only reverse search one image at a time.');\n return;\n }\n file = value[0];\n } else {\n file = value;\n }\n\n setState(State.PREPROCESSING);\n\n const image = new Image();\n const canvas = canvasRef.current;\n image.onload = () => {\n const target = 256;\n const thumbnailSize = calculateThumbnailSize(image.width, image.height, target);\n\n // In the first place we scaled down the image to a fixed size (250x250), but that\n // caused such a significant loss in image quality in some instances that we had to\n // scale preserving the aspect ratio of the original image \n canvas.width = thumbnailSize[0];\n canvas.height = thumbnailSize[1];\n const ctx = canvas.getContext('2d');\n ctx.drawImage(image, 0, 0, canvas.width, canvas.height);\n\n // Convert image drawn on canvas to blob\n const dataUri = canvas.toDataURL('image/png');\n fetch(dataUri).then(response => response.blob()).then(thumbnail => {\n searchInternal(file, thumbnail);\n });\n };\n\n // The error might simply be that the image format isn't supported by the canvas.\n // Therefore, we should still send it to the server.\n image.onerror = () => {\n searchInternal(file, file);\n }\n\n image.src = URL.createObjectURL(file);\n }\n\n function searchInternal(file: Blob, thumbnail: Blob) {\n setState(State.UPLOADING);\n Api.search(file, thumbnail, searchConfig.includeNsfw, 32, {\n onUploadProgress: e => {\n const progress = Math.round(e.loaded / e.total * 100);\n\n setProgress(progress);\n\n if (progress === 100) {\n setState(State.PROCESSING);\n }\n }\n }).then(data => {\n setData(data);\n setState(State.DONE);\n\n // TODO: Using a timeout has proven unreliable in the Angular version of the application\n setTimeout(() => {\n containerRef.current.scrollIntoView({\n behavior: 'smooth'\n });\n }, 250);\n }).catch(message => {\n setError(message);\n });\n }\n\n function onSelect(event) {\n search(event.target.files);\n }\n\n function onProgrammaticSubmit(event) {\n const dataUrl = dataUrlRef.current.value;\n fetch(dataUrl).then(request => request.blob()).then(blob => {\n search(blob);\n });\n }\n\n function onDragover(event) {\n setHasDrag(true);\n event.preventDefault();\n }\n\n function onDragLeave(event) {\n setHasDrag(false);\n event.preventDefault();\n }\n\n function onDrop(event) {\n // Prevent file from being opened\n event.preventDefault();\n setHasDrag(false);\n\n if (event.dataTransfer.files.length == 0) {\n setError('Did you drop a file which originates from the browser? Due to your browser its limitations, Fluffle cannot access those files. Save the file to your device first, then submit this file instead.')\n return;\n }\n\n search(event.dataTransfer.files);\n }\n\n // Safari doesn't handle clickable elements the same way as other browsers.\n // We need to explicitly cancel the opening of a file dialog when another element\n // is clicked on. We use a custom ignore attribute for that.\n function onLabelClick(event) {\n if (event.target.hasAttribute('data-ignore')) {\n event.preventDefault();\n }\n }\n\n return (\n \n \n \n \n
\n
\n
\n \n \n \n \n
\n
\n A reverse image search service tailored to the furry community\n
\n
\n \n \n \n \n {![State.PREPROCESSING, State.UPLOADING, State.PROCESSING].includes(state) &&\n
\n {state === State.ERROR &&\n
\n \n {errorMessage}\n
\n }\n \n
\n }\n\n {[State.WAITING_FOR_BROWSER_EXTENSION, State.PREPROCESSING, State.UPLOADING, State.PROCESSING].includes(state) &&\n
\n \n \n \n {state === State.WAITING_FOR_BROWSER_EXTENSION ? 'Waiting for the browser extension to download the image' : state === State.PREPROCESSING ? \"Preprocessing\" : state === State.UPLOADING ? \"Uploading\" : \"Processing\"}...\n
\n }\n\n {state === State.DONE &&\n
\n \n \n
\n }\n
\n
\n )\n}\n\nSearchPage.defaultProps = {\n forBrowserExtension: false\n}\n\nexport default SearchPage\n","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}"],"names":["className","style","maxWidth","src","svg","alt","galleryThumbnail","thumbnail","hasBlur","React","hasBeenLoaded","setHasBeenLoaded","error","setError","classNames","objectPosition","centerX","centerY","opacity","ref","element","image","Image","onload","onerror","location","load","hidden","progressBar","ProgressBarPart","color","percentage","isStriped","isAnimated","classes","width","defaultProps","children","Gallery","_targetHeight","_maximumHeight","images","addImage","height","data","this","push","GalleryImage","clear","render","targetWidth","targetMargin","shouldFit","rows","row","GalleryRow","tryAddImage","any","fit","length","isLast","targetHeight","_targetWidth","_targetMargin","hasSpaceFor","GalleryRowImage","calculateTheoreticalSpaceTaken","aspectRatio","calculateTheoreticalSpaceTakenIncludingMargin","spaceTakenByImageWithMargin","Math","round","calculateSpaceTaken","calculateSpaceLeft","spaceTakenInRow","couldFit","spaceLeft","totalAspectRatio","extraWidth","widthIncreaseFactor","floor","extraHeight","fitMaximumHeight","percentageLeft","growFactor","GalleryDesktopCard","shouldBlur","hasHover","setHasHover","href","rel","target","onMouseEnter","onMouseLeave","match","class","name","platform","score","toFixed","credits","GalleryDesktop","maximumHeight","gallery","setRender","forEach","result","newRender","minNumberOfImages","minNumberOfRows","currentNumberOfImages","i","slice","renderGallery","map","key","id","join","hideImprobable","setHideImprobable","setWidth","containerRef","onResize","current","clientWidth","window","addEventListener","removeEventListener","parameters","imageUrl","maxHeight","stats","count","toLocaleString","elapsedMilliseconds","probableResults","improbableResults","lineHeight","onClick","ImageRating","localStorage","getItem","includeNsfw","setIncludeNsfw","setItem","GalleryCard","enableBlur","seq","hasBeenClicked","setHasBeenClicked","setHasBlur","e","preventDefault","GalleryMobile","results","item","Match","shouldHide","setShouldHide","setSeq","concat","dropZone","State","ERROR","IDLE","WAITING_FOR_BROWSER_EXTENSION","PREPROCESSING","UPLOADING","PROCESSING","DONE","SearchPage","forBrowserExtension","searchConfig","SearchConfig","canvasRef","dataUrlRef","state","setState","setData","errorMessage","setErrorMessage","progress","setProgress","hasDrag","setHasDrag","message","search","value","file","FileList","canvas","thumbnailSize","determineSize","sizeOne","sizeTwo","sizeOneTarget","calculateThumbnailSize","getContext","drawImage","dataUri","toDataURL","fetch","then","response","blob","searchInternal","URL","createObjectURL","Api","onUploadProgress","loaded","total","setTimeout","scrollIntoView","behavior","catch","center","requireBrowser","title","Helmet","content","to","process","type","onChange","event","files","dataUrl","request","includes","htmlFor","hasAttribute","onDragOver","onDrop","dataTransfer","onDragLeave","_defineProperties","props","descriptor","enumerable","configurable","writable","Object","defineProperty","_createClass","Constructor","protoProps","staticProps","prototype"],"sourceRoot":""}