{"release_id":"01a1998d-9802-0000-b0f7-33a23307f4ed","chunk_id":"01a1998d-993a-7f93-bd69-387326a8a405","file":"Jaf0bJc_.mjs","mappings":"qTAeA,eAAsBA,EAAYC,EAA2B,CAC5D,GAAI,CAACA,EAAK,KAAK,WAAW,QAAQ,GAAKA,EAAK,OAAS,YAAa,OAAOA,EACzE,MAAMC,EAAM,IAAI,gBAAgBD,CAAI,EACpC,GAAI,CACH,MAAME,EAAM,MAAM,IAAI,QAA0B,CAACC,EAASC,IAAW,CACpE,MAAMC,EAAK,IAAI,MACfA,EAAG,OAAS,IAAMF,EAAQE,CAAE,EAC5BA,EAAG,QAAU,IAAMD,EAAO,IAAI,MAAM,eAAe,CAAC,EACpDC,EAAG,IAAMJ,CACV,CAAC,EACKK,EAAQ,KAAK,IAAI,EAAG,KAAY,KAAK,IAAIJ,EAAI,aAAcA,EAAI,aAAa,CAAC,EAC7EK,EAAI,KAAK,MAAML,EAAI,aAAeI,CAAK,EACvC,EAAI,KAAK,MAAMJ,EAAI,cAAgBI,CAAK,EACxCE,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,MAAQD,EACfC,EAAO,OAAS,EAChB,MAAMC,EAAMD,EAAO,WAAW,IAAI,EAClC,GAAI,CAACC,EAAK,OAAOT,EACjBS,EAAI,UAAUP,EAAK,EAAG,EAAGK,EAAG,CAAC,EAC7B,MAAMG,EAAO,MAAM,IAAI,QAAsBP,GAAYK,EAAO,OAAOL,EAAS,aAAc,GAAO,CAAC,EACtG,GAAI,CAACO,GAAQA,EAAK,MAAQV,EAAK,KAAM,OAAOA,EAC5C,MAAMW,EAAOX,EAAK,KAAK,QAAQ,WAAY,EAAE,EAAI,OACjD,OAAO,IAAI,KAAK,CAACU,CAAI,EAAGC,EAAM,CAAE,KAAM,aAAc,CACrD,MAAQ,CACP,OAAOX,CACR,QAAA,CACC,IAAI,gBAAgBC,CAAG,CACxB,CACD","names":["shrinkPhoto","file","url","img","resolve","reject","el","scale","w","canvas","ctx","blob","name"],"sources":["../../../../../../src/lib/utils/shrink-photo.ts"],"sourcesContent":["/** A phone photo made small before it goes up.\n *\n *  A ToD dare used to upload the camera's original (3–8 MB, 4000 px), and the\n *  table's 15 s vote clock ran while every other player's browser pulled that\n *  through the CDN's first, cold resize — a black box for most of the vote.\n *  Drawn through a canvas at a 1600 px long edge it is a few hundred KB: faster\n *  up, faster down, and EXIF (location included) is gone with it.\n *\n *  Browsers apply the EXIF orientation when drawing an <img> (CSS\n *  `image-orientation: from-image` is the default), so the canvas copy is upright.\n *  Anything that can't be decoded comes back unchanged.\n */\nconst LONG_EDGE = 1600;\nconst QUALITY = 0.85;\n\nexport async function shrinkPhoto(file: File): Promise<File> {\n\tif (!file.type.startsWith('image/') || file.type === 'image/gif') return file;\n\tconst url = URL.createObjectURL(file);\n\ttry {\n\t\tconst img = await new Promise<HTMLImageElement>((resolve, reject) => {\n\t\t\tconst el = new Image();\n\t\t\tel.onload = () => resolve(el);\n\t\t\tel.onerror = () => reject(new Error('decode failed'));\n\t\t\tel.src = url;\n\t\t});\n\t\tconst scale = Math.min(1, LONG_EDGE / Math.max(img.naturalWidth, img.naturalHeight));\n\t\tconst w = Math.round(img.naturalWidth * scale);\n\t\tconst h = Math.round(img.naturalHeight * scale);\n\t\tconst canvas = document.createElement('canvas');\n\t\tcanvas.width = w;\n\t\tcanvas.height = h;\n\t\tconst ctx = canvas.getContext('2d');\n\t\tif (!ctx) return file;\n\t\tctx.drawImage(img, 0, 0, w, h);\n\t\tconst blob = await new Promise<Blob | null>((resolve) => canvas.toBlob(resolve, 'image/jpeg', QUALITY));\n\t\tif (!blob || blob.size >= file.size) return file;\n\t\tconst name = file.name.replace(/\\.[^.]+$/, '') + '.jpg';\n\t\treturn new File([blob], name, { type: 'image/jpeg' });\n\t} catch {\n\t\treturn file;\n\t} finally {\n\t\tURL.revokeObjectURL(url);\n\t}\n}\n"],"version":3}