{
  "version": 3,
  "sources": ["/cdn/shop/t/31/assets/craftdiy-customizer.js?craftdiy_release=v44-final.3"],
  "sourcesContent": ["(() => {\n  'use strict';\n\n  const RELEASE = 'v44-final.3';\n  const CORE_VERSION = '6.0.3-v44-ring1387-router-and-layered-preview';\n  const BIRTHSTONE_MASK_MAP_ASSET = 'craftdiy-birthstone-mask-map-v33.json';\n  const GEM_CROP_MANIFEST_ASSET = 'craftdiy-gem-crop-manifest-v33.json';\n  const BIRTHSTONE_DOT_SPRITE_ASSET = 'craftdiy-birthstone-palette-birthstone-engraved-necklaces-product-04.png';\n  const BIRTHSTONE_SLOT_OVERRIDES = Object.freeze({\n    'birthstone-engraved-rings/6': 2,\n    'birthstone-engraved-rings/7': 2,\n    'birthstone-engraved-rings/8': 2,\n  });\n  const BIRTHSTONE_BASE_ASSET_OVERRIDES = Object.freeze({\n    'birthstone-engraved-rings/6': 'craftdiy-mask-birthstone-engraved-rings-7.png',\n    'birthstone-engraved-rings/7': 'craftdiy-mask-birthstone-engraved-rings-6.png',\n    'birthstone-engraved-rings/8': 'craftdiy-mask-birthstone-engraved-rings-8.png',\n  });\n  const RING1387_SETTING_REFERENCE_ASSETS = Object.freeze({\n    'birthstone-engraved-rings/6': 'craftdiy-ring1387-gold-bbab8a8c.png',\n    'birthstone-engraved-rings/7': 'craftdiy-ring1387-rose-2547c730.png',\n    'birthstone-engraved-rings/8': 'craftdiy-ring1387-silver-f0c3b566.png',\n  });\n  const RING1387_MASK_ASSETS = Object.freeze({\n    'birthstone-engraved-rings/6': Object.freeze([\n      Object.freeze({ assetName: 'craftdiy-ring1387-gold-mask-left-a013fc20.png', bounds: Object.freeze({ x: 367, y: 511, width: 137, height: 149 }), pixels: 13228 }),\n      Object.freeze({ assetName: 'craftdiy-ring1387-gold-mask-right-35081a61.png', bounds: Object.freeze({ x: 500, y: 516, width: 147, height: 145 }), pixels: 13821 }),\n    ]),\n    'birthstone-engraved-rings/7': Object.freeze([\n      Object.freeze({ assetName: 'craftdiy-ring1387-rose-mask-left-c41547e5.png', bounds: Object.freeze({ x: 353, y: 506, width: 153, height: 155 }), pixels: 13542 }),\n      Object.freeze({ assetName: 'craftdiy-ring1387-rose-mask-right-e552113f.png', bounds: Object.freeze({ x: 500, y: 516, width: 147, height: 145 }), pixels: 13905 }),\n    ]),\n    'birthstone-engraved-rings/8': Object.freeze([\n      Object.freeze({ assetName: 'craftdiy-ring1387-silver-mask-left-5eed3f96.png', bounds: Object.freeze({ x: 360, y: 511, width: 144, height: 151 }), pixels: 13534 }),\n      Object.freeze({ assetName: 'craftdiy-ring1387-silver-mask-right-fd067a3f.png', bounds: Object.freeze({ x: 495, y: 507, width: 153, height: 159 }), pixels: 14715 }),\n    ]),\n  });\n  const TEXT_ZONE_LAYOUT_OVERRIDES = Object.freeze({\n    'engraved-bracelets/81': Object.freeze({\n      x: 50.9, y: 60, w: 40, h: 8, fontSize: 50, minFontSize: 30,\n    }),\n    'engraved-bracelets/82': Object.freeze({\n      x: 50.9, y: 60, w: 40, h: 8, fontSize: 50, minFontSize: 30,\n    }),\n  });\n  const MULTILINE_TEXT_LIMITS = Object.freeze({\n    'personalized-envelope-message-necklace-663': Object.freeze({ maxChars: 16, maxLines: 4 }),\n    'personalized-sliding-photo-engraved-tag-necklace-671': Object.freeze({ maxChars: 18, maxLines: 4 }),\n    'personalized-double-sided-round-photo-necklace-1311': Object.freeze({ maxChars: 18, maxLines: 4 }),\n  });\n  const PATTERN_NUMBER_CONFIGS = new Set([\n    'photo-necklaces/32',\n    'photo-necklaces/33',\n    'photo-necklaces/34',\n  ]);\n  const WHITE_ENGRAVING_PRODUCT_HANDLES = new Set([\n    'personalized-cube-name-cord-bracelet-1398',\n  ]);\n  const WHITE_ENGRAVING_SKUS = new Set([\n    'CD-1286-003',\n    'CD-1286-008',\n    'CD-1471-002',\n  ]);\n  const NAME_MIN_FONT_RATIO = 0.6;\n  const NAME_MAX_CHAR_WIDTH_RATIO = 0.65;\n  let birthstoneMaskMapPromise = null;\n  let gemCropManifestPromise = null;\n\n  const BIRTHSTONES = [\n    ['January', 'Garnet', '#8f1d2c'],\n    ['February', 'Amethyst', '#7d4aa8'],\n    ['March', 'Aquamarine', '#72c8d7'],\n    ['April', 'Diamond', '#dce9ef'],\n    ['May', 'Emerald', '#2b9b68'],\n    ['June', 'Alexandrite', '#b48abf'],\n    ['July', 'Ruby', '#d52c4f'],\n    ['August', 'Peridot', '#93b83f'],\n    ['September', 'Sapphire', '#315da7'],\n    ['October', 'Tourmaline', '#e68ca7'],\n    ['November', 'Citrine', '#e8a92f'],\n    ['December', 'Blue Topaz', '#4a9fcd'],\n  ];\n\n  const SLOT_MASK_COLORS = [\n    [255, 31, 45], [37, 211, 102], [40, 116, 255], [255, 195, 25],\n    [176, 74, 255], [0, 205, 205], [255, 112, 25], [255, 69, 174],\n  ];\n\n  const FONT_OPTIONS = [\n    ['sorealism', 'Sorealism Signature', '\"Craftdiy Sorealism\", \"Brush Script MT\", cursive', 'Forever yours'],\n    ['signature', 'Signature', '\"Snell Roundhand\", \"Segoe Script\", \"Brush Script MT\", cursive', 'Darling'],\n    ['flourish', 'Flourish Script', '\"Apple Chancery\", \"Snell Roundhand\", \"URW Chancery L\", cursive', 'Beloved'],\n    ['calligraphy', 'Calligraphy', '\"Lucida Calligraphy\", \"Monotype Corsiva\", \"Apple Chancery\", cursive', 'With love'],\n    ['classic', 'Classic Serif', 'Georgia, \"Times New Roman\", serif', 'Forever'],\n    ['garamond', 'Garamond', 'Garamond, \"EB Garamond\", \"Times New Roman\", serif', 'Heritage'],\n    ['baskerville', 'Baskerville', 'Baskerville, \"Baskerville Old Face\", Georgia, serif', 'Keepsake'],\n    ['modern', 'Modern Sans', 'Arial, Helvetica, sans-serif', 'STUDIO'],\n    ['geometric', 'Geometric Sans', '\"Century Gothic\", Futura, Arial, sans-serif', 'UNITY'],\n    ['editorial', 'Editorial', 'Didot, \"Bodoni 72\", \"Bodoni MT\", serif', 'Amour'],\n    ['slab', 'Slab Serif', 'Rockwell, \"Rockwell Nova\", \"Courier New\", serif', 'TOGETHER'],\n    ['typewriter', 'Typewriter', '\"American Typewriter\", \"Courier New\", monospace', 'EST. 2026'],\n    ['handwritten', 'Handwritten', '\"Bradley Hand\", \"Segoe Print\", cursive', 'with love'],\n    ['casual', 'Casual Hand', '\"Segoe Print\", \"Bradley Hand\", \"Chalkboard SE\", cursive', 'just for you'],\n    ['notebook', 'Notebook', '\"Comic Sans MS\", \"Chalkboard SE\", \"Segoe Print\", cursive', 'our story'],\n    ['rounded', 'Rounded', '\"Avenir Next Rounded\", \"Trebuchet MS\", sans-serif', 'Together'],\n    ['condensed', 'Bold Condensed', 'Impact, Haettenschweiler, \"Arial Narrow Bold\", sans-serif', 'ALWAYS'],\n    ['roman', 'Roman', 'Copperplate, \"Copperplate Gothic Light\", serif', 'LEGACY'],\n    ['artdeco', 'Art Deco', 'Copperplate, \"Copperplate Gothic Light\", fantasy', 'FOREVER'],\n  ];\n\n  const FONT_MAP = Object.fromEntries(FONT_OPTIONS.map(([key, , stack]) => [key, stack]));\n  const clamp = (value, min, max) => Math.min(max, Math.max(min, value));\n  const percentX = (value, canvas) => (Number(value || 0) / 100) * canvas.width;\n  const percentY = (value, canvas) => (Number(value || 0) / 100) * canvas.height;\n\n  function escapeHtml(value) {\n    return String(value ?? '')\n      .replaceAll('&', '&amp;')\n      .replaceAll('<', '&lt;')\n      .replaceAll('>', '&gt;')\n      .replaceAll('\"', '&quot;')\n      .replaceAll(\"'\", '&#039;');\n  }\n\n  function zoneLabel(zone, index, fallback) {\n    const label = String(zone?.label || '').trim();\n    if (!label || /^Custom text/i.test(label) || /^Photo( \\d+)?$/i.test(label)) {\n      return `${fallback} ${index + 1}`;\n    }\n    return label;\n  }\n\n  function repairMalformedBirthstoneMask(maskCanvas, pixelCount) {\n    const bounds = maskCanvas?.craftdiyBounds;\n    if (!bounds || !pixelCount || bounds.width < 3 || bounds.height < 3) return false;\n    const fillRatio = pixelCount / Math.max(1, bounds.width * bounds.height);\n    const aspect = bounds.width / Math.max(1, bounds.height);\n    const context = maskCanvas.getContext('2d');\n    let repaired = null;\n\n    /* Some generated single-stone masks contain only a coloured zig-zag\n     * through the centre of a heart. Tinting that seed produces the green or\n     * black stripe seen in the storefront. Reconstruct the full heart around\n     * the seed; the product's own photographed facets remain the texture. */\n    if (fillRatio < 0.5 && aspect > 1.65) {\n      /* The encoded seed ends around the upper facets, not at the true stone\n       * edge.  Cover the photographed heart through its lower point and add a\n       * two-pixel safety edge so Safari's antialiasing cannot reveal the\n       * original pink gemstone as a red fringe after recolouring. */\n      const size = Math.max(bounds.width * 1.36, bounds.height * 2.55);\n      const width = Math.min(maskCanvas.width, size);\n      const height = Math.min(maskCanvas.height, size * 1.04);\n      const cx = bounds.x + bounds.width / 2;\n      const cy = bounds.y + bounds.height / 2 + bounds.height * 0.55;\n      const left = cx - width / 2;\n      const top = cy - height / 2;\n      const right = cx + width / 2;\n      const bottom = cy + height / 2;\n      context.clearRect(0, 0, maskCanvas.width, maskCanvas.height);\n      context.fillStyle = '#fff';\n      context.beginPath();\n      context.moveTo(cx, bottom);\n      context.bezierCurveTo(cx - width * 0.14, top + height * 0.76, left, top + height * 0.55, left, top + height * 0.3);\n      context.bezierCurveTo(left, top + height * 0.06, cx - width * 0.18, top, cx, top + height * 0.22);\n      context.bezierCurveTo(cx + width * 0.18, top, right, top + height * 0.06, right, top + height * 0.3);\n      context.bezierCurveTo(right, top + height * 0.55, cx + width * 0.14, top + height * 0.76, cx, bottom);\n      context.closePath();\n      context.fill();\n      context.lineJoin = 'round';\n      context.lineWidth = 4;\n      context.strokeStyle = '#fff';\n      context.stroke();\n      repaired = {\n        x: Math.max(0, left - 2),\n        y: Math.max(0, top - 2),\n        width: Math.min(maskCanvas.width - Math.max(0, left - 2), width + 4),\n        height: Math.min(maskCanvas.height - Math.max(0, top - 2), height + 4),\n      };\n    } else if (fillRatio < 0.28) {\n      /* A few round/oval slots are similarly reduced to sparse highlight\n       * fragments. Their existing bounds are correct, so restore the solid\n       * oval without expanding into the surrounding metal setting. */\n      context.clearRect(0, 0, maskCanvas.width, maskCanvas.height);\n      context.fillStyle = '#fff';\n      context.beginPath();\n      context.ellipse(\n        bounds.x + bounds.width / 2,\n        bounds.y + bounds.height / 2,\n        bounds.width / 2,\n        bounds.height / 2,\n        0,\n        0,\n        Math.PI * 2,\n      );\n      context.fill();\n      repaired = { ...bounds };\n    }\n\n    if (!repaired) return false;\n    maskCanvas.craftdiyBounds = repaired;\n    maskCanvas.craftdiyMaskRepaired = true;\n    return true;\n  }\n\n  function createReferenceGemMask(textureImage, baseImage, width, height) {\n    if (!textureImage?.naturalWidth || !baseImage?.naturalWidth) return null;\n    const textureCanvas = document.createElement('canvas');\n    const baseCanvas = document.createElement('canvas');\n    textureCanvas.width = baseCanvas.width = width;\n    textureCanvas.height = baseCanvas.height = height;\n    const textureContext = textureCanvas.getContext('2d', { willReadFrequently: true });\n    const baseContext = baseCanvas.getContext('2d', { willReadFrequently: true });\n    textureContext.drawImage(textureImage, 0, 0, width, height);\n    baseContext.drawImage(baseImage, 0, 0, width, height);\n    const texture = textureContext.getImageData(0, 0, width, height);\n    const base = baseContext.getImageData(0, 0, width, height);\n    const referenceCanvas = document.createElement('canvas');\n    referenceCanvas.width = width;\n    referenceCanvas.height = height;\n    const referenceContext = referenceCanvas.getContext('2d');\n    const reference = referenceContext.createImageData(width, height);\n    let changedPixels = 0;\n\n    for (let offset = 0; offset < texture.data.length; offset += 4) {\n      const alpha = Math.min(texture.data[offset + 3], base.data[offset + 3]);\n      if (!alpha) continue;\n      const difference = Math.abs(texture.data[offset] - base.data[offset])\n        + Math.abs(texture.data[offset + 1] - base.data[offset + 1])\n        + Math.abs(texture.data[offset + 2] - base.data[offset + 2]);\n      /* Difference from the true empty setting is the boundary signal. Do not\n       * require colour here: April/diamond and pale aquamarine stones can be\n       * almost neutral yet still need a complete preview mask. */\n      if (difference < 20) continue;\n      reference.data[offset] = 255;\n      reference.data[offset + 1] = 255;\n      reference.data[offset + 2] = 255;\n      reference.data[offset + 3] = alpha;\n      changedPixels += 1;\n    }\n    if (changedPixels < 12) return null;\n    referenceContext.putImageData(reference, 0, 0);\n    return referenceCanvas;\n  }\n\n  function constrainMaskToReference(maskCanvas, referenceMask) {\n    if (!maskCanvas || !referenceMask) return false;\n    const context = maskCanvas.getContext('2d', { willReadFrequently: true });\n    const originalPixels = context.getImageData(0, 0, maskCanvas.width, maskCanvas.height).data;\n    let originalCount = 0;\n    for (let offset = 3; offset < originalPixels.length; offset += 4) {\n      if (originalPixels[offset] >= 10) originalCount += 1;\n    }\n    const candidateCanvas = document.createElement('canvas');\n    candidateCanvas.width = maskCanvas.width;\n    candidateCanvas.height = maskCanvas.height;\n    const candidateContext = candidateCanvas.getContext('2d', { willReadFrequently: true });\n    candidateContext.drawImage(maskCanvas, 0, 0);\n    candidateContext.globalCompositeOperation = 'destination-in';\n    candidateContext.drawImage(referenceMask, 0, 0, maskCanvas.width, maskCanvas.height);\n    const pixels = candidateContext.getImageData(0, 0, maskCanvas.width, maskCanvas.height).data;\n    let minX = maskCanvas.width;\n    let minY = maskCanvas.height;\n    let maxX = -1;\n    let maxY = -1;\n    let pixelCount = 0;\n    for (let offset = 3; offset < pixels.length; offset += 4) {\n      if (pixels[offset] < 10) continue;\n      const pixel = (offset - 3) / 4;\n      const x = pixel % maskCanvas.width;\n      const y = Math.floor(pixel / maskCanvas.width);\n      minX = Math.min(minX, x);\n      minY = Math.min(minY, y);\n      maxX = Math.max(maxX, x);\n      maxY = Math.max(maxY, y);\n      pixelCount += 1;\n    }\n    /* A few multi-stone source photos expose only some stones in colour. Do\n     * not erase a valid slot when its reference-difference signal is missing;\n     * keep the supplied SKU mask as the safe fallback for that slot. */\n    if (pixelCount < Math.max(12, originalCount * 0.15)) return false;\n    context.clearRect(0, 0, maskCanvas.width, maskCanvas.height);\n    context.drawImage(candidateCanvas, 0, 0);\n    maskCanvas.craftdiyBounds = {\n      x: minX,\n      y: minY,\n      width: maxX - minX + 1,\n      height: maxY - minY + 1,\n    };\n    maskCanvas.craftdiyReferenceConstrained = true;\n    return true;\n  }\n\n  function rgbToHsl(red, green, blue) {\n    const r = red / 255;\n    const g = green / 255;\n    const b = blue / 255;\n    const max = Math.max(r, g, b);\n    const min = Math.min(r, g, b);\n    const delta = max - min;\n    let hue = 0;\n    if (delta) {\n      if (max === r) hue = ((g - b) / delta) % 6;\n      else if (max === g) hue = (b - r) / delta + 2;\n      else hue = (r - g) / delta + 4;\n      hue /= 6;\n      if (hue < 0) hue += 1;\n    }\n    const lightness = (max + min) / 2;\n    const saturation = delta ? delta / (1 - Math.abs(2 * lightness - 1)) : 0;\n    return { hue, saturation, lightness };\n  }\n\n  function hslToRgb(hue, saturation, lightness) {\n    const chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;\n    const segment = ((hue % 1) + 1) % 1 * 6;\n    const x = chroma * (1 - Math.abs((segment % 2) - 1));\n    let red = 0;\n    let green = 0;\n    let blue = 0;\n    if (segment < 1) [red, green] = [chroma, x];\n    else if (segment < 2) [red, green] = [x, chroma];\n    else if (segment < 3) [green, blue] = [chroma, x];\n    else if (segment < 4) [green, blue] = [x, chroma];\n    else if (segment < 5) [red, blue] = [x, chroma];\n    else [red, blue] = [chroma, x];\n    const match = lightness - chroma / 2;\n    return [red, green, blue].map((channel) => Math.round((channel + match) * 255));\n  }\n\n  function parseTargetStoneColor(value) {\n    const match = String(value || '').trim().match(/^#([0-9a-f]{6})$/i);\n    if (!match) return rgbToHsl(220, 220, 220);\n    const integer = Number.parseInt(match[1], 16);\n    return rgbToHsl((integer >> 16) & 255, (integer >> 8) & 255, integer & 255);\n  }\n\n  function buildCroppedGemstoneLayer(maskCanvas, textureImage, color) {\n    const rawBounds = maskCanvas?.craftdiyBounds;\n    if (!rawBounds || !textureImage?.naturalWidth || !textureImage?.naturalHeight) return null;\n    const left = Math.max(0, Math.floor(rawBounds.x));\n    const top = Math.max(0, Math.floor(rawBounds.y));\n    const right = Math.min(maskCanvas.width, Math.ceil(rawBounds.x + rawBounds.width));\n    const bottom = Math.min(maskCanvas.height, Math.ceil(rawBounds.y + rawBounds.height));\n    const width = Math.max(1, right - left);\n    const height = Math.max(1, bottom - top);\n    const crop = document.createElement('canvas');\n    crop.width = width;\n    crop.height = height;\n    const cropContext = crop.getContext('2d', { willReadFrequently: true });\n    cropContext.imageSmoothingEnabled = true;\n    cropContext.imageSmoothingQuality = 'high';\n    const sourceScaleX = textureImage.naturalWidth / maskCanvas.width;\n    const sourceScaleY = textureImage.naturalHeight / maskCanvas.height;\n    cropContext.drawImage(\n      textureImage,\n      left * sourceScaleX,\n      top * sourceScaleY,\n      width * sourceScaleX,\n      height * sourceScaleY,\n      0,\n      0,\n      width,\n      height,\n    );\n    const sourcePixels = cropContext.getImageData(0, 0, width, height);\n\n    const maskCrop = document.createElement('canvas');\n    maskCrop.width = width;\n    maskCrop.height = height;\n    const maskContext = maskCrop.getContext('2d', { willReadFrequently: true });\n    maskContext.drawImage(maskCanvas, left, top, width, height, 0, 0, width, height);\n    const maskPixels = maskContext.getImageData(0, 0, width, height).data;\n    const target = parseTargetStoneColor(color);\n\n    for (let offset = 0; offset < sourcePixels.data.length; offset += 4) {\n      const maskAlpha = maskPixels[offset + 3];\n      if (!maskAlpha || !sourcePixels.data[offset + 3]) {\n        sourcePixels.data[offset + 3] = 0;\n        continue;\n      }\n      const source = rgbToHsl(\n        sourcePixels.data[offset],\n        sourcePixels.data[offset + 1],\n        sourcePixels.data[offset + 2],\n      );\n      /* Keep the photographed facet brightness pixel-for-pixel. Bright facets\n       * lose most saturation and remain white; dark internal reflections keep\n       * their depth. Only the hue family follows the selected birth month. */\n      const highlight = clamp((source.lightness - 0.68) / 0.3, 0, 1);\n      const textureStrength = 0.58 + source.saturation * 0.42;\n      const saturation = clamp(\n        target.saturation * textureStrength * (1 - highlight * 0.86),\n        0,\n        1,\n      );\n      const lightness = clamp(0.5 + (source.lightness - 0.5) * 1.12, 0, 1);\n      const [red, green, blue] = hslToRgb(target.hue, saturation, lightness);\n      sourcePixels.data[offset] = red;\n      sourcePixels.data[offset + 1] = green;\n      sourcePixels.data[offset + 2] = blue;\n      sourcePixels.data[offset + 3] = Math.min(sourcePixels.data[offset + 3], maskAlpha);\n    }\n    cropContext.putImageData(sourcePixels, 0, 0);\n    crop.craftdiyDestination = { x: left, y: top, width, height };\n    return crop;\n  }\n\n  function pointsForZone(zone, canvas) {\n    if (Array.isArray(zone.points) && zone.points.length > 2) {\n      return zone.points.map((point) => ({\n        x: percentX(point.x, canvas),\n        y: percentY(point.y, canvas),\n      }));\n    }\n    const cx = percentX(zone.x, canvas);\n    const cy = percentY(zone.y, canvas);\n    const halfW = percentX(zone.w, canvas) / 2;\n    const halfH = percentY(zone.h, canvas) / 2;\n    return [\n      { x: cx - halfW, y: cy - halfH },\n      { x: cx + halfW, y: cy - halfH },\n      { x: cx + halfW, y: cy + halfH },\n      { x: cx - halfW, y: cy + halfH },\n    ];\n  }\n\n  function boundsForPoints(points) {\n    const xs = points.map((point) => point.x);\n    const ys = points.map((point) => point.y);\n    const minX = Math.min(...xs);\n    const maxX = Math.max(...xs);\n    const minY = Math.min(...ys);\n    const maxY = Math.max(...ys);\n    return {\n      x: minX,\n      y: minY,\n      width: maxX - minX,\n      height: maxY - minY,\n      cx: (minX + maxX) / 2,\n      cy: (minY + maxY) / 2,\n    };\n  }\n\n  function beginZonePath(context, points) {\n    context.beginPath();\n    points.forEach((point, index) => {\n      if (index === 0) context.moveTo(point.x, point.y);\n      else context.lineTo(point.x, point.y);\n    });\n    context.closePath();\n  }\n\n  function isBlackTextZone(context, zone, canvas) {\n    if (!context || !zone || !canvas) return false;\n    const centerX = percentX(zone.x, canvas);\n    const centerY = percentY(zone.y, canvas);\n    const width = Math.max(2, percentX(Number(zone.w || 20), canvas));\n    const height = Math.max(2, percentY(Number(zone.h || 8), canvas));\n    const angle = (Number(zone.rotation || 0) * Math.PI) / 180;\n    const cos = Math.cos(angle);\n    const sin = Math.sin(angle);\n    const luminances = [];\n    let darkNeutral = 0;\n\n    for (let row = -2; row <= 2; row += 1) {\n      for (let column = -3; column <= 3; column += 1) {\n        const localX = (column / 3) * width * 0.38;\n        const localY = (row / 2) * height * 0.38;\n        const x = Math.round(centerX + localX * cos - localY * sin);\n        const y = Math.round(centerY + localX * sin + localY * cos);\n        if (x < 0 || y < 0 || x >= canvas.width || y >= canvas.height) continue;\n        const pixel = context.getImageData(x, y, 1, 1).data;\n        if (pixel[3] < 96) continue;\n        const red = pixel[0];\n        const green = pixel[1];\n        const blue = pixel[2];\n        const maximum = Math.max(red, green, blue);\n        const minimum = Math.min(red, green, blue);\n        const luminance = red * 0.2126 + green * 0.7152 + blue * 0.0722;\n        const chroma = maximum - minimum;\n        luminances.push(luminance);\n\n        /* Black-plated jewelry commonly contains bright, neutral reflections.\n         * Classify the complete engraving surface rather than requiring every\n         * sampled pixel to be near pure black. Gold and saturated stone colors\n         * remain excluded by the low-chroma requirement. */\n        if (luminance <= 185 && chroma <= 52) darkNeutral += 1;\n      }\n    }\n\n    if (luminances.length < 8) return false;\n    luminances.sort((left, right) => left - right);\n    const middle = Math.floor(luminances.length / 2);\n    const median = luminances.length % 2\n      ? luminances[middle]\n      : (luminances[middle - 1] + luminances[middle]) / 2;\n    return darkNeutral / luminances.length >= 0.55 && median <= 170;\n  }\n\n  class CraftdiyCustomizer extends HTMLElement {\n    constructor() {\n      super();\n      this.config = null;\n      this.baseImage = null;\n      this.textState = [];\n      this.whiteEngravingZoneIds = new Set();\n      this.photoState = [];\n      this.birthstoneState = [];\n      this.birthstoneSlotMasks = [];\n      this.birthstonePaletteImage = null;\n      this.birthstoneTextureImage = null;\n      this.birthstoneRasterEntry = null;\n      this.birthstoneRasterSprite = null;\n      this.ring1387SettingReference = null;\n      this.birthstoneColorCanvas = null;\n      this.birthstoneLayerCache = new WeakMap();\n      this.birthstoneRenderWarningShown = false;\n      this.renderQueued = false;\n      this.manifestCache = null;\n    }\n\n    connectedCallback() {\n      if (this.dataset.initialized === 'true') return;\n      this.dataset.initialized = 'true';\n      this.dataset.engineVersion = CORE_VERSION;\n      this.dataset.loadedRelease = RELEASE;\n      this.readyPromise = this.initialize().then(() => {\n        this.dispatchEvent(new CustomEvent('craftdiy:customizer-ready', {\n          bubbles: true,\n          detail: { customizer: this, config: this.config },\n        }));\n        return this;\n      }).catch((error) => {\n        this.showFatal(error);\n        throw error;\n      });\n    }\n\n    async initialize() {\n      this.classList.add('craftdiy-customizer');\n      this.inlineConfigText = this.querySelector('script[data-craftdiy-config]')?.textContent.trim() || '';\n      this.innerHTML = '<div class=\"craftdiy-customizer__loading\">Loading customizer\u2026</div>';\n      this.config = await this.loadConfig();\n      this.normalizeConfig();\n      this.seedState();\n      this.renderShell();\n      this.bindEvents();\n      await this.loadBaseImage();\n      await Promise.all([\n        this.loadBirthstoneAssets(),\n        this.loadBirthstoneRasterAssets(),\n        this.loadBundledFonts(),\n      ]);\n      this.queueCanvasRender();\n      this.syncPayload();\n    }\n\n    async loadConfig() {\n      if (this.inlineConfigText) return JSON.parse(this.inlineConfigText);\n\n      const configKey = this.dataset.configKey;\n      const manifestUrl = this.dataset.manifestUrl;\n      if (!configKey) throw new Error('Missing data-config-key.');\n      if (!manifestUrl) throw new Error('Missing data-manifest-url.');\n\n      if (!CraftdiyCustomizer.manifestPromises) CraftdiyCustomizer.manifestPromises = new Map();\n      if (!CraftdiyCustomizer.manifestPromises.has(manifestUrl)) {\n        CraftdiyCustomizer.manifestPromises.set(\n          manifestUrl,\n          fetch(manifestUrl, { credentials: 'same-origin' }).then((response) => {\n            if (!response.ok) throw new Error(`Cannot load manifest (${response.status}).`);\n            return response.json();\n          }),\n        );\n      }\n      const manifest = await CraftdiyCustomizer.manifestPromises.get(manifestUrl);\n      const config = manifest?.items?.[configKey];\n      if (!config) throw new Error(`Unknown customizer config: ${configKey}`);\n      return structuredClone(config);\n    }\n\n    normalizeConfig() {\n      this.config.key = this.config.key || this.dataset.configKey;\n      this.config.code = this.config.code || this.config.key;\n      this.config.defaultView = this.config.defaultView || 'front';\n      this.config.views = Array.isArray(this.config.views) && this.config.views.length\n        ? this.config.views\n        : [{ id: 'front', label: 'Front' }];\n      this.config.fonts = Array.isArray(this.config.fonts) && this.config.fonts.length\n        ? this.config.fonts\n        : FONT_OPTIONS.map(([key]) => key);\n      this.config.textZones = Array.isArray(this.config.textZones) ? this.config.textZones : [];\n      this.config.photoZones = Array.isArray(this.config.photoZones) ? this.config.photoZones : [];\n      const productHandle = String(this.dataset.productHandle || '');\n      const multilineLimits = MULTILINE_TEXT_LIMITS[productHandle];\n      const textLayoutOverride = TEXT_ZONE_LAYOUT_OVERRIDES[this.config.key];\n      if (textLayoutOverride && this.config.textZones[0]) {\n        Object.assign(this.config.textZones[0], textLayoutOverride, {\n          maxLines: 1,\n          align: 'center',\n        });\n      }\n      this.config.textZones.forEach((zone) => {\n        zone.view = zone.view || 'front';\n        zone.engraveDepth = Number(zone.engraveDepth || zone.engravingDepth || 1.3);\n        if (PATTERN_NUMBER_CONFIGS.has(this.config.key)) {\n          zone.defaultText = '';\n          zone.label = 'Pattern number';\n          zone.propertyName = 'Pattern number';\n          zone.placeholder = 'Enter pattern number';\n          zone.inputMode = 'numeric';\n          zone.maxChars = 4;\n          zone.maxLines = 1;\n          zone.minFontSize = Math.max(\n            Number(zone.minFontSize || 10),\n            Math.ceil(Number(zone.fontSize || 18) * NAME_MIN_FONT_RATIO),\n          );\n          return;\n        }\n        if (multilineLimits) {\n          zone.maxChars = multilineLimits.maxChars;\n          zone.maxLines = multilineLimits.maxLines;\n          zone.minFontSize = Number(zone.minFontSize || 10);\n          return;\n        }\n\n        /* Names and short inscriptions belong on one physical engraving\n         * surface. Keep them readable instead of shrinking four 50-character\n         * lines into a tag, ring or pendant. The 60% floor and per-zone limit\n         * were verified against all 1,114 text zones in the approved SKU map. */\n        const configuredFontSize = Number(zone.fontSize || 18);\n        const minFontSize = Math.max(\n          Number(zone.minFontSize || 10),\n          Math.ceil(configuredFontSize * NAME_MIN_FONT_RATIO),\n        );\n        const usableWidthAt1000 = Number(zone.w || 0) * 10 * 0.94;\n        const safeCharacters = Math.floor(\n          usableWidthAt1000 / Math.max(1, minFontSize * NAME_MAX_CHAR_WIDTH_RATIO),\n        );\n        zone.minFontSize = minFontSize;\n        zone.maxChars = clamp(safeCharacters, 12, 16);\n        zone.maxLines = 1;\n      });\n      this.config.photoZones.forEach((zone) => { zone.view = zone.view || 'front'; });\n      this.config.birthstoneSlots = Number(this.config.birthstoneSlots || 0);\n      this.config.birthstonePalette = this.config.birthstonePalette || null;\n      if (this.config.birthstonePalette) {\n        this.config.birthstonePalette.swatches = Array.isArray(this.config.birthstonePalette.swatches)\n          ? this.config.birthstonePalette.swatches\n          : [];\n      }\n      this.config.birthstonePreview = this.config.birthstonePreview || null;\n      const forcedBirthstoneSlots = BIRTHSTONE_SLOT_OVERRIDES[this.config.key];\n      if (Number.isInteger(forcedBirthstoneSlots)) {\n        /* Product 1387 has exactly two customer-selectable stones. This\n         * engine-level guard protects all three metal variants even if a\n         * browser temporarily receives an older manifest from the CDN. */\n        this.config.birthstoneSlots = forcedBirthstoneSlots;\n        if (this.config.birthstonePreview) {\n          this.config.birthstonePreview.slotCount = forcedBirthstoneSlots;\n        }\n        if (this.config.pairing === 'text_birthstone_by_index') {\n          this.config.textZones = this.config.textZones.slice(0, forcedBirthstoneSlots);\n        }\n        this.dataset.slotOverride = `two-stone-${this.config.key.split('/').pop()}`;\n      }\n      this.config.capabilities = this.config.capabilities || {\n        engraving: this.config.textZones.length > 0,\n        photo: this.config.photoZones.length > 0,\n        birthstone: this.config.birthstoneSlots > 0,\n      };\n    }\n\n    seedState() {\n      this.textState = this.config.textZones.map((zone) => ({\n        value: zone.defaultText === 'your text' ? '' : String(zone.defaultText || ''),\n        fontKey: zone.fontKey || 'signature',\n      }));\n      this.photoState = this.config.photoZones.map((zone) => ({\n        image: null,\n        file: null,\n        objectUrl: null,\n        zoom: Number(zone.zoom || 1),\n        offsetX: 0,\n        offsetY: 0,\n        rotation: Number(zone.photoRotation || 0),\n      }));\n      this.birthstoneState = Array.from(\n        { length: this.config.birthstoneSlots },\n        () => ({ month: '' }),\n      );\n    }\n\n    renderShell() {\n      this.innerHTML = `\n        <div class=\"craftdiy-customizer__layout craftdiy-customizer__layout--controls-only\">\n          <section class=\"craftdiy-customizer__controls\" aria-label=\"Customization options\">\n            ${this.renderControlMarkup()}\n            <div class=\"craftdiy-customizer__status\" data-status role=\"status\" aria-live=\"polite\" hidden></div>\n            <div class=\"craftdiy-customizer__actions\">\n              <button type=\"button\" class=\"craftdiy-button craftdiy-button--apply\" data-action=\"apply\">Apply preview to cart</button>\n            </div>\n            <p class=\"craftdiy-customizer__production-note\" style=\"margin:12px 0 0;font-size:11px;line-height:1.45;opacity:.72;\">\n              Preview text may extend slightly beyond the engraving area. Final placement and sizing will be adjusted by our production team.\n            </p>\n          </section>\n        </div>\n        <div class=\"craftdiy-customizer__production-canvas\" aria-hidden=\"true\">\n          <canvas data-preview-canvas></canvas>\n          <div data-canvas-loading hidden>Preparing preview\u2026</div>\n        </div>\n        <input type=\"hidden\" data-customization-json name=\"properties[_Customization JSON]\" value=\"\">\n      `;\n      this.canvas = this.querySelector('[data-preview-canvas]');\n      this.context = this.canvas.getContext('2d');\n    }\n\n    renderControlMarkup() {\n      const blocks = [];\n      if (this.config.textZones.length) blocks.push(this.renderTextControls());\n      if (this.config.birthstoneSlots && this.config.pairing !== 'text_birthstone_by_index') {\n        blocks.push(this.renderBirthstoneOnlyControls());\n      }\n      if (this.config.photoZones.length) blocks.push(this.renderPhotoControls());\n      if (!blocks.length) blocks.push('<p>No editable zones were found in this configuration.</p>');\n      return blocks.join('');\n    }\n\n    assetUrlFor(assetName) {\n      if (!assetName) return '';\n      const assetBase = this.dataset.assetBaseUrl?.replace(/\\/$/, '');\n      if (assetBase) return `${assetBase}/${assetName}`;\n      if (this.dataset.manifestUrl) {\n        try {\n          const manifestUrl = new URL(this.dataset.manifestUrl, location.href);\n          const assetUrl = new URL(assetName, manifestUrl);\n          if (!assetUrl.search && manifestUrl.search) assetUrl.search = manifestUrl.search;\n          return assetUrl.href;\n        } catch (error) {\n          // Fall through to the relative asset name for inline configurations.\n        }\n      }\n      return assetName;\n    }\n\n    async loadBundledFonts() {\n      if (!globalThis.FontFace || !document.fonts) return;\n      const source = this.assetUrlFor('sorealism.woff2');\n      if (!source) return;\n      if (!CraftdiyCustomizer.fontPromises) CraftdiyCustomizer.fontPromises = new Map();\n      if (!CraftdiyCustomizer.fontPromises.has(source)) {\n        CraftdiyCustomizer.fontPromises.set(source, (async () => {\n          const face = new FontFace('Craftdiy Sorealism', `url(\"${source}\") format(\"woff2\")`, {\n            style: 'normal',\n            weight: '400',\n          });\n          const loaded = await face.load();\n          document.fonts.add(loaded);\n          return loaded;\n        })().catch((error) => {\n          CraftdiyCustomizer.fontPromises.delete(source);\n          console.warn('[CRAFTDIY customizer] bundled signature font could not be loaded', error);\n          return null;\n        }));\n      }\n      await CraftdiyCustomizer.fontPromises.get(source);\n    }\n\n    birthstoneForMonth(month) {\n      const index = BIRTHSTONES.findIndex(([candidate]) => candidate === month);\n      if (index < 0) return null;\n      const fallback = BIRTHSTONES[index];\n      const source = this.config.birthstonePalette?.swatches?.[index];\n      return {\n        index,\n        month: fallback[0],\n        name: fallback[1],\n        color: source?.color || fallback[2],\n      };\n    }\n\n    birthstoneDotStyle(index) {\n      const fallback = BIRTHSTONES[index % BIRTHSTONES.length];\n      const source = this.config.birthstonePalette?.swatches?.[index];\n      const color = source?.color || fallback[2];\n      const spriteUrl = this.assetUrlFor(BIRTHSTONE_DOT_SPRITE_ASSET);\n      const position = `${(index / (BIRTHSTONES.length - 1)) * 100}% 50%`;\n      const image = spriteUrl ? `background-image:url('${spriteUrl}');` : '';\n      return `--stone:${color};--stone-position:${position};${image}`;\n    }\n\n    birthstoneEmptyDotStyle() {\n      return '--stone:#c99a55;--stone-position:0% 50%;background-image:none;opacity:.5;';\n    }\n\n    syncBirthstoneControl(index, month) {\n      const select = this.querySelector(`[data-birthstone-index=\"${index}\"]`);\n      if (select) select.value = month || '';\n      const dot = this.querySelector(`[data-birthstone-dot=\"${index}\"]`);\n      if (!dot) return;\n      const stone = this.birthstoneForMonth(month);\n      if (!stone) {\n        dot.dataset.empty = 'true';\n        dot.style.setProperty('--stone', '#c99a55');\n        dot.style.setProperty('--stone-position', '0% 50%');\n        dot.style.backgroundImage = 'none';\n        dot.style.opacity = '.5';\n        return;\n      }\n      const spriteUrl = this.assetUrlFor(BIRTHSTONE_DOT_SPRITE_ASSET);\n      dot.dataset.empty = 'false';\n      dot.style.setProperty('--stone', stone.color);\n      dot.style.setProperty('--stone-position', `${(stone.index / (BIRTHSTONES.length - 1)) * 100}% 50%`);\n      dot.style.backgroundImage = spriteUrl ? `url('${spriteUrl}')` : '';\n      dot.style.opacity = '1';\n    }\n\n    renderTextControls() {\n      const paired = this.config.capabilities.birthstone && this.config.pairing === 'text_birthstone_by_index';\n      const rows = this.config.textZones.map((zone, index) => {\n        const maxChars = Number(zone.maxChars || 50);\n        const selectedFontKey = FONT_MAP[zone.fontKey] ? zone.fontKey : 'signature';\n        const fonts = FONT_OPTIONS.map(([key, label]) => `<option value=\"${key}\"${key === selectedFontKey ? ' selected' : ''}>${label}</option>`).join('');\n        const fontChoices = FONT_OPTIONS.map(([key, label, stack, sample]) => `\n          <button type=\"button\" class=\"craftdiy-font-picker__option\" role=\"option\"\n            data-font-choice=\"${key}\" data-font-choice-index=\"${index}\"\n            aria-selected=\"${key === selectedFontKey ? 'true' : 'false'}\">\n            <span>${escapeHtml(label)}</span>\n            <em style=\"font-family:${escapeHtml(stack)}\">${escapeHtml(sample)}</em>\n          </button>`).join('');\n        const selectedFont = FONT_OPTIONS.find(([key]) => key === selectedFontKey) || FONT_OPTIONS[0];\n        const birthstone = paired && index < this.config.birthstoneSlots\n          ? `<label class=\"craftdiy-field craftdiy-field--birthstone\">\n              <span>Birthstone ${index + 1}</span>\n              <span class=\"craftdiy-select-wrap\">\n                <i data-birthstone-dot=\"${index}\" data-empty=\"true\" style=\"${this.birthstoneEmptyDotStyle()}\"></i>\n                <select data-birthstone-index=\"${index}\" autocomplete=\"off\">\n                  <option value=\"\" selected disabled>Choose a birthstone</option>\n                  ${BIRTHSTONES.map(([month, name]) => `<option value=\"${month}\">${month} \u00B7 ${name}</option>`).join('')}\n                </select>\n              </span>\n            </label>`\n          : '';\n        return `<div class=\"craftdiy-option-card\">\n          <div class=\"craftdiy-option-card__number\">${String(index + 1).padStart(2, '0')}</div>\n          <div class=\"craftdiy-option-card__fields\">\n            <label class=\"craftdiy-field\">\n              <span>${escapeHtml(zoneLabel(zone, index, 'Engraving'))}</span>\n              <textarea data-text-index=\"${index}\" maxlength=\"${maxChars * Math.max(1, Number(zone.maxLines || 1))}\" rows=\"${Math.min(4, Math.max(1, Number(zone.maxLines || 1)))}\" placeholder=\"${escapeHtml(zone.placeholder || 'Enter your text')}\" inputmode=\"${escapeHtml(zone.inputMode || 'text')}\" autocomplete=\"off\"></textarea>\n              <small><b data-character-count=\"${index}\">0</b> \u00B7 ${maxChars} characters per line \u00B7 ${Math.max(1, Number(zone.maxLines || 1))} line(s)</small>\n            </label>\n            <div class=\"craftdiy-field craftdiy-field--font\" role=\"group\" aria-label=\"Font\">\n              <span>Font</span>\n              <select class=\"craftdiy-font-native\" data-font-index=\"${index}\" tabindex=\"-1\" aria-hidden=\"true\">${fonts}</select>\n              <details class=\"craftdiy-font-picker\" data-font-picker-index=\"${index}\">\n                <summary>\n                  <span data-font-picker-label=\"${index}\">${escapeHtml(selectedFont[1])}</span>\n                  <em data-font-picker-sample=\"${index}\" style=\"font-family:${escapeHtml(selectedFont[2])}\">${escapeHtml(selectedFont[3])}</em>\n                </summary>\n                <div class=\"craftdiy-font-picker__menu\" role=\"listbox\" aria-label=\"Choose engraving font\">\n                  ${fontChoices}\n                </div>\n              </details>\n            </div>\n            ${birthstone}\n          </div>\n        </div>`;\n      });\n      return `<div class=\"craftdiy-customizer__module\">\n        <div class=\"craftdiy-customizer__module-title\"><span>01</span><h3>${paired ? 'Names & birthstones' : 'Engraving'}</h3></div>\n        ${rows.join('')}\n      </div>`;\n    }\n\n    renderBirthstoneOnlyControls() {\n      const rows = Array.from({ length: this.config.birthstoneSlots }, (_, index) => `\n        <div class=\"craftdiy-option-card\">\n          <div class=\"craftdiy-option-card__number\">${String(index + 1).padStart(2, '0')}</div>\n          <div class=\"craftdiy-option-card__fields\">\n            <label class=\"craftdiy-field craftdiy-field--birthstone\">\n              <span>Birthstone ${index + 1}</span>\n              <span class=\"craftdiy-select-wrap\">\n                <i data-birthstone-dot=\"${index}\" data-empty=\"true\" style=\"${this.birthstoneEmptyDotStyle()}\"></i>\n                <select data-birthstone-index=\"${index}\" autocomplete=\"off\">\n                  <option value=\"\" selected disabled>Choose a birthstone</option>\n                  ${BIRTHSTONES.map(([month, name]) => `<option value=\"${month}\">${month} \u00B7 ${name}</option>`).join('')}\n                </select>\n              </span>\n            </label>\n          </div>\n        </div>`);\n      return `<div class=\"craftdiy-customizer__module\">\n        <div class=\"craftdiy-customizer__module-title\"><span>${this.config.textZones.length ? '02' : '01'}</span><h3>Birthstones</h3></div>\n        ${rows.join('')}\n      </div>`;\n    }\n\n    renderPhotoControls() {\n      const precedingModules = Number(this.config.textZones.length > 0)\n        + Number(this.config.birthstoneSlots > 0 && this.config.pairing !== 'text_birthstone_by_index');\n      const moduleNumber = String(precedingModules + 1).padStart(2, '0');\n      const rows = this.config.photoZones.map((zone, index) => `<div class=\"craftdiy-option-card craftdiy-option-card--photo\">\n        <div class=\"craftdiy-option-card__number\">${String(index + 1).padStart(2, '0')}</div>\n        <div class=\"craftdiy-option-card__fields\">\n          <label class=\"craftdiy-upload\" data-upload-label=\"${index}\">\n            <input type=\"file\" accept=\"image/jpeg,image/png,image/webp\" data-photo-index=\"${index}\">\n            <span class=\"craftdiy-upload__icon\">\uFF0B</span>\n            <span><b>${escapeHtml(zoneLabel(zone, index, 'Photo'))}</b><small>JPG, PNG or WebP</small></span>\n          </label>\n          <div class=\"craftdiy-photo-tools\" data-photo-tools=\"${index}\" hidden>\n            <label>Zoom<input type=\"range\" min=\"1\" max=\"3\" step=\"0.01\" value=\"1\" data-photo-control=\"zoom\" data-photo-control-index=\"${index}\"></label>\n            <label>Left / right<input type=\"range\" min=\"-1\" max=\"1\" step=\"0.01\" value=\"0\" data-photo-control=\"offsetX\" data-photo-control-index=\"${index}\"></label>\n            <label>Up / down<input type=\"range\" min=\"-1\" max=\"1\" step=\"0.01\" value=\"0\" data-photo-control=\"offsetY\" data-photo-control-index=\"${index}\"></label>\n            <label>Rotate<input type=\"range\" min=\"-180\" max=\"180\" step=\"1\" value=\"${Number(zone.photoRotation || 0)}\" data-photo-control=\"rotation\" data-photo-control-index=\"${index}\"></label>\n          </div>\n        </div>\n      </div>`);\n      return `<div class=\"craftdiy-customizer__module\">\n        <div class=\"craftdiy-customizer__module-title\"><span>${moduleNumber}</span><h3>Photos</h3></div>\n        ${rows.join('')}\n      </div>`;\n    }\n\n    bindEvents() {\n      if (this.eventsBound) return;\n      this.eventsBound = true;\n      this.addEventListener('input', (event) => {\n        const target = event.target;\n        if (target.matches('[data-text-index]')) {\n          const index = Number(target.dataset.textIndex);\n          this.textState[index].value = target.value;\n          const counter = this.querySelector(`[data-character-count=\"${index}\"]`);\n          if (counter) counter.textContent = String(target.value.length);\n          this.onStateChange();\n        }\n        if (target.matches('[data-font-index]')) {\n          const index = Number(target.dataset.fontIndex);\n          this.textState[index].fontKey = target.value;\n          this.syncFontPicker(index, target.value);\n          this.onStateChange();\n        }\n        if (target.matches('[data-birthstone-index]')) {\n          const index = Number(target.dataset.birthstoneIndex);\n          this.birthstoneState[index].month = target.value;\n          this.syncBirthstoneControl(index, target.value);\n          this.onStateChange();\n        }\n        if (target.matches('[data-photo-control]')) {\n          const index = Number(target.dataset.photoControlIndex);\n          this.photoState[index][target.dataset.photoControl] = Number(target.value);\n          this.onStateChange();\n        }\n      });\n\n      this.addEventListener('change', (event) => {\n        const target = event.target;\n        if (target.matches('[data-photo-index]') && target.files?.[0]) {\n          this.loadPhoto(Number(target.dataset.photoIndex), target.files[0]);\n        }\n      });\n\n      this.addEventListener('click', (event) => {\n        const fontChoice = event.target.closest('[data-font-choice]');\n        if (fontChoice) {\n          const index = Number(fontChoice.dataset.fontChoiceIndex);\n          const fontKey = fontChoice.dataset.fontChoice;\n          const nativeSelect = this.querySelector(`[data-font-index=\"${index}\"]`);\n          if (this.textState[index] && FONT_MAP[fontKey]) {\n            this.textState[index].fontKey = fontKey;\n            if (nativeSelect) nativeSelect.value = fontKey;\n            this.syncFontPicker(index, fontKey);\n            const picker = this.querySelector(`[data-font-picker-index=\"${index}\"]`);\n            if (picker) picker.open = false;\n            this.onStateChange();\n          }\n          return;\n        }\n        const button = event.target.closest('[data-action]');\n        if (!button) return;\n        if (button.dataset.action === 'reset') this.reset();\n        if (button.dataset.action === 'download') this.downloadPreview();\n        if (button.dataset.action === 'apply') this.requestApply();\n      });\n    }\n\n    syncFontPicker(index, fontKey) {\n      const option = FONT_OPTIONS.find(([key]) => key === fontKey) || FONT_OPTIONS[0];\n      const label = this.querySelector(`[data-font-picker-label=\"${index}\"]`);\n      const sample = this.querySelector(`[data-font-picker-sample=\"${index}\"]`);\n      if (label) label.textContent = option[1];\n      if (sample) {\n        sample.textContent = option[3];\n        sample.style.fontFamily = option[2];\n      }\n      this.querySelectorAll(`[data-font-choice-index=\"${index}\"]`).forEach((button) => {\n        button.setAttribute('aria-selected', button.dataset.fontChoice === option[0] ? 'true' : 'false');\n      });\n    }\n\n    async loadBaseImage() {\n      const configured = this.dataset.baseImageUrl || this.config.image?.url;\n      const assetBase = this.dataset.assetBaseUrl?.replace(/\\/$/, '');\n      const fallback = assetBase && this.config.image?.shopifyAssetName\n        ? `${assetBase}/${this.config.image.shopifyAssetName}`\n        : null;\n      const originalSource = configured || fallback;\n      if (!originalSource) throw new Error('No base image URL was supplied.');\n\n      /* Every birthstone SKU opens on its verified v33 empty setting. If that\n       * exact asset is ever unavailable, fall back to the SKU's untouched\n       * product reference\u2014not a legacy grey or white-mask approximation. */\n      const preview = this.config.birthstonePreview;\n      const emptyAssetName = this.config.birthstoneSlots && this.config.key\n        ? (BIRTHSTONE_BASE_ASSET_OVERRIDES[this.config.key]\n          || preview?.emptySettingAssetName\n          || `craftdiy-empty-v33-${this.config.key.replace('/', '-')}.png`)\n        : '';\n      const referenceSource = preview?.textureAssetName\n        ? this.assetUrlFor(preview.textureAssetName)\n        : originalSource;\n      if (emptyAssetName) {\n        try {\n          this.baseImage = await this.createImage(this.assetUrlFor(emptyAssetName));\n          this.dataset.emptySettingAsset = emptyAssetName;\n        } catch (error) {\n          if (BIRTHSTONE_BASE_ASSET_OVERRIDES[this.config.key]) throw error;\n          console.warn('[CRAFTDIY customizer] v33 empty setting unavailable; using SKU reference artwork', error);\n          this.baseImage = await this.createImage(referenceSource);\n        }\n      } else {\n        this.baseImage = await this.createImage(originalSource);\n      }\n      this.canvas.width = Number(this.config.image?.width || this.baseImage.naturalWidth || 1000);\n      this.canvas.height = Number(this.config.image?.height || this.baseImage.naturalHeight || 1000);\n      this.refreshEngravingZoneColors();\n      this.querySelector('[data-canvas-loading]')?.remove();\n    }\n\n    refreshEngravingZoneColors() {\n      this.whiteEngravingZoneIds = new Set();\n      const zones = this.config?.textZones || [];\n      const forceWhite = WHITE_ENGRAVING_PRODUCT_HANDLES.has(this.dataset.productHandle)\n        || WHITE_ENGRAVING_SKUS.has(this.dataset.sku);\n      if (forceWhite) {\n        zones.forEach((zone) => this.whiteEngravingZoneIds.add(zone.id));\n        return;\n      }\n      if (this.dataset.engravingColor || !this.baseImage || !zones.length) return;\n\n      const sample = document.createElement('canvas');\n      sample.width = this.canvas.width;\n      sample.height = this.canvas.height;\n      const sampleContext = sample.getContext('2d', { willReadFrequently: true });\n      try {\n        sampleContext.drawImage(this.baseImage, 0, 0, sample.width, sample.height);\n        zones.forEach((zone) => {\n          if (isBlackTextZone(sampleContext, zone, sample)) {\n            this.whiteEngravingZoneIds.add(zone.id);\n          }\n        });\n      } catch (error) {\n        console.warn('[CRAFTDIY customizer] engraving surface colour could not be sampled', error);\n      }\n    }\n\n    usesWhiteEngraving(zone) {\n      return Boolean(zone?.id && this.whiteEngravingZoneIds.has(zone.id));\n    }\n\n    hasWhiteEngravingZones() {\n      return this.whiteEngravingZoneIds.size > 0;\n    }\n\n    async loadBirthstoneAssets() {\n      this.birthstoneSlotMasks = [];\n      this.birthstonePaletteImage = null;\n      this.birthstoneTextureImage = null;\n      this.birthstoneLayerCache = new WeakMap();\n      this.birthstoneRenderWarningShown = false;\n      if (BIRTHSTONE_BASE_ASSET_OVERRIDES[this.config.key]) return;\n\n      const preview = this.config.birthstonePreview;\n      const textureAssetName = preview?.textureAssetName;\n      if (textureAssetName) {\n        try {\n          this.birthstoneTextureImage = await this.createImage(this.assetUrlFor(textureAssetName));\n        } catch (error) {\n          console.warn('[CRAFTDIY customizer] original gemstone texture unavailable; using current base image', error);\n        }\n      }\n      const paletteAssetName = this.config.birthstonePalette?.spriteAssetName;\n      if (paletteAssetName) {\n        try {\n          this.birthstonePaletteImage = await this.createImage(this.assetUrlFor(paletteAssetName));\n        } catch (error) {\n          console.warn('[CRAFTDIY customizer] real gemstone sprite unavailable; using colour fallback', error);\n        }\n      }\n\n      /* A single compact v33 mask map contains the verified, per-SKU position\n       * of every setting. It replaces hundreds of extra gemstone PNG files,\n       * while the gemstone facets still come from each product's own reference\n       * photo. This prevents cross-product offsets and the old grey fallback. */\n      if (this.config.birthstoneSlots) {\n        try {\n          if (!birthstoneMaskMapPromise) {\n            birthstoneMaskMapPromise = fetch(this.assetUrlFor(BIRTHSTONE_MASK_MAP_ASSET), {\n              credentials: 'same-origin',\n            }).then((response) => {\n              if (!response.ok) throw new Error(`Cannot load v33 birthstone mask map (${response.status}).`);\n              return response.json();\n            }).catch((error) => {\n              birthstoneMaskMapPromise = null;\n              throw error;\n            });\n          }\n          const maskMap = await birthstoneMaskMapPromise;\n          const entry = maskMap?.configs?.[this.config.key];\n          if (!Array.isArray(entry?.slots)\n            || entry.slots.length < Number(this.config.birthstoneSlots || 0)) {\n            throw new Error(`No complete v33 slot map is registered for ${this.config.key}.`);\n          }\n          this.birthstoneSlotMasks = entry.slots\n            .slice(0, Number(this.config.birthstoneSlots || 0))\n            .map((slot, slotIndex) => {\n              const maskCanvas = document.createElement('canvas');\n              maskCanvas.width = this.canvas.width;\n              maskCanvas.height = this.canvas.height;\n              const maskContext = maskCanvas.getContext('2d');\n              maskContext.fillStyle = '#fff';\n              const runs = Array.isArray(slot.runs) ? slot.runs : [];\n              for (let index = 0; index + 2 < runs.length; index += 3) {\n                const y = Number(runs[index]);\n                const startX = Number(runs[index + 1]);\n                const endX = Number(runs[index + 2]);\n                if (!Number.isFinite(y) || !Number.isFinite(startX) || !Number.isFinite(endX)) continue;\n                maskContext.fillRect(startX, y, Math.max(1, endX - startX + 1), 1);\n              }\n              maskCanvas.craftdiySlotIndex = slotIndex;\n              maskCanvas.craftdiyBounds = { ...slot.bounds };\n              maskCanvas.craftdiyVerifiedV33 = true;\n              return maskCanvas;\n            });\n          return;\n        } catch (error) {\n          console.warn('[CRAFTDIY customizer] v33 verified slot map unavailable; trying encoded mask fallback', error);\n        }\n      }\n\n      const fallbackMaskAsset = preview?.sourceMaskAssetName || preview?.maskAssetName;\n      if (!fallbackMaskAsset || !this.config.birthstoneSlots) return;\n      const source = this.assetUrlFor(fallbackMaskAsset);\n      if (!source) return;\n\n      try {\n        const maskImage = await this.createImage(source);\n        let referenceGemMask = null;\n        try {\n          referenceGemMask = createReferenceGemMask(\n            this.birthstoneTextureImage,\n            this.baseImage,\n            this.canvas.width,\n            this.canvas.height,\n          );\n        } catch (error) {\n          console.warn('[CRAFTDIY customizer] product reference gemstone boundary unavailable', error);\n        }\n        const encodedCanvas = document.createElement('canvas');\n        encodedCanvas.width = this.canvas.width;\n        encodedCanvas.height = this.canvas.height;\n        const encodedContext = encodedCanvas.getContext('2d', { willReadFrequently: true });\n        encodedContext.imageSmoothingEnabled = false;\n        encodedContext.drawImage(maskImage, 0, 0, encodedCanvas.width, encodedCanvas.height);\n        const encoded = encodedContext.getImageData(0, 0, encodedCanvas.width, encodedCanvas.height);\n\n        this.birthstoneSlotMasks = Array.from({ length: this.config.birthstoneSlots }, (_, slotIndex) => {\n          const maskCanvas = document.createElement('canvas');\n          maskCanvas.width = encodedCanvas.width;\n          maskCanvas.height = encodedCanvas.height;\n          const maskContext = maskCanvas.getContext('2d');\n          const maskData = maskContext.createImageData(maskCanvas.width, maskCanvas.height);\n          const target = SLOT_MASK_COLORS[slotIndex % SLOT_MASK_COLORS.length];\n          let minX = maskCanvas.width;\n          let minY = maskCanvas.height;\n          let maxX = -1;\n          let maxY = -1;\n          let pixelCount = 0;\n          for (let offset = 0; offset < encoded.data.length; offset += 4) {\n            if (!encoded.data[offset + 3]) continue;\n            const distance = Math.abs(encoded.data[offset] - target[0])\n              + Math.abs(encoded.data[offset + 1] - target[1])\n              + Math.abs(encoded.data[offset + 2] - target[2]);\n            if (distance > 18) continue;\n            maskData.data[offset] = 255;\n            maskData.data[offset + 1] = 255;\n            maskData.data[offset + 2] = 255;\n            maskData.data[offset + 3] = encoded.data[offset + 3];\n            pixelCount += 1;\n            const pixel = offset / 4;\n            const x = pixel % maskCanvas.width;\n            const y = Math.floor(pixel / maskCanvas.width);\n            minX = Math.min(minX, x);\n            minY = Math.min(minY, y);\n            maxX = Math.max(maxX, x);\n            maxY = Math.max(maxY, y);\n          }\n          maskContext.putImageData(maskData, 0, 0);\n          maskCanvas.craftdiyBounds = maxX >= minX && maxY >= minY\n            ? { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 }\n            : { x: 0, y: 0, width: maskCanvas.width, height: maskCanvas.height };\n          maskCanvas.craftdiySlotIndex = slotIndex;\n          repairMalformedBirthstoneMask(maskCanvas, pixelCount);\n          constrainMaskToReference(maskCanvas, referenceGemMask);\n          return maskCanvas;\n        });\n      } catch (error) {\n        this.birthstoneSlotMasks = [];\n        console.warn('[CRAFTDIY customizer] birthstone preview disabled', error);\n      }\n    }\n\n    async loadBirthstoneRasterAssets() {\n      this.birthstoneRasterEntry = null;\n      this.birthstoneRasterSprite = null;\n      this.ring1387SettingReference = null;\n      this.fittedBirthstoneMasks = null;\n      this.fittedBirthstoneCache = new Map();\n      if (!this.config.birthstoneSlots || !this.config.key) return;\n\n      if (BIRTHSTONE_BASE_ASSET_OVERRIDES[this.config.key]) {\n        try {\n          const settingAssetName = RING1387_SETTING_REFERENCE_ASSETS[this.config.key];\n          const maskEntries = RING1387_MASK_ASSETS[this.config.key] || [];\n          const [settingReference, ...maskImages] = await Promise.all([\n            this.createImage(this.assetUrlFor(settingAssetName)),\n            ...maskEntries.map((entry) => this.createImage(this.assetUrlFor(entry.assetName))),\n          ]);\n          if (settingReference.naturalWidth !== 1000 || settingReference.naturalHeight !== 1000) {\n            throw new Error('The two-heart setting reference does not match its immutable asset revision.');\n          }\n          if (maskEntries.length !== 2 || maskImages.length !== 2\n            || maskImages.some((image) => image.naturalWidth !== 1000 || image.naturalHeight !== 1000)) {\n            throw new Error('The two-heart fitted masks do not match their immutable asset revision.');\n          }\n          this.ring1387SettingReference = settingReference;\n          this.fittedBirthstoneMasks = maskImages.map((image, index) => {\n            const mask = document.createElement('canvas');\n            mask.width = 1000;\n            mask.height = 1000;\n            mask.getContext('2d').drawImage(image, 0, 0);\n            mask.craftdiyBounds = { ...maskEntries[index].bounds };\n            mask.craftdiyPixelCount = maskEntries[index].pixels;\n            return mask;\n          });\n        } catch (error) {\n          this.ring1387SettingReference = null;\n          this.fittedBirthstoneMasks = null;\n          console.warn('[CRAFTDIY customizer] two-heart preview assets unavailable; controls remain enabled', error);\n        }\n        return;\n      }\n\n      const manifestAssetName = this.config.birthstonePreview?.gemCropManifestAssetName\n        || GEM_CROP_MANIFEST_ASSET;\n      const manifestUrl = this.assetUrlFor(manifestAssetName);\n      try {\n        if (!gemCropManifestPromise) {\n          gemCropManifestPromise = fetch(manifestUrl, { credentials: 'same-origin' })\n            .then((response) => {\n              if (!response.ok) throw new Error(`Cannot load v33 gemstone atlas map (${response.status}).`);\n              return response.json();\n            }).catch((error) => {\n              gemCropManifestPromise = null;\n              throw error;\n            });\n        }\n        const manifest = await gemCropManifestPromise;\n        const entry = manifest?.configs?.[this.config.key];\n        const expectedSlots = Number(this.config.birthstoneSlots || 0);\n        if (!entry || !Number(entry.tileWidth)\n          || !Array.isArray(entry.slots) || entry.slots.length < expectedSlots) {\n          throw new Error(`No complete v33 gemstone atlas is registered for ${this.config.key}.`);\n        }\n        const spriteAssetName = entry.assetName || this.config.birthstonePreview?.gemCropAssetName;\n        if (!spriteAssetName) throw new Error(`Missing v33 gemstone atlas image for ${this.config.key}.`);\n        const sprite = await this.createImage(this.assetUrlFor(spriteAssetName));\n        const tileWidth = Number(entry.tileWidth);\n        if (sprite.naturalWidth !== tileWidth * BIRTHSTONES.length) {\n          throw new Error(`Invalid v33 gemstone atlas width for ${this.config.key}.`);\n        }\n        const rasterSlotsToValidate = entry.slots.slice(0, expectedSlots);\n        rasterSlotsToValidate.forEach((slot, index) => {\n          const values = ['sourceY', 'x', 'y', 'width', 'height'].map((name) => Number(slot[name]));\n          if (values.some((value) => !Number.isFinite(value) || value < 0)\n            || values[3] < 1 || values[4] < 1\n            || values[0] + values[4] > sprite.naturalHeight\n            || values[1] + values[3] > this.canvas.width\n            || values[2] + values[4] > this.canvas.height) {\n            throw new Error(`Invalid v33 gemstone atlas slot ${index + 1} for ${this.config.key}.`);\n          }\n        });\n        this.birthstoneRasterEntry = entry;\n        this.birthstoneRasterSprite = sprite;\n      } catch (error) {\n        console.warn('[CRAFTDIY customizer] v33 real-gem atlas unavailable; using texture fallback', error);\n      }\n    }\n\n    createFittedBirthstoneMasks(settingReference) {\n      const width = this.baseImage.naturalWidth;\n      const height = this.baseImage.naturalHeight;\n      if (width !== 1000 || height !== 1000) throw new Error('Unexpected two-heart base dimensions.');\n      const sourceCanvas = document.createElement('canvas');\n      sourceCanvas.width = width;\n      sourceCanvas.height = height;\n      const sourceContext = sourceCanvas.getContext('2d', { willReadFrequently: true });\n      sourceContext.drawImage(this.baseImage, 0, 0);\n      const sourcePixels = sourceContext.getImageData(0, 0, width, height).data;\n      const settingCanvas = document.createElement('canvas');\n      settingCanvas.width = width;\n      settingCanvas.height = height;\n      const settingContext = settingCanvas.getContext('2d', { willReadFrequently: true });\n      settingContext.drawImage(settingReference, 0, 0);\n      const settingPixels = settingContext.getImageData(0, 0, width, height).data;\n      const regions = [\n        { left: 340, right: 535, top: 490, bottom: 680 },\n        { left: 465, right: 660, top: 490, bottom: 680 },\n      ];\n\n      return regions.map((region, slotIndex) => {\n        const silhouette = document.createElement('canvas');\n        silhouette.width = width;\n        silhouette.height = height;\n        const silhouetteContext = silhouette.getContext('2d', { willReadFrequently: true });\n        silhouetteContext.beginPath();\n        if (slotIndex === 0) {\n          silhouetteContext.moveTo(462, 674);\n          silhouetteContext.bezierCurveTo(435, 651, 368, 614, 354, 568);\n          silhouetteContext.bezierCurveTo(343, 532, 365, 505, 397, 505);\n          silhouetteContext.bezierCurveTo(421, 498, 439, 515, 446, 541);\n          silhouetteContext.bezierCurveTo(451, 511, 471, 490, 498, 494);\n          silhouetteContext.bezierCurveTo(523, 502, 535, 532, 526, 566);\n          silhouetteContext.bezierCurveTo(516, 610, 485, 650, 462, 674);\n        } else {\n          silhouetteContext.moveTo(538, 674);\n          silhouetteContext.bezierCurveTo(510, 649, 482, 611, 475, 568);\n          silhouetteContext.bezierCurveTo(469, 528, 484, 495, 513, 493);\n          silhouetteContext.bezierCurveTo(541, 486, 560, 500, 564, 541);\n          silhouetteContext.bezierCurveTo(567, 522, 584, 504, 607, 505);\n          silhouetteContext.bezierCurveTo(639, 507, 657, 536, 645, 573);\n          silhouetteContext.bezierCurveTo(632, 614, 571, 653, 538, 674);\n        }\n        silhouetteContext.closePath();\n        silhouetteContext.fillStyle = '#fff';\n        silhouetteContext.fill();\n        if (slotIndex === 0) silhouetteContext.fillRect(410, 495, 95, 62);\n        else silhouetteContext.fillRect(495, 492, 76, 72);\n        const silhouettePixels = silhouetteContext.getImageData(0, 0, width, height).data;\n\n        const mask = document.createElement('canvas');\n        mask.width = width;\n        mask.height = height;\n        const maskContext = mask.getContext('2d');\n        const maskData = maskContext.createImageData(width, height);\n        let pixelCount = 0;\n        let minX = width, minY = height, maxX = 0, maxY = 0;\n        for (let y = region.top; y <= region.bottom; y += 1) {\n          for (let x = region.left; x <= region.right; x += 1) {\n            const offset = (y * width + x) * 4;\n            if (!silhouettePixels[offset + 3]) continue;\n            const difference = Math.abs(sourcePixels[offset] - settingPixels[offset])\n              + Math.abs(sourcePixels[offset + 1] - settingPixels[offset + 1])\n              + Math.abs(sourcePixels[offset + 2] - settingPixels[offset + 2]);\n            if (difference < 24) continue;\n            const source = rgbToHsl(\n              sourcePixels[offset],\n              sourcePixels[offset + 1],\n              sourcePixels[offset + 2],\n            );\n            const hueMatchesFactoryGem = slotIndex === 0\n              ? (source.hue > 0.72 || source.hue < 0.025)\n              : (source.hue > 0.38 && source.hue < 0.82);\n            if (!hueMatchesFactoryGem || source.saturation <= 0.08 || source.lightness >= 0.98) continue;\n            maskData.data[offset] = 255;\n            maskData.data[offset + 1] = 255;\n            maskData.data[offset + 2] = 255;\n            maskData.data[offset + 3] = 255;\n            pixelCount += 1;\n            minX = Math.min(minX, x); maxX = Math.max(maxX, x);\n            minY = Math.min(minY, y); maxY = Math.max(maxY, y);\n          }\n        }\n        if (pixelCount < 10000 || pixelCount > 18000) {\n          throw new Error('Unable to isolate the photographed two-heart gemstone pixels.');\n        }\n        maskContext.putImageData(maskData, 0, 0);\n        mask.craftdiyBounds = { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 };\n        mask.craftdiyPixelCount = pixelCount;\n        return mask;\n      });\n    }\n\n    drawFittedBirthstones(context, metrics = { scale: 1, offsetX: 0, offsetY: 0 }, renderScale = 1) {\n      context.save();\n      context.setTransform(metrics.scale * renderScale, 0, 0, metrics.scale * renderScale,\n        metrics.offsetX * renderScale, metrics.offsetY * renderScale);\n      this.fittedBirthstoneMasks.forEach((mask, index) => {\n        const month = this.birthstoneState[index]?.month;\n        const stone = month ? this.birthstoneForMonth(month) : null;\n        if (!stone) return;\n        const key = `factory-facet:${index}:${stone.index}`;\n        let layer = this.fittedBirthstoneCache.get(key);\n        if (!layer) {\n          layer = buildCroppedGemstoneLayer(mask, this.baseImage, stone.color);\n          if (!layer) return;\n          this.fittedBirthstoneCache.set(key, layer);\n        }\n        const destination = layer.craftdiyDestination;\n        context.drawImage(layer, destination.x, destination.y, destination.width, destination.height);\n      });\n      context.restore();\n    }\n\n    createImage(source) {\n      return new Promise((resolve, reject) => {\n        const image = new Image();\n        if (!source.startsWith('data:') && !source.startsWith('blob:')) image.crossOrigin = 'anonymous';\n        image.onload = () => resolve(image);\n        image.onerror = () => reject(new Error(`Could not load image: ${source}`));\n        image.src = source;\n      });\n    }\n\n    async loadPhoto(index, file) {\n      const zone = this.config.photoZones[index];\n      const state = this.photoState[index];\n      if (state.objectUrl) URL.revokeObjectURL(state.objectUrl);\n      state.objectUrl = URL.createObjectURL(file);\n      try {\n        const image = await this.createImage(state.objectUrl);\n        state.image = image;\n        state.file = file;\n        const minWidth = Number(zone.minWidth || 0);\n        const minHeight = Number(zone.minHeight || 0);\n        const lowResolution = image.naturalWidth < minWidth || image.naturalHeight < minHeight;\n        const label = this.querySelector(`[data-upload-label=\"${index}\"]`);\n        label?.classList.add('is-loaded');\n        const title = label?.querySelector('b');\n        if (title) title.textContent = file.name;\n        const tools = this.querySelector(`[data-photo-tools=\"${index}\"]`);\n        if (tools) tools.hidden = false;\n        this.setStatus(lowResolution\n          ? `Photo ${index + 1} is below the recommended ${minWidth}\u00D7${minHeight}px resolution.`\n          : `Photo ${index + 1} added.`, lowResolution ? 'warning' : 'success');\n        this.onStateChange();\n        this.dispatchEvent(new CustomEvent('craftdiy:photo-selected', {\n          bubbles: true,\n          detail: { customizer: this, index, zone, file, image },\n        }));\n      } catch (error) {\n        this.setStatus('This photo could not be opened. Please try another JPG, PNG or WebP.', 'error');\n        console.warn('[CRAFTDIY customizer] photo preview could not be opened', error);\n      }\n    }\n\n    onStateChange() {\n      this.queueCanvasRender();\n      this.syncPayload();\n    }\n\n    queueCanvasRender() {\n      if (this.renderQueued || !this.baseImage || !this.canvas) return;\n      this.renderQueued = true;\n      requestAnimationFrame(() => {\n        this.renderQueued = false;\n        this.drawCanvas();\n      });\n    }\n\n    drawCanvas() {\n      const context = this.context;\n      const canvas = this.canvas;\n      context.clearRect(0, 0, canvas.width, canvas.height);\n      context.fillStyle = '#fff';\n      context.fillRect(0, 0, canvas.width, canvas.height);\n      const allFittedStonesSelected = Boolean(this.fittedBirthstoneMasks?.length)\n        && this.birthstoneState.length > 0\n        && this.birthstoneState.every((state) => Boolean(state?.month));\n      const visibleBaseImage = this.ring1387SettingReference && !allFittedStonesSelected\n        ? this.ring1387SettingReference\n        : this.baseImage;\n      context.drawImage(visibleBaseImage, 0, 0, canvas.width, canvas.height);\n      this.config.photoZones.forEach((zone, index) => this.drawPhotoZone(zone, this.photoState[index]));\n      this.drawBirthstones();\n      this.config.textZones.forEach((zone, index) => this.drawTextZone(zone, this.textState[index]));\n    }\n\n    drawBirthstones() {\n      if (this.fittedBirthstoneMasks) {\n        this.drawFittedBirthstones(this.context);\n        return;\n      }\n      if (this.birthstoneRasterEntry && this.birthstoneRasterSprite) {\n        const entry = this.birthstoneRasterEntry;\n        const sprite = this.birthstoneRasterSprite;\n        const tileWidth = Number(entry.tileWidth);\n        const drawRasterStone = (slot, stoneIndex) => {\n          const width = Number(slot.width);\n          const height = Number(slot.height);\n          this.context.drawImage(\n            sprite,\n            Number(stoneIndex) * tileWidth,\n            Number(slot.sourceY),\n            width,\n            height,\n            Number(slot.x),\n            Number(slot.y),\n            width,\n            height,\n          );\n        };\n        entry.slots.slice(0, Number(this.config.birthstoneSlots || 0)).forEach((slot, index) => {\n          const state = this.birthstoneState[index];\n          const stone = state?.month ? this.birthstoneForMonth(state.month) : null;\n          if (!stone) return;\n          drawRasterStone(slot, stone.index);\n        });\n        return;\n      }\n      if (!this.birthstoneSlotMasks.length) return;\n      const context = this.context;\n      if (!this.birthstoneColorCanvas\n        || this.birthstoneColorCanvas.width !== this.canvas.width\n        || this.birthstoneColorCanvas.height !== this.canvas.height) {\n        this.birthstoneColorCanvas = document.createElement('canvas');\n        this.birthstoneColorCanvas.width = this.canvas.width;\n        this.birthstoneColorCanvas.height = this.canvas.height;\n      }\n      const colorLayer = this.birthstoneColorCanvas;\n      const colorContext = colorLayer.getContext('2d');\n      this.birthstoneSlotMasks.forEach((mask, index) => {\n        const state = this.birthstoneState[index];\n        if (!state?.month || !mask) return;\n        const stone = this.birthstoneForMonth(state.month);\n        if (!stone) return;\n        this.paintBirthstoneLayer(colorLayer, mask, stone);\n\n        context.save();\n        context.globalAlpha = 1;\n        context.globalCompositeOperation = 'source-over';\n        context.drawImage(colorLayer, 0, 0, this.canvas.width, this.canvas.height);\n        context.restore();\n      });\n    }\n\n    paintBirthstoneLayer(targetCanvas, mask, stone) {\n      const targetContext = targetCanvas.getContext('2d');\n      targetContext.setTransform(1, 0, 0, 1, 0, 0);\n      targetContext.globalCompositeOperation = 'source-over';\n      targetContext.globalAlpha = 1;\n      targetContext.filter = 'none';\n      targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height);\n      targetContext.imageSmoothingEnabled = true;\n      targetContext.imageSmoothingQuality = 'high';\n\n      const textureImage = this.birthstoneTextureImage;\n      if (textureImage?.naturalWidth && textureImage?.naturalHeight) {\n        let maskCache = this.birthstoneLayerCache.get(mask);\n        if (!maskCache) {\n          maskCache = new Map();\n          this.birthstoneLayerCache.set(mask, maskCache);\n        }\n        const cacheKey = `${stone.index}:${stone.color}`;\n        let croppedLayer = maskCache.get(cacheKey);\n        if (!croppedLayer) {\n          try {\n            croppedLayer = buildCroppedGemstoneLayer(mask, textureImage, stone.color);\n            if (croppedLayer) maskCache.set(cacheKey, croppedLayer);\n          } catch (error) {\n            console.warn('[CRAFTDIY customizer] SKU gemstone crop could not be rendered', error);\n          }\n        }\n        const destination = croppedLayer?.craftdiyDestination;\n        if (croppedLayer && destination) {\n          targetContext.drawImage(\n            croppedLayer,\n            destination.x,\n            destination.y,\n            destination.width,\n            destination.height,\n          );\n          return targetCanvas;\n        }\n      }\n\n      /* Last-resort compatibility renderer. This keeps a selected stone\n       * coloured and faceted even if a theme asset is temporarily missing;\n       * unlike the old failure path it never silently exposes the grey base. */\n      const palette = this.birthstonePaletteImage;\n      const bounds = mask?.craftdiyBounds;\n      if (palette?.naturalWidth && palette?.naturalHeight && bounds?.width && bounds?.height) {\n        const sourceWidth = palette.naturalWidth / BIRTHSTONES.length;\n        const insetX = sourceWidth * 0.08;\n        const insetY = palette.naturalHeight * 0.08;\n        targetContext.drawImage(\n          palette,\n          Number(stone.index || 0) * sourceWidth + insetX,\n          insetY,\n          sourceWidth - insetX * 2,\n          palette.naturalHeight - insetY * 2,\n          bounds.x,\n          bounds.y,\n          bounds.width,\n          bounds.height,\n        );\n        targetContext.globalCompositeOperation = 'destination-in';\n        targetContext.drawImage(mask, 0, 0, targetCanvas.width, targetCanvas.height);\n        targetContext.globalCompositeOperation = 'source-over';\n        if (!this.birthstoneRenderWarningShown) {\n          this.birthstoneRenderWarningShown = true;\n          console.warn('[CRAFTDIY customizer] gemstone texture fallback is active');\n        }\n      }\n\n      targetContext.globalAlpha = 1;\n      targetContext.globalCompositeOperation = 'source-over';\n      return targetCanvas;\n    }\n\n    drawPhotoZone(zone, state) {\n      if (!state?.image) return;\n      const context = this.context;\n      const points = pointsForZone(zone, this.canvas);\n      const bounds = boundsForPoints(points);\n      const imageWidth = state.image.naturalWidth || state.image.width;\n      const imageHeight = state.image.naturalHeight || state.image.height;\n      const cover = Math.max(bounds.width / imageWidth, bounds.height / imageHeight);\n      const configuredScale = Number(zone.coverScale || 1);\n      const scale = cover * configuredScale * Number(state.zoom || 1);\n      const width = imageWidth * scale;\n      const height = imageHeight * scale;\n      const offsetX = Number(state.offsetX || 0) * bounds.width * 0.5;\n      const offsetY = Number(state.offsetY || 0) * bounds.height * 0.5;\n\n      context.save();\n      beginZonePath(context, points);\n      context.clip();\n      context.translate(bounds.cx + offsetX, bounds.cy + offsetY);\n      context.rotate(((Number(zone.rotation || 0) + Number(state.rotation || 0)) * Math.PI) / 180);\n      context.drawImage(state.image, -width / 2, -height / 2, width, height);\n      context.restore();\n    }\n\n    drawTextZone(zone, state) {\n      const value = String(state?.value || '');\n      if (!value) return;\n      const context = this.context;\n      const points = pointsForZone(zone, this.canvas);\n      const bounds = boundsForPoints(points);\n      const hasCustomPoints = Array.isArray(zone.points) && zone.points.length >= 3;\n      const zoneWidth = hasCustomPoints\n        ? bounds.width\n        : percentX(Number(zone.w || 20), this.canvas);\n      const zoneHeight = hasCustomPoints\n        ? bounds.height\n        : percentY(Number(zone.h || 8), this.canvas);\n      const configuredSize = Number(zone.fontSize || 18) * (this.canvas.width / 1000);\n      const minSize = Number(zone.minFontSize || 8) * (this.canvas.width / 1000);\n      let fontSize = Math.max(minSize, configuredSize);\n      const family = FONT_MAP[state.fontKey] || FONT_MAP.signature;\n      const weight = zone.bold ? '700' : '400';\n      const style = zone.italic ? 'italic' : 'normal';\n      const maxWidth = Math.max(4, zoneWidth * 0.94);\n\n      context.save();\n      if (hasCustomPoints) {\n        beginZonePath(context, points);\n        if (zone.clip !== false) context.clip();\n        context.translate(percentX(zone.x, this.canvas), percentY(zone.y, this.canvas));\n        context.rotate((Number(zone.rotation || 0) * Math.PI) / 180);\n      } else {\n        /*\n         * Text rectangles in the manifests are defined in their own rotated\n         * coordinate space. Clipping before rotation cuts diagonal engraving\n         * down to a small fragment. Move into that coordinate space first so\n         * the clip, fitting measurements and rendered text stay aligned.\n         */\n        context.translate(percentX(zone.x, this.canvas), percentY(zone.y, this.canvas));\n        context.rotate((Number(zone.rotation || 0) * Math.PI) / 180);\n        if (zone.clip !== false) {\n          context.beginPath();\n          context.rect(-zoneWidth / 2, -zoneHeight / 2, zoneWidth, zoneHeight);\n          context.closePath();\n          context.clip();\n        }\n      }\n      context.textAlign = zone.align || 'center';\n      context.textBaseline = 'middle';\n      const useWhiteEngraving = this.usesWhiteEngraving(zone);\n      context.globalCompositeOperation = useWhiteEngraving ? 'source-over' : 'multiply';\n      context.fillStyle = useWhiteEngraving\n        ? 'rgba(255, 255, 255, 0.96)'\n        : (this.dataset.engravingColor || 'rgba(55, 49, 45, 0.82)');\n\n      const lines = value.split('\\n').slice(0, Math.max(1, Number(zone.maxLines || 1)));\n      do {\n        context.font = `${style} ${weight} ${fontSize}px ${family}`;\n        const fitsWidth = lines.every((line) => context.measureText(line).width <= maxWidth);\n        const fitsHeight = lines.length * fontSize * Number(zone.lineHeight || 1.25) <= Math.max(zoneHeight, fontSize);\n        if (fitsWidth && fitsHeight) break;\n        fontSize -= 0.5;\n      } while (fontSize > minSize);\n\n      const letterSpacing = Number(zone.letterSpacing || 0) * (this.canvas.width / 1000);\n      if (letterSpacing && 'letterSpacing' in context) context.letterSpacing = `${letterSpacing}px`;\n      const x = zone.align === 'left' ? -zoneWidth / 2 : zone.align === 'right' ? zoneWidth / 2 : 0;\n      const lineHeight = fontSize * Number(zone.lineHeight || 1.25);\n      const firstY = -((lines.length - 1) * lineHeight) / 2;\n      lines.forEach((line, index) => context.fillText(line, x, firstY + index * lineHeight, maxWidth));\n      context.restore();\n    }\n\n    buildPayload() {\n      return {\n        schemaVersion: 'craftdiy-customization-2.0',\n        product: {\n          handle: this.dataset.productHandle || '',\n          id: this.dataset.productId || '',\n          variantId: this.dataset.variantId || '',\n          sku: this.dataset.sku || '',\n        },\n        customizerType: this.dataset.customizerType || '',\n        configKey: this.config.key || this.dataset.configKey,\n        mode: this.config.mode,\n        textZones: this.config.textZones.map((zone, index) => ({\n          id: zone.id,\n          propertyName: zone.propertyName || `Custom Text ${index + 1}`,\n          value: this.textState[index]?.value || '',\n          fontKey: this.textState[index]?.fontKey || zone.fontKey || 'signature',\n          fontLabel: (FONT_OPTIONS.find(([key]) => key === (this.textState[index]?.fontKey || zone.fontKey || 'signature')) || FONT_OPTIONS[0])[1],\n          fontFamily: (FONT_OPTIONS.find(([key]) => key === (this.textState[index]?.fontKey || zone.fontKey || 'signature')) || FONT_OPTIONS[0])[2],\n          fontSize: Number(zone.fontSize || 24),\n          bold: Boolean(zone.bold),\n          italic: Boolean(zone.italic),\n          letterSpacing: Number(zone.letterSpacing || 0),\n          lineHeight: Number(zone.lineHeight || 1.25),\n          rotation: Number(zone.rotation || 0),\n          curveBend: Number(zone.curveBend || 0),\n          engraveDepth: Number(zone.engraveDepth || zone.engravingDepth || 1.3),\n          offsetX: 0,\n          offsetY: 0,\n          tone: 'engraved',\n        })),\n        birthstones: this.birthstoneState.map((stone, index) => ({\n          id: `birthstone-${index + 1}`,\n          propertyName: `Birthstone ${index + 1}`,\n          month: stone.month,\n        })),\n        photoZones: this.config.photoZones.map((zone, index) => ({\n          id: zone.id,\n          propertyName: zone.propertyName || `Uploaded Photo ${index + 1}`,\n          fileName: this.photoState[index]?.file?.name || '',\n          zoom: this.photoState[index]?.zoom || 1,\n          offsetX: this.photoState[index]?.offsetX || 0,\n          offsetY: this.photoState[index]?.offsetY || 0,\n          rotation: this.photoState[index]?.rotation || 0,\n        })),\n      };\n    }\n\n    exportState() {\n      return {\n        text: Object.fromEntries(this.config.textZones.map((zone, index) => [zone.id, { ...this.textState[index] }])),\n        photos: Object.fromEntries(this.config.photoZones.map((zone, index) => [zone.id, { ...this.photoState[index] }])),\n        birthstones: Object.fromEntries(this.birthstoneState.map((state, index) => [`birthstone-${index + 1}`, { ...state }])),\n      };\n    }\n\n    importState(saved) {\n      if (!saved) return;\n      this.config.textZones.forEach((zone, index) => {\n        const state = saved.text?.[zone.id];\n        if (!state) return;\n        this.textState[index] = { ...this.textState[index], ...state };\n        const input = this.querySelector(`[data-text-index=\"${index}\"]`);\n        if (input) input.value = this.textState[index].value || '';\n        const font = this.querySelector(`[data-font-index=\"${index}\"]`);\n        const fontKey = this.textState[index].fontKey || zone.fontKey || 'signature';\n        if (font) font.value = fontKey;\n        this.syncFontPicker(index, fontKey);\n        const count = this.querySelector(`[data-character-count=\"${index}\"]`);\n        if (count) count.textContent = String((this.textState[index].value || '').length);\n      });\n      this.config.photoZones.forEach((zone, index) => {\n        const state = saved.photos?.[zone.id];\n        if (!state?.file || !state?.image) return;\n        this.photoState[index] = { ...this.photoState[index], ...state };\n        const label = this.querySelector(`[data-upload-label=\"${index}\"]`);\n        label?.classList.add('is-loaded');\n        const title = label?.querySelector('b');\n        if (title) title.textContent = state.file.name;\n        const tools = this.querySelector(`[data-photo-tools=\"${index}\"]`);\n        if (tools) tools.hidden = false;\n      });\n      this.birthstoneState.forEach((state, index) => {\n        const savedStone = saved.birthstones?.[`birthstone-${index + 1}`];\n        if (!savedStone) return;\n        this.birthstoneState[index] = { ...state, ...savedStone };\n        this.syncBirthstoneControl(index, this.birthstoneState[index].month);\n      });\n      this.queueCanvasRender();\n      this.syncPayload();\n    }\n\n    exportProofCanvas(kind) {\n      const output = document.createElement('canvas');\n      output.width = this.canvas.width;\n      output.height = this.canvas.height;\n      const originalCanvas = this.canvas;\n      const originalContext = this.context;\n      this.canvas = output;\n      this.context = output.getContext('2d');\n      try {\n        if (kind === 'photo') {\n          this.config.photoZones.forEach((zone, index) => this.drawPhotoZone(zone, this.photoState[index]));\n        } else {\n          this.drawBirthstones();\n          this.config.textZones.forEach((zone, index) => this.drawTextZone(zone, this.textState[index]));\n        }\n      } finally {\n        this.canvas = originalCanvas;\n        this.context = originalContext;\n      }\n      return output;\n    }\n\n    validateForApply() {\n      this.config.textZones.forEach((zone, index) => {\n        const value = String(this.textState[index]?.value || '');\n        if (zone.required && !value.trim()) throw new Error(`Complete ${zoneLabel(zone, index, 'Engraving')}.`);\n        const lines = value.split('\\n');\n        const maxLines = Math.max(1, Number(zone.maxLines || 1));\n        const maxChars = Math.max(1, Number(zone.maxChars || 50));\n        if (lines.length > maxLines) throw new Error(`${zoneLabel(zone, index, 'Engraving')} allows ${maxLines} line(s).`);\n        if (lines.some((line) => Array.from(line).length > maxChars)) throw new Error(`${zoneLabel(zone, index, 'Engraving')} allows ${maxChars} characters per line.`);\n      });\n      this.config.photoZones.forEach((zone, index) => {\n        if (zone.required && !this.photoState[index]?.file) throw new Error(`Upload ${zoneLabel(zone, index, 'Photo')}.`);\n      });\n      this.birthstoneState.forEach((stone, index) => {\n        if (!stone?.month) throw new Error(`Choose Birthstone ${index + 1}.`);\n      });\n      return this.buildPayload();\n    }\n\n    requestApply() {\n      try {\n        const payload = this.validateForApply();\n        this.syncPayload();\n        this.setStatus('Preparing your personalized preview\u2026', 'info');\n        this.dispatchEvent(new CustomEvent('craftdiy:apply-request', {\n          bubbles: true,\n          detail: { payload, customizer: this },\n        }));\n      } catch (error) {\n        this.setStatus(error.message || String(error), 'error');\n      }\n    }\n\n    syncPayload() {\n      const payload = this.buildPayload();\n      const hidden = this.querySelector('[data-customization-json]');\n      if (hidden) hidden.value = JSON.stringify(payload);\n      this.dispatchEvent(new CustomEvent('craftdiy:customization-change', {\n        bubbles: true,\n        detail: { payload, customizer: this },\n      }));\n    }\n\n    reset() {\n      this.photoState.forEach((state) => {\n        if (state.objectUrl) URL.revokeObjectURL(state.objectUrl);\n      });\n      this.seedState();\n      this.renderShell();\n      this.canvas.width = Number(this.config.image?.width || this.baseImage?.naturalWidth || 1000);\n      this.canvas.height = Number(this.config.image?.height || this.baseImage?.naturalHeight || 1000);\n      this.querySelector('[data-canvas-loading]')?.remove();\n      this.queueCanvasRender();\n      this.syncPayload();\n      this.setStatus('Customization reset.', 'success');\n    }\n\n    downloadPreview() {\n      if (!this.canvas) return;\n      const link = document.createElement('a');\n      link.download = `craftdiy-preview-${(this.config.key || 'custom').replaceAll('/', '-')}.png`;\n      link.href = this.canvas.toDataURL('image/png');\n      link.click();\n      this.setStatus('Preview downloaded.', 'success');\n    }\n\n    getPreviewDataUrl(type = 'image/jpeg', quality = 0.9) {\n      return this.canvas?.toDataURL(type, quality) || null;\n    }\n\n    setStatus(message, type = 'info') {\n      const status = this.querySelector('[data-status]');\n      if (!status) return;\n      status.textContent = String(message || '');\n      status.dataset.type = type;\n      status.hidden = !status.textContent;\n    }\n\n    showFatal(error) {\n      this.innerHTML = '<div class=\"craftdiy-customizer__error\"><strong>Personalization is temporarily unavailable.</strong><span>Please refresh the page and try again.</span></div>';\n      console.error('[CRAFTDIY customizer]', error);\n    }\n  }\n\n  if (globalThis.__CRAFTDIY_TEST_HOOKS__) {\n    globalThis.__CRAFTDIY_TEST_HOOKS__.customizer = {\n      RELEASE,\n      CORE_VERSION,\n      repairMalformedBirthstoneMask,\n      createReferenceGemMask,\n      constrainMaskToReference,\n      buildCroppedGemstoneLayer,\n      isBlackTextZone,\n    };\n  }\n\n  if (!customElements.get('craftdiy-customizer')) {\n    customElements.define('craftdiy-customizer', CraftdiyCustomizer);\n  }\n})();\n"],
  "mappings": "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",
  "names": []
}
