{
  "version": 3,
  "sources": ["/cdn/shop/t/5/assets/custom-artwork-upload.js?psv=cropper-20260814"],
  "sourcesContent": ["(() => {\n  const root = document.querySelector('[data-ps-product]');\n  const component = root?.querySelector('[data-ps-artwork-upload]');\n  if (!root || !component) return;\n\n  const input = component.querySelector('[data-ps-artwork-input]');\n  const dropzone = component.querySelector('[data-ps-artwork-dropzone]');\n  const selection = component.querySelector('[data-ps-artwork-selection]');\n  const fileOutput = component.querySelector('[data-ps-artwork-file]');\n  const removeButton = component.querySelector('[data-ps-artwork-remove]');\n  const status = component.querySelector('[data-ps-artwork-status]');\n  const mainImage = root.querySelector('[data-ps-main-image]');\n  if (!input || !dropzone || !selection || !fileOutput || !removeButton || !status || !mainImage) return;\n\n  const maxBytes = Number(component.dataset.maxFileBytes || 20971520);\n  const maxPixels = Number(component.dataset.maxImagePixels || 20000000);\n  const allowedTypes = new Set(['image/jpeg', 'image/png', 'image/webp']);\n  const allowedExtension = /\\.(jpe?g|png|webp)$/i;\n  const originalImage = {\n    src: mainImage.getAttribute('src') || '',\n    srcset: mainImage.getAttribute('srcset'),\n    sizes: mainImage.getAttribute('sizes'),\n    alt: mainImage.getAttribute('alt') || '',\n  };\n  let selectedFile = null;\n  let selectedMetadata = null;\n  let previewUrl = '';\n  let selectionToken = 0;\n\n  const setStatus = (message = '', type = '') => {\n    status.textContent = message;\n    status.classList.toggle('is-error', type === 'error');\n    status.classList.toggle('is-success', type === 'success');\n  };\n\n  const formatFileSize = (bytes) => bytes >= 1048576\n    ? `${(bytes / 1048576).toFixed(1)} MB`\n    : `${Math.max(1, Math.round(bytes / 1024))} KB`;\n\n  const revokePreview = () => {\n    if (!previewUrl) return;\n    URL.revokeObjectURL(previewUrl);\n    previewUrl = '';\n  };\n\n  const restoreOriginalImage = () => {\n    mainImage.src = originalImage.src;\n    if (originalImage.srcset) mainImage.setAttribute('srcset', originalImage.srcset);\n    else mainImage.removeAttribute('srcset');\n    if (originalImage.sizes) mainImage.setAttribute('sizes', originalImage.sizes);\n    else mainImage.removeAttribute('sizes');\n    mainImage.alt = originalImage.alt;\n    root.dispatchEvent(new CustomEvent('product:media-change', {\n      detail: { mediaId: mainImage.closest('[data-ps-art-preview]')?.dataset.mediaId || '', isCustomPreview: false, source: 'artwork_removed' },\n    }));\n  };\n\n  const clearSelection = ({ restoreImage = true, announce = true } = {}) => {\n    selectionToken += 1;\n    selectedFile = null;\n    selectedMetadata = null;\n    input.value = '';\n    selection.hidden = true;\n    fileOutput.textContent = '';\n    component.dataset.state = 'empty';\n    revokePreview();\n    if (restoreImage) restoreOriginalImage();\n    setStatus(announce ? 'Image removed.' : '', announce ? 'success' : '');\n    root.dispatchEvent(new CustomEvent('product:artwork-change', { detail: { hasArtwork: false } }));\n  };\n\n  const inspectImage = (url) => new Promise((resolve, reject) => {\n    const image = new Image();\n    image.onload = () => resolve({ width: image.naturalWidth, height: image.naturalHeight });\n    image.onerror = () => reject(new Error('This image could not be read. Please choose another file.'));\n    image.src = url;\n  });\n\n  const validateFile = (file) => {\n    if (!file) return 'Choose an image to continue.';\n    if (!allowedTypes.has(file.type) && !allowedExtension.test(file.name)) return 'Use a JPEG, PNG or WebP image.';\n    if (file.size > maxBytes) return 'The image must be 20 MB or smaller.';\n    return '';\n  };\n\n  const syncInputFile = (file) => {\n    if (!file) {\n      input.value = '';\n      return;\n    }\n    if (typeof DataTransfer !== 'function') return;\n    const transfer = new DataTransfer();\n    transfer.items.add(file);\n    input.files = transfer.files;\n  };\n\n  const applyFile = async (file) => {\n    const token = ++selectionToken;\n    const basicError = validateFile(file);\n    if (basicError) {\n      clearSelection({ announce: false });\n      setStatus(basicError, 'error');\n      return;\n    }\n\n    const previousFile = selectedFile;\n    setStatus('Preparing crop\u2026');\n    const nextUrl = URL.createObjectURL(file);\n    try {\n      const dimensions = await inspectImage(nextUrl);\n      if (token !== selectionToken) {\n        URL.revokeObjectURL(nextUrl);\n        return;\n      }\n      if (dimensions.width * dimensions.height > maxPixels) {\n        URL.revokeObjectURL(nextUrl);\n        clearSelection({ announce: false });\n        setStatus('The image must be 20 megapixels or smaller.', 'error');\n        return;\n      }\n\n      URL.revokeObjectURL(nextUrl);\n      const cropResult = root.productArtworkCropper\n        ? await root.productArtworkCropper.open(file)\n        : { file, orientation: dimensions.width > dimensions.height ? 'landscape' : dimensions.width < dimensions.height ? 'portrait' : 'square' };\n      if (token !== selectionToken) return;\n      if (!cropResult) {\n        syncInputFile(previousFile);\n        setStatus(previousFile ? 'Your existing image is unchanged.' : '', previousFile ? 'success' : '');\n        return;\n      }\n\n      const croppedFile = cropResult.file;\n      const croppedUrl = URL.createObjectURL(croppedFile);\n      const croppedDimensions = await inspectImage(croppedUrl);\n      if (token !== selectionToken) {\n        URL.revokeObjectURL(croppedUrl);\n        return;\n      }\n\n      revokePreview();\n      previewUrl = croppedUrl;\n      selectedFile = croppedFile;\n      syncInputFile(croppedFile);\n      selectedMetadata = {\n        ...croppedDimensions,\n        size: croppedFile.size,\n        type: croppedFile.type || 'image',\n        orientation: cropResult.orientation,\n        ratio: cropResult.ratio,\n        sourceWidth: dimensions.width,\n        sourceHeight: dimensions.height,\n      };\n      mainImage.removeAttribute('srcset');\n      mainImage.removeAttribute('sizes');\n      mainImage.alt = 'Your uploaded artwork preview';\n      mainImage.addEventListener('load', () => {\n        root.dispatchEvent(new CustomEvent('product:media-change', {\n          detail: { mediaId: 'customer-artwork', isCustomPreview: true, source: 'customer_upload' },\n        }));\n      }, { once: true });\n      mainImage.src = previewUrl;\n      fileOutput.textContent = `${croppedFile.name} \u00B7 ${croppedDimensions.width}\u00D7${croppedDimensions.height}px \u00B7 ${formatFileSize(croppedFile.size)}`;\n      selection.hidden = false;\n      component.dataset.state = 'ready';\n      setStatus('Your image is now shown in the preview.', 'success');\n      root.dispatchEvent(new CustomEvent('product:artwork-change', { detail: { hasArtwork: true, ...selectedMetadata } }));\n      window.dataLayer?.push({\n        event: 'custom_artwork_uploaded',\n        file_type: selectedMetadata.type,\n        file_size_bytes: selectedMetadata.size,\n        image_width: selectedMetadata.width,\n        image_height: selectedMetadata.height,\n        crop_orientation: selectedMetadata.orientation,\n        crop_ratio: selectedMetadata.ratio,\n      });\n    } catch (error) {\n      URL.revokeObjectURL(nextUrl);\n      if (token !== selectionToken) return;\n      syncInputFile(previousFile);\n      setStatus(error.message || 'This image could not be read. Please choose another file.', 'error');\n    }\n  };\n\n  input.addEventListener('change', () => applyFile(input.files?.[0]));\n  removeButton.addEventListener('click', () => clearSelection());\n  dropzone.addEventListener('dragover', (event) => {\n    event.preventDefault();\n    dropzone.classList.add('is-dragging');\n  });\n  dropzone.addEventListener('dragleave', () => dropzone.classList.remove('is-dragging'));\n  dropzone.addEventListener('drop', (event) => {\n    event.preventDefault();\n    dropzone.classList.remove('is-dragging');\n    const file = event.dataTransfer?.files?.[0];\n    if (!file) return;\n    if (typeof DataTransfer !== 'function') {\n      setStatus('Use the Choose image button to select this file.', 'error');\n      return;\n    }\n    const transfer = new DataTransfer();\n    transfer.items.add(file);\n    input.files = transfer.files;\n    applyFile(file);\n  });\n  window.addEventListener('beforeunload', revokePreview, { once: true });\n\n  component.dataset.state = 'empty';\n  root.productArtwork = {\n    getFile: () => selectedFile,\n    getMetadata: () => selectedMetadata ? { ...selectedMetadata } : null,\n    clear: () => clearSelection(),\n  };\n})();\n"],
  "mappings": "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",
  "names": []
}
