{
  "version": 3,
  "sources": ["/cdn/shop/t/2/assets/custom-framing-catalog.js?psv=image-framing-20260814"],
  "sourcesContent": ["(() => {\r\n  const DEFAULT_HANDLES = {\r\n    passepartout: 'system-passepartout-addon',\r\n    frame: 'system-frame-addon',\r\n  };\r\n  const EXPECTED_VARIANTS = { passepartout: 143, frame: 225 };\n  const PASSEPARTOUT_FITS = new Map([\r\n    ['a3 (29.7x42 cm)', 'A4 (21x29,7 cm)'],\r\n    ['a2 (42x59.4 cm)', 'A3 (29,7x42 cm)'],\r\n    ['a1 (59.4x84.1 cm)', 'A2 (42x59,4 cm)'],\r\n    ['30x40 cm', 'A4 (21x29,7 cm)'],\r\n    ['40x50 cm', '30x40 cm'],\r\n    ['50x70 cm', '40x50 cm'],\r\n    ['60x80 cm', '50x70 cm'],\r\n    ['70x70 cm', '50x50 cm'],\n    ['70x100 cm', '50x70 cm'],\n    ['100x140 cm', '70x100 cm'],\n    ['140x200 cm', '100x140 cm'],\n  ]);\n\r\n  const normalizeSize = (value = '') => value\r\n    .toLowerCase()\r\n    .replaceAll(',', '.')\r\n    .replace(/[\u00D7\u2715\u2716]/g, 'x')\r\n    .replace(/\\s*x\\s*/g, 'x')\r\n    .replace(/\\s+/g, ' ')\r\n    .trim();\r\n\r\n  const slugify = (value = '') => value\r\n    .normalize('NFKD')\r\n    .replace(/[\\u0300-\\u036f]/g, '')\r\n    .toLowerCase()\r\n    .replace(/[^a-z0-9]+/g, '-')\r\n    .replace(/^-|-$/g, '');\r\n\r\n  const assetUrl = (baseUrl, kind, styleSlug, orientation) => {\r\n    if (!baseUrl) return '';\r\n    const prefix = kind === 'passepartout' ? 'ps-mat' : 'ps-frame';\r\n    return `${baseUrl}${prefix}-${styleSlug}-${orientation}.png`;\r\n  };\r\n\r\n  const money = (price) => {\r\n    const currency = globalThis.Shopify?.currency?.active || 'GBP';\r\n    const locale = document.documentElement.lang || 'en-GB';\r\n    return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(Number(price || 0) / 100);\r\n  };\r\n\r\n  const optionPosition = (product, matcher, fallback) => {\r\n    const index = (product.options || []).findIndex((option) => matcher(typeof option === 'string' ? option : option.name));\r\n    return index >= 0 ? index + 1 : fallback;\r\n  };\r\n\r\n  const optionValue = (variant, position) => variant[`option${position}`] || variant.options?.[position - 1] || '';\r\n\r\n  const convertProduct = (kind, product, previewBaseUrl) => {\r\n    const sizePosition = optionPosition(product, (name = '') => name.toLowerCase().includes('size'), 2);\r\n    const stylePosition = optionPosition(product, (name = '') => !name.toLowerCase().includes('size'), 1);\r\n    return {\r\n      productId: product.id,\r\n      handle: product.handle,\r\n      variants: (product.variants || []).map((variant) => {\r\n        const style = optionValue(variant, stylePosition);\r\n        const size = optionValue(variant, sizePosition);\r\n        const styleSlug = slugify(style);\r\n        const fitsSize = kind === 'passepartout' ? PASSEPARTOUT_FITS.get(normalizeSize(size)) || '' : size;\r\n        return {\r\n          id: variant.id,\r\n          style,\r\n          styleSlug,\r\n          size,\r\n          fitsSize,\r\n          price: Number(variant.price),\r\n          formattedPrice: money(variant.price),\r\n          available: Boolean(variant.available),\r\n          sku: variant.sku || '',\r\n          preview: Object.fromEntries(['portrait', 'landscape', 'square'].map((orientation) => [\r\n            orientation,\r\n            assetUrl(previewBaseUrl, kind, styleSlug, orientation),\r\n          ])),\r\n        };\r\n      }),\r\n    };\r\n  };\r\n\r\n  const readInline = (node) => {\r\n    try {\r\n      return JSON.parse(node.textContent);\r\n    } catch (error) {\r\n      console.error('Framing catalog could not be read.', error);\r\n      return {};\r\n    }\r\n  };\r\n\r\n  const isComplete = (catalog) => Object.entries(EXPECTED_VARIANTS).every(([kind, count]) => (\r\n    catalog[kind]?.variants?.length === count\r\n  ));\r\n\r\n  const fetchProduct = async (handle) => {\r\n    const response = await fetch(`/products/${encodeURIComponent(handle)}.js`, {\r\n      headers: { Accept: 'application/json' },\r\n    });\r\n    if (!response.ok) throw new Error(`Could not load framing product ${handle} (HTTP ${response.status}).`);\r\n    return response.json();\r\n  };\r\n\r\n  const load = async (node) => {\r\n    const inline = readInline(node);\r\n    if (isComplete(inline)) return { ...inline, source: 'liquid' };\r\n\r\n    const handles = Object.fromEntries(Object.keys(DEFAULT_HANDLES).map((kind) => [\r\n      kind,\r\n      inline[kind]?.handle || DEFAULT_HANDLES[kind],\r\n    ]));\r\n    try {\r\n      const [passepartout, frame] = await Promise.all([\r\n        fetchProduct(handles.passepartout),\r\n        fetchProduct(handles.frame),\r\n      ]);\r\n      const catalog = {\r\n        previewBaseUrl: inline.previewBaseUrl || '',\r\n        passepartout: convertProduct('passepartout', passepartout, inline.previewBaseUrl),\r\n        frame: convertProduct('frame', frame, inline.previewBaseUrl),\r\n        source: 'ajax-product-api',\r\n      };\r\n      if (!isComplete(catalog)) throw new Error('Shopify returned an incomplete framing catalog.');\r\n      return catalog;\r\n    } catch (error) {\r\n      console.error('Framing catalog fallback failed.', error);\r\n      return { ...inline, source: 'incomplete-liquid' };\r\n    }\r\n  };\r\n\r\n  globalThis.PosterFramingCatalog = { load, normalizeSize };\r\n})();\r\n\r\n"],
  "mappings": "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",
  "names": []
}
