{"version":3,"sources":["../src/image.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type ImgHTMLAttributes, type SyntheticEvent } from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport {\n  DEFAULT_FARM_IMAGE_DEVICE_SIZES,\n  DEFAULT_FARM_IMAGE_FORMATS,\n  DEFAULT_FARM_IMAGE_PATH,\n  DEFAULT_FARM_IMAGE_QUALITIES,\n  DEFAULT_FARM_IMAGE_SIZES,\n  type PublicFarmImageConfig,\n} from \"./image-config\";\n\ndeclare const __FARM_IMAGE_CONFIG__: PublicFarmImageConfig | undefined;\n\nexport interface StaticImageData {\n  src: string;\n  width: number;\n  height: number;\n  blurDataURL?: string;\n}\n\nexport interface FarmImageLoaderProps {\n  src: string;\n  width: number;\n  quality: number;\n}\n\nexport type FarmImageLoader = (props: FarmImageLoaderProps) => string;\n\nexport interface ImageProps extends Omit<\n  ImgHTMLAttributes<HTMLImageElement>,\n  \"src\" | \"srcSet\" | \"width\" | \"height\" | \"loading\" | \"placeholder\"\n> {\n  src: string | StaticImageData;\n  alt: string;\n  width?: number | `${number}`;\n  height?: number | `${number}`;\n  fill?: boolean;\n  quality?: number;\n  sizes?: string;\n  loading?: \"eager\" | \"lazy\";\n  preload?: boolean;\n  placeholder?: \"empty\" | \"blur\";\n  blurDataURL?: string;\n  unoptimized?: boolean;\n  loader?: FarmImageLoader;\n  onLoad?: (event: SyntheticEvent<HTMLImageElement>) => void;\n}\n\nexport interface ImagePropsResult {\n  props: ImgHTMLAttributes<HTMLImageElement>;\n}\n\nconst FALLBACK_CONFIG: PublicFarmImageConfig = {\n  provider: \"auto\",\n  path: DEFAULT_FARM_IMAGE_PATH,\n  deviceSizes: DEFAULT_FARM_IMAGE_DEVICE_SIZES,\n  imageSizes: DEFAULT_FARM_IMAGE_SIZES,\n  qualities: DEFAULT_FARM_IMAGE_QUALITIES,\n  formats: DEFAULT_FARM_IMAGE_FORMATS,\n};\n\nfunction getImageConfig(): PublicFarmImageConfig {\n  return typeof __FARM_IMAGE_CONFIG__ !== \"undefined\" && __FARM_IMAGE_CONFIG__\n    ? __FARM_IMAGE_CONFIG__\n    : FALLBACK_CONFIG;\n}\n\nfunction defaultImageLoader(config: PublicFarmImageConfig): FarmImageLoader {\n  return ({ src, width, quality }) => {\n    const query = new URLSearchParams({\n      url: src,\n      w: String(width),\n      q: String(quality),\n    });\n    return `${config.path}?${query}`;\n  };\n}\n\nfunction getClosestQuality(quality: number | undefined, allowed: readonly number[]): number {\n  const requested = quality ?? 75;\n  return allowed.reduce((closest, candidate) =>\n    Math.abs(candidate - requested) < Math.abs(closest - requested) ? candidate : closest,\n  );\n}\n\nfunction getCandidateWidths(\n  config: PublicFarmImageConfig,\n  width: number | undefined,\n  sizes: string | undefined,\n  fill: boolean,\n): { widths: number[]; descriptor: \"w\" | \"x\" } {\n  const allSizes = [...new Set([...config.imageSizes, ...config.deviceSizes])].sort(\n    (left, right) => left - right,\n  );\n\n  if (fill || sizes) {\n    const viewportPercentages = [...(sizes?.matchAll(/(^|\\s)(\\d{1,3})vw/g) ?? [])].map((match) =>\n      Number(match[2]),\n    );\n    if (viewportPercentages.length > 0) {\n      const smallestRatio = Math.min(...viewportPercentages) / 100;\n      const minimum = config.deviceSizes[0] * smallestRatio;\n      return { widths: allSizes.filter((candidate) => candidate >= minimum), descriptor: \"w\" };\n    }\n    return { widths: allSizes, descriptor: \"w\" };\n  }\n\n  if (!width) return { widths: config.deviceSizes.slice(), descriptor: \"w\" };\n\n  const requested = [width, width * 2];\n  const widths = requested.map(\n    (target) => allSizes.find((candidate) => candidate >= target) ?? allSizes.at(-1)!,\n  );\n  return { widths: [...new Set(widths)], descriptor: \"x\" };\n}\n\nfunction isStaticImageData(value: ImageProps[\"src\"]): value is StaticImageData {\n  return typeof value === \"object\" && value !== null && typeof value.src === \"string\";\n}\n\nfunction shouldSkipOptimization(src: string, config: PublicFarmImageConfig): boolean {\n  return (\n    config.provider === \"none\" ||\n    src.startsWith(\"data:\") ||\n    src.startsWith(\"blob:\") ||\n    /\\.svg(?:$|[?#])/i.test(src)\n  );\n}\n\nexport function getImageProps(input: ImageProps): ImagePropsResult {\n  const {\n    src: srcInput,\n    alt,\n    width: widthInput,\n    height: heightInput,\n    fill = false,\n    quality: qualityInput,\n    sizes: sizesInput,\n    loading,\n    preload = false,\n    placeholder = \"empty\",\n    blurDataURL: blurDataURLInput,\n    unoptimized: unoptimizedInput = false,\n    loader: loaderInput,\n    style,\n    ...rest\n  } = input;\n  const config = getImageConfig();\n  const staticImage = isStaticImageData(srcInput) ? srcInput : undefined;\n  const src = typeof srcInput === \"string\" ? srcInput : srcInput.src;\n  const width = Number(widthInput ?? staticImage?.width) || undefined;\n  const height = Number(heightInput ?? staticImage?.height) || undefined;\n  const blurDataURL = blurDataURLInput ?? staticImage?.blurDataURL;\n\n  if (!fill && (!width || !height)) {\n    throw new TypeError(\n      \"Farm Image requires width and height unless src is a static import or fill is enabled\",\n    );\n  }\n  if (fill && (widthInput !== undefined || heightInput !== undefined)) {\n    throw new TypeError(\"Farm Image cannot use width or height together with fill\");\n  }\n  if (placeholder === \"blur\" && !blurDataURL) {\n    throw new TypeError(\"Farm Image placeholder=blur requires a static import or blurDataURL\");\n  }\n\n  const unoptimized = unoptimizedInput || shouldSkipOptimization(src, config);\n  const quality = getClosestQuality(qualityInput, config.qualities);\n  const loader = loaderInput ?? defaultImageLoader(config);\n  const sizes = sizesInput ?? (fill ? \"100vw\" : undefined);\n  const candidates = getCandidateWidths(config, width, sizes, fill);\n  const srcSet = unoptimized\n    ? undefined\n    : candidates.widths\n        .map((candidate, index) => {\n          const descriptor = candidates.descriptor === \"w\" ? `${candidate}w` : `${index + 1}x`;\n          return `${loader({ src, width: candidate, quality })} ${descriptor}`;\n        })\n        .join(\", \");\n  const renderedSrc = unoptimized\n    ? src\n    : loader({ src, width: candidates.widths.at(-1) ?? width ?? config.deviceSizes[0], quality });\n  const fillStyle: CSSProperties | undefined = fill\n    ? { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" }\n    : undefined;\n  const placeholderStyle: CSSProperties | undefined =\n    placeholder === \"blur\"\n      ? {\n          backgroundImage: `url(\"${blurDataURL}\")`,\n          backgroundPosition: \"50% 50%\",\n          backgroundRepeat: \"no-repeat\",\n          backgroundSize: \"cover\",\n        }\n      : undefined;\n\n  return {\n    props: {\n      ...rest,\n      alt,\n      src: renderedSrc,\n      srcSet,\n      sizes,\n      width: fill ? undefined : width,\n      height: fill ? undefined : height,\n      loading: preload ? \"eager\" : (loading ?? \"lazy\"),\n      fetchPriority: preload ? \"high\" : rest.fetchPriority,\n      decoding: rest.decoding ?? \"async\",\n      style: { ...fillStyle, ...placeholderStyle, ...style },\n    },\n  };\n}\n\nexport const Image = forwardRef<HTMLImageElement, ImageProps>(function Image(input, ref) {\n  const { props } = getImageProps(input);\n\n  if (input.preload && typeof (ReactDOM as any).preload === \"function\") {\n    (ReactDOM as any).preload(props.src as string, {\n      as: \"image\",\n      imageSrcSet: props.srcSet,\n      imageSizes: props.sizes,\n      fetchPriority: \"high\",\n    });\n  }\n\n  return <img {...props} ref={ref} />;\n});\n\nImage.displayName = \"Image\";\n\nexport default Image;\n\nexport type {\n  FarmImageConfig,\n  FarmImageFormat,\n  FarmImageLocalPattern,\n  FarmImageProvider,\n  FarmImageRemotePattern,\n  ResolvedFarmImageConfig,\n} from \"./image-config\";\n"],"mappings":"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","names":["preload","Image"]}