| 
                        123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 | 
                        - export const createImage = (url: string) =>
 -   new Promise<HTMLImageElement>((resolve, reject) => {
 -     const image = new Image()
 -     image.addEventListener('load', () => resolve(image))
 -     image.addEventListener('error', error => reject(error))
 -     image.setAttribute('crossOrigin', 'anonymous') // needed to avoid cross-origin issues on CodeSandbox
 -     image.src = url
 -   })
 - 
 - export function getRadianAngle(degreeValue: number) {
 -   return (degreeValue * Math.PI) / 180
 - }
 - 
 - export function getMimeType(fileName: string): string {
 -   const extension = fileName.split('.').pop()?.toLowerCase()
 -   switch (extension) {
 -     case 'png':
 -       return 'image/png'
 -     case 'jpg':
 -     case 'jpeg':
 -       return 'image/jpeg'
 -     case 'gif':
 -       return 'image/gif'
 -     case 'webp':
 -       return 'image/webp'
 -     default:
 -       return 'image/jpeg'
 -   }
 - }
 - 
 - /**
 -  * Returns the new bounding area of a rotated rectangle.
 -  */
 - export function rotateSize(width: number, height: number, rotation: number) {
 -   const rotRad = getRadianAngle(rotation)
 - 
 -   return {
 -     width:
 -             Math.abs(Math.cos(rotRad) * width) + Math.abs(Math.sin(rotRad) * height),
 -     height:
 -             Math.abs(Math.sin(rotRad) * width) + Math.abs(Math.cos(rotRad) * height),
 -   }
 - }
 - 
 - /**
 -  * This function was adapted from the one in the ReadMe of https://github.com/DominicTobias/react-image-crop
 -  */
 - export default async function getCroppedImg(
 -   imageSrc: string,
 -   pixelCrop: { x: number; y: number; width: number; height: number },
 -   fileName: string,
 -   rotation = 0,
 -   flip = { horizontal: false, vertical: false },
 - ): Promise<Blob> {
 -   const image = await createImage(imageSrc)
 -   const canvas = document.createElement('canvas')
 -   const ctx = canvas.getContext('2d')
 -   const mimeType = getMimeType(fileName)
 - 
 -   if (!ctx)
 -     throw new Error('Could not create a canvas context')
 - 
 -   const rotRad = getRadianAngle(rotation)
 - 
 -   // calculate bounding box of the rotated image
 -   const { width: bBoxWidth, height: bBoxHeight } = rotateSize(
 -     image.width,
 -     image.height,
 -     rotation,
 -   )
 - 
 -   // set canvas size to match the bounding box
 -   canvas.width = bBoxWidth
 -   canvas.height = bBoxHeight
 - 
 -   // translate canvas context to a central location to allow rotating and flipping around the center
 -   ctx.translate(bBoxWidth / 2, bBoxHeight / 2)
 -   ctx.rotate(rotRad)
 -   ctx.scale(flip.horizontal ? -1 : 1, flip.vertical ? -1 : 1)
 -   ctx.translate(-image.width / 2, -image.height / 2)
 - 
 -   // draw rotated image
 -   ctx.drawImage(image, 0, 0)
 - 
 -   const croppedCanvas = document.createElement('canvas')
 - 
 -   const croppedCtx = croppedCanvas.getContext('2d')
 - 
 -   if (!croppedCtx)
 -     throw new Error('Could not create a canvas context')
 - 
 -   // Set the size of the cropped canvas
 -   croppedCanvas.width = pixelCrop.width
 -   croppedCanvas.height = pixelCrop.height
 - 
 -   // Draw the cropped image onto the new canvas
 -   croppedCtx.drawImage(
 -     canvas,
 -     pixelCrop.x,
 -     pixelCrop.y,
 -     pixelCrop.width,
 -     pixelCrop.height,
 -     0,
 -     0,
 -     pixelCrop.width,
 -     pixelCrop.height,
 -   )
 - 
 -   return new Promise((resolve, reject) => {
 -     croppedCanvas.toBlob((file) => {
 -       if (file)
 -         resolve(file)
 -       else
 -         reject(new Error('Could not create a blob'))
 -     }, mimeType)
 -   })
 - }
 - 
 - export function checkIsAnimatedImage(file: File): Promise<boolean> {
 -   return new Promise((resolve, reject) => {
 -     const fileReader = new FileReader()
 - 
 -     fileReader.onload = function (e) {
 -       const arr = new Uint8Array(e.target?.result as ArrayBuffer)
 - 
 -       // Check file extension
 -       const fileName = file.name.toLowerCase()
 -       if (fileName.endsWith('.gif')) {
 -         // If file is a GIF, assume it's animated
 -         resolve(true)
 -       }
 -       // Check for WebP signature (RIFF and WEBP)
 -       else if (isWebP(arr)) {
 -         resolve(checkWebPAnimation(arr)) // Check if it's animated
 -       }
 -       else {
 -         resolve(false) // Not a GIF or WebP
 -       }
 -     }
 - 
 -     fileReader.onerror = function (err) {
 -       reject(err) // Reject the promise on error
 -     }
 - 
 -     // Read the file as an array buffer
 -     fileReader.readAsArrayBuffer(file)
 -   })
 - }
 - 
 - // Function to check for WebP signature
 - function isWebP(arr: Uint8Array) {
 -   return (
 -     arr[0] === 0x52 && arr[1] === 0x49 && arr[2] === 0x46 && arr[3] === 0x46
 -     && arr[8] === 0x57 && arr[9] === 0x45 && arr[10] === 0x42 && arr[11] === 0x50
 -   ) // "WEBP"
 - }
 - 
 - // Function to check if the WebP is animated (contains ANIM chunk)
 - function checkWebPAnimation(arr: Uint8Array) {
 -   // Search for the ANIM chunk in WebP to determine if it's animated
 -   for (let i = 12; i < arr.length - 4; i++) {
 -     if (arr[i] === 0x41 && arr[i + 1] === 0x4E && arr[i + 2] === 0x49 && arr[i + 3] === 0x4D)
 -       return true // Found animation
 -   }
 -   return false // No animation chunk found
 - }
 
 
  |