{
  "version": 3,
  "sources": ["/cdn/shop/t/18/assets/ft-order-builder.js?nocache=1788488743"],
  "sourcesContent": ["/* ============================================================\n * 60ft Ink \u2014 Unified order builder (dev pilot)\n * ------------------------------------------------------------\n * Replaces size-quantity-matrix.liquid for `order-builder-ready`\n * products only. Combines size/qty selection, colour, print\n * locations and live real pricing into one widget, styled like\n * ft-quote-calculator.js but driving REAL state instead of an\n * estimate.\n *\n * Deliberately scoped to standard (non-Special, non-promo-front-\n * only) products \u2014 size-quantity-matrix.liquid keeps handling\n * those, untouched. See /Users/rolandsoutar/.claude/plans/\n * humble-wiggling-peach.md for the full rationale.\n *\n * Cart/pricing logic (discountTiers, getDiscount, PRINT_VARIANTS,\n * buildBaseItems, addToCart, sendItemsToCart) is ported near-\n * verbatim from size-quantity-matrix.liquid's standard-path code,\n * since that logic is already correct and tested \u2014 only the\n * presentation layer and print-location handling are new.\n *\n * Print-location pills carry NO pricing logic of their own \u2014 they\n * toggle the REAL print-location-selector.liquid checkboxes\n * underneath (set checked + dispatch change), the exact technique\n * ft-mockup-builder.js's syncPrintLocationSelector() already uses.\n * That keeps print-location-selector.liquid as the single source\n * of truth for location pricing/upload-URL properties.\n *\n * Colour swatches keep the class name `size-qty-matrix__swatch`\n * (and `data-color` attribute) so ft-mockup-builder.js's existing\n * colour-sync (initColourSync(), delegated click listener) keeps\n * working with zero changes there.\n *\n * The Add to Cart action binds to the SAME real #pls-main-add-btn\n * element size-quantity-matrix.liquid uses \u2014 this is what the\n * mockup wizard's review-step CTA already proxies a click to, so\n * that existing chain (wizard CTA -> #pls-main-add-btn -> real\n * cart submit) keeps working with zero changes to the wizard's\n * own proxy code.\n * ============================================================ */\n\n(function () {\n  'use strict';\n\n  var PRINT_VARIANTS = {\n    front:        47537209803054,\n    back:         47537209901358,\n    large_front:  52020797309230,\n    left_sleeve:  52394261348654,\n    right_sleeve: 52394261512494\n  };\n\n  var PLS_CHECKBOX_IDS = {\n    front: 'pls-front',\n    large_front: 'pls-large-front',\n    back: 'pls-back',\n    left_sleeve: 'pls-left-sleeve',\n    right_sleeve: 'pls-right-sleeve'\n  };\n\n  // Maps a print-location pill to the {side, zone} it corresponds to in\n  // ft-print-zones.json \u2014 the same config/geometry ft-mockup-builder.js\n  // uses for its own zone thumbnails, just looked up independently here so\n  // the pills can show one without depending on that widget's (async,\n  // possibly-absent-if-no-mockup-ready-tag) init.\n  var LOCATION_TO_ZONE = {\n    front:        { side: 'front',        zone: 'left_chest' },\n    large_front:  { side: 'front',        zone: 'full_front' },\n    back:         { side: 'back',         zone: 'full_back' },\n    left_sleeve:  { side: 'left_sleeve',  zone: 'left_sleeve' },\n    right_sleeve: { side: 'right_sleeve', zone: 'right_sleeve' }\n  };\n\n  // Real, enforced bulk ladder as of 2026-08-26 \u2014 mirrors the Hulk\n  // Discounts tier tables (see assets/ai-designer.js's DEFAULTS.tierTable\n  // for the full rationale). Was previously the old 5/20-10/25-20/30-50/35-\n  // 100/40-200/50 ladder, which Hulk itself no longer enforces \u2014 this\n  // widget's own live estimate was quoting a HIGHER total than the cart\n  // actually charges, same trust problem fixed in the wizard.\n  var DISCOUNT_TIERS = [\n    { min: 200, pct: 35, label: '35% off' },\n    { min: 100, pct: 33, label: '33% off' },\n    { min: 50,  pct: 30, label: '30% off' },\n    { min: 20,  pct: 25, label: '25% off' },\n    { min: 10,  pct: 18, label: '18% off' }\n  ];\n\n  function formatMoney(cents) {\n    return '$' + (cents / 100).toFixed(2);\n  }\n\n  function getDiscount(totalQty) {\n    for (var i = 0; i < DISCOUNT_TIERS.length; i++) {\n      if (totalQty >= DISCOUNT_TIERS[i].min) return DISCOUNT_TIERS[i];\n    }\n    return null;\n  }\n\n  function hideThemeVariantPickers() {\n    document.body.classList.add('size-qty-matrix-hide-theme-pickers');\n    var inputs = document.querySelectorAll('input[name^=\"options[\"], select[name^=\"options[\"]');\n    inputs.forEach(function (el) {\n      var wrap = el.closest('fieldset, .product-form__input, .variant-picker__option, .product-form__option, .variant-input-wrap, label.product-form__label, .form__field-wrap');\n      if (wrap) wrap.style.display = 'none';\n      else el.style.display = 'none';\n    });\n  }\n\n  function initOrderBuilder(root) {\n    var allVariants = JSON.parse(root.getAttribute('data-variants'));\n    var colorIndex = parseInt(root.getAttribute('data-color-index'), 10);\n    var sizeIndex = parseInt(root.getAttribute('data-size-index'), 10);\n    var priceMin = parseInt(root.getAttribute('data-price-min'), 10);\n    var initialVariantId = parseInt(root.getAttribute('data-initial-variant-id'), 10);\n\n    var variantId = initialVariantId;\n    var selectedColor = '';\n    if (colorIndex >= 0) {\n      var initial = allVariants.find(function (v) { return v.id === initialVariantId; }) || allVariants[0];\n      if (initial && initial.options) selectedColor = initial.options[colorIndex] || '';\n    }\n\n    var swatchesEl = root.querySelector('[data-ob-swatches]');\n    var tbody = root.querySelector('[data-ob-body]');\n    var summaryEl = root.querySelector('[data-ob-summary]');\n    var totalQtyEl = root.querySelector('[data-ob-total-qty]');\n    var discountEl = root.querySelector('[data-ob-discount]');\n    var totalPriceEl = root.querySelector('[data-ob-total-price]');\n    var perShirtEl = root.querySelector('[data-ob-per-shirt]');\n    var tierPromptEl = root.querySelector('[data-ob-tier-prompt]');\n    var locationsEl = root.querySelector('[data-ob-locations]');\n    var messageEl = root.querySelector('[data-ob-message]');\n\n    var printExtra = 0; // dollars, per-shirt, sum of selected location prices\n    var selectedLocations = {}; // key -> true\n\n    // Cart-wide quantity awareness (2026-09-03 \u2014 real customer complaint:\n    // ordered 10 shirts, 2 hoodies, 1 tank in one visit, called the site\n    // \"too complicated\" / \"not working\"). The bulk-discount tiers here are\n    // enforced cart-wide at checkout (confirmed by testing that exact\n    // order \u2014 13 garments combined correctly triggered 18% off across all\n    // three products) but this widget's own preview only ever counted\n    // ITS OWN page's quantity, so every product after the first told the\n    // customer \"add N more to unlock 18% off\" even when they'd already\n    // earned it with garments already sitting in their cart \u2014 directly\n    // contradicting what they'd just seen on the previous product page.\n    // Fetched once per page load (garment-only \u2014 print-location fee line\n    // items are excluded via PRINT_VARIANTS, or they'd double-count\n    // against the same tier the garments already trigger) and folded into\n    // updateSummary() below.\n    var cartGarmentQty = 0;\n    var printVariantIdSet = {};\n    Object.keys(PRINT_VARIANTS).forEach(function (loc) { printVariantIdSet[PRINT_VARIANTS[loc]] = true; });\n    function fetchCartGarmentQty() {\n      fetch('/cart.js')\n        .then(function (r) { return r.ok ? r.json() : null; })\n        .then(function (cart) {\n          if (!cart) return;\n          var qty = 0;\n          cart.items.forEach(function (item) {\n            if (!printVariantIdSet[item.variant_id]) qty += item.quantity;\n          });\n          cartGarmentQty = qty;\n          updateSummary();\n        })\n        .catch(function () { /* cart-awareness is a nice-to-have \u2014 never block the page on it */ });\n    }\n    fetchCartGarmentQty();\n\n    // Zone-thumbnail config (garment photo + print-area rect per side),\n    // fetched independently of ft-mockup-builder.js so the pills' visuals\n    // don't depend on that widget's own (async, and on some products\n    // absent) init. Pills render immediately with text only; thumbnails\n    // fill in a moment later once this resolves.\n    var zoneCfg = null;\n    var configUrl = root.getAttribute('data-config-url');\n    var productKey = root.getAttribute('data-product-key');\n    if (configUrl && productKey) {\n      fetch(configUrl).then(function (r) { return r.json(); }).then(function (json) {\n        zoneCfg = json.products && json.products[productKey];\n        if (zoneCfg) { renderSwatches(); renderLocationPills(); recomputeSelectedLocations(); }\n      }).catch(function () { /* swatch colours/thumbnails are a nice-to-have, not required */ });\n    }\n\n    function colourIdForLabel(label) {\n      if (!zoneCfg || !zoneCfg.colours) return null;\n      var lower = (label || '').toLowerCase();\n      var match = zoneCfg.colours.filter(function (c) { return c.label.toLowerCase() === lower; })[0];\n      return match ? match.id : null;\n    }\n\n    // Real sampled hex per colour already exists in ft-print-zones.json\n    // (used today only for the mockup canvas/pill thumbnails) \u2014 reusing it\n    // here turns the colour picker from plain text buttons into actual\n    // colour swatches, no new data needed.\n    function hexForLabel(label) {\n      if (!zoneCfg || !zoneCfg.colours) return null;\n      var lower = (label || '').toLowerCase();\n      var match = zoneCfg.colours.filter(function (c) { return c.label.toLowerCase() === lower; })[0];\n      return match ? match.hex : null;\n    }\n\n    hideThemeVariantPickers();\n\n    function getUniqueColors() {\n      var seen = {};\n      var out = [];\n      allVariants.forEach(function (v) {\n        var c = v.options && v.options[colorIndex];\n        if (c && !seen[c]) { seen[c] = true; out.push(c); }\n      });\n      return out;\n    }\n\n    function colorIsAvailable(color) {\n      return allVariants.some(function (v) { return v.options && v.options[colorIndex] === color && v.available; });\n    }\n\n    function findVariantForColor(color) {\n      if (colorIndex < 0) return allVariants[0];\n      return allVariants.find(function (v) { return v.options && v.options[colorIndex] === color && v.available; })\n        || allVariants.find(function (v) { return v.options && v.options[colorIndex] === color; })\n        || allVariants[0];\n    }\n\n    function getVariantsForColor(color) {\n      if (colorIndex < 0) return allVariants;\n      return allVariants.filter(function (v) { return v.options && v.options[colorIndex] === color; });\n    }\n\n    // Most products offer 15-20+ colours, but real sales data is heavily\n    // concentrated in the first few (on the AS Colour Staple Tee, Black\n    // alone is ~95% of a year of sales, with Charcoal/White/Cobalt/Petrol\n    // Blue a distant rest \u2014 Roland's 2026-09-04 usability pass). Rather\n    // than overwhelm every visitor with the full palette up front, show\n    // only the first SWATCH_VISIBLE_LIMIT (the admin-configured colour\n    // order already puts the actual best-sellers first) and let a \"See all\"\n    // toggle reveal the rest for anyone who wants a less common colour.\n    var SWATCH_VISIBLE_LIMIT = 6;\n    var swatchesExpanded = false;\n\n    function renderSwatches() {\n      if (!swatchesEl || colorIndex < 0) return;\n      swatchesEl.innerHTML = '';\n      var colors = getUniqueColors();\n      var showToggle = colors.length > SWATCH_VISIBLE_LIMIT;\n\n      colors.forEach(function (color, i) {\n        var btn = document.createElement('button');\n        btn.type = 'button';\n        btn.className = 'size-qty-matrix__swatch';\n        btn.setAttribute('data-color', color);\n        if (!colorIsAvailable(color)) btn.classList.add('is-unavailable');\n        if (color === selectedColor) btn.classList.add('is-selected');\n        // Always show the currently-selected colour even if it's past the\n        // cutoff (e.g. arrived via a link/reorder that picked a less common\n        // colour) \u2014 collapsing it out of view would look like the pick\n        // silently reverted.\n        if (showToggle && !swatchesExpanded && i >= SWATCH_VISIBLE_LIMIT && color !== selectedColor) {\n          btn.hidden = true;\n        }\n\n        var hex = hexForLabel(color);\n        if (hex) {\n          btn.classList.add('has-chip');\n          var chip = document.createElement('span');\n          chip.className = 'size-qty-matrix__swatch-chip';\n          chip.style.background = hex;\n          btn.appendChild(chip);\n        }\n        var text = document.createElement('span');\n        text.className = 'size-qty-matrix__swatch-text';\n        text.textContent = color;\n        btn.appendChild(text);\n\n        btn.addEventListener('click', function () { selectColor(color); });\n        swatchesEl.appendChild(btn);\n      });\n\n      if (showToggle) {\n        var toggle = document.createElement('button');\n        toggle.type = 'button';\n        toggle.className = 'size-qty-matrix__swatch-toggle';\n        toggle.textContent = swatchesExpanded ? 'Show fewer colours' : 'See all ' + colors.length + ' colours';\n        toggle.addEventListener('click', function () {\n          swatchesExpanded = !swatchesExpanded;\n          renderSwatches();\n        });\n        swatchesEl.appendChild(toggle);\n      }\n    }\n\n    function updateSwatchUI() {\n      if (!swatchesEl) return;\n      swatchesEl.querySelectorAll('.size-qty-matrix__swatch').forEach(function (btn) {\n        btn.classList.toggle('is-selected', btn.getAttribute('data-color') === selectedColor);\n      });\n    }\n\n    function selectColor(color) {\n      if (color === selectedColor) return;\n      selectedColor = color;\n      var variant = findVariantForColor(color);\n      if (variant) variantId = variant.id;\n      updateSwatchUI();\n      buildMatrix(color);\n      updatePillThumbColours();\n\n      var idInput = document.querySelector('input[name=\"id\"]');\n      if (idInput && variant) {\n        idInput.value = variant.id;\n        idInput.dispatchEvent(new Event('change', { bubbles: true }));\n      }\n\n      var nativeInputs = document.querySelectorAll('input[data-variant-input]');\n      for (var ni = 0; ni < nativeInputs.length; ni++) {\n        var nativeName = (nativeInputs[ni].name || '').toLowerCase();\n        if ((nativeName === 'color' || nativeName === 'colour') && nativeInputs[ni].value === color) {\n          if (!nativeInputs[ni].checked) {\n            nativeInputs[ni].checked = true;\n            nativeInputs[ni].dispatchEvent(new Event('change', { bubbles: true }));\n          }\n          break;\n        }\n      }\n    }\n\n    function getTotalQty() {\n      var total = 0;\n      tbody.querySelectorAll('.ft-ob__qty-input').forEach(function (input) {\n        total += parseInt(input.value, 10) || 0;\n      });\n      return total;\n    }\n\n    function buildMatrix(color) {\n      var variants = getVariantsForColor(color);\n      tbody.innerHTML = '';\n      variants.forEach(function (variant) {\n        var tr = document.createElement('tr');\n        if (!variant.available) tr.classList.add('is-unavailable');\n        var sizeLabel = sizeIndex >= 0 && variant.options ? variant.options[sizeIndex] : variant.title;\n        var priceSuffix = '';\n        if (variant.price > priceMin) {\n          priceSuffix = ' <span class=\"ft-ob__price-note\">(+' + formatMoney(variant.price - priceMin) + ')</span>';\n        }\n        tr.innerHTML =\n          '<td>' + sizeLabel + (!variant.available ? ' <span class=\"ft-ob__soldout\">(sold out)</span>' : '') + '</td>' +\n          '<td>' + formatMoney(variant.price) + priceSuffix + '</td>' +\n          '<td><input type=\"number\" class=\"ft-ob__qty-input\" data-variant-id=\"' + variant.id + '\" data-variant-price=\"' + variant.price + '\" min=\"0\" max=\"999\" value=\"0\"' + (variant.available ? '' : ' disabled') + '></td>';\n        tbody.appendChild(tr);\n      });\n      tbody.querySelectorAll('.ft-ob__qty-input').forEach(function (input) {\n        input.addEventListener('input', updateSummary);\n        input.addEventListener('change', updateSummary);\n      });\n      updateSummary();\n    }\n\n    function anyLocationSelected() {\n      return Object.keys(selectedLocations).some(function (loc) { return selectedLocations[loc]; });\n    }\n\n    function updateSummary() {\n      var totalQty = 0;\n      var totalPrice = 0;\n      tbody.querySelectorAll('.ft-ob__qty-input').forEach(function (input) {\n        var qty = parseInt(input.value, 10) || 0;\n        if (qty < 0) { input.value = 0; qty = 0; }\n        totalQty += qty;\n        totalPrice += qty * parseInt(input.getAttribute('data-variant-price'), 10);\n      });\n\n      // A garment-only total (no print location picked yet) isn't the\n      // number a customer actually cares about \u2014 it's not the price of\n      // anything they can order (every Printable product needs at least\n      // one print location) and just reads as a premature/wrong-looking\n      // total. Wait for a real location before showing anything\n      // (2026-09-03, Roland's feedback).\n      if (totalQty > 0 && anyLocationSelected()) {\n        summaryEl.hidden = false;\n        totalQtyEl.textContent = totalQty;\n        var printTotal = Math.round(printExtra * 100) * totalQty;\n        var grandTotal = totalPrice + printTotal;\n        // Tier is based on this page's quantity PLUS whatever's already in\n        // the cart from other products \u2014 matches how the discount is\n        // actually enforced at checkout (cart-wide, not per-product).\n        var combinedQty = totalQty + cartGarmentQty;\n        var tier = getDiscount(combinedQty);\n        var finalTotal = tier ? Math.round(grandTotal * (1 - tier.pct / 100)) : grandTotal;\n        if (tier) {\n          discountEl.textContent = tier.label;\n          discountEl.hidden = false;\n        } else {\n          discountEl.hidden = true;\n        }\n        totalPriceEl.textContent = formatMoney(finalTotal);\n        // A lump sum is hard to reason about at bulk quantities \u2014 showing\n        // the effective per-shirt price too (garment + all its prints,\n        // discount already folded in) is the number a customer ordering\n        // 10+ actually thinks in. Skipped at qty 1, where it would just\n        // repeat the total.\n        if (perShirtEl) {\n          perShirtEl.textContent = totalQty > 1 ? ('(' + formatMoney(Math.round(finalTotal / totalQty)) + '/shirt)') : '';\n        }\n        if (tierPromptEl) {\n          var nextTier = null;\n          for (var i = DISCOUNT_TIERS.length - 1; i >= 0; i--) {\n            if (DISCOUNT_TIERS[i].min > combinedQty) { nextTier = DISCOUNT_TIERS[i]; break; }\n          }\n          var cartNote = cartGarmentQty > 0\n            ? ' <span class=\"ft-ob__tier-cart-note\">(' + cartGarmentQty + ' already in your cart, counted in)</span>'\n            : '';\n          // Showing \"add 9 more to unlock 18% off\" the instant someone\n          // types a qty of 1 reads as pressure/noise to a customer who was\n          // never going to buy 10 \u2014 only surface the upsell once they're\n          // genuinely getting close (at least halfway to the next tier),\n          // per Roland's 2026-09-04 simplification pass.\n          if (nextTier && combinedQty >= nextTier.min / 2) {\n            var needed = nextTier.min - combinedQty;\n            tierPromptEl.innerHTML = 'Add <strong>' + needed + ' more</strong> \u2014 here or on another product \u2014 to unlock <strong>' + nextTier.label + '</strong>' + cartNote;\n            tierPromptEl.hidden = false;\n          } else if (!nextTier && tier) {\n            tierPromptEl.innerHTML = 'You\u2019ve unlocked our best price.' + cartNote;\n            tierPromptEl.hidden = false;\n          } else {\n            tierPromptEl.hidden = true;\n          }\n        }\n      } else {\n        summaryEl.hidden = true;\n        if (tierPromptEl) tierPromptEl.hidden = true;\n      }\n\n      updateAddBtnState(totalQty);\n    }\n\n    // ---------- Print locations ----------\n    // Builds the small garment-thumbnail + dashed zone-rect visual for a\n    // pill \u2014 same rect-as-percent-of-canvas math ft-mockup-builder.js's\n    // buildZoneVisualBlock() uses, kept independent here (see zoneCfg\n    // fetch above) rather than reaching into that widget.\n    function buildPillThumb(location) {\n      var mapping = LOCATION_TO_ZONE[location];\n      if (!mapping || !zoneCfg) return null;\n      var sideCfg = zoneCfg.sides && zoneCfg.sides[mapping.side];\n      var zone = sideCfg && sideCfg.zones && sideCfg.zones[mapping.zone];\n      if (!sideCfg || !zone) return null;\n\n      var colourId = colourIdForLabel(selectedColor);\n      var tplUrl = (colourId && sideCfg.templates[colourId]) || sideCfg.templates._default;\n      if (!tplUrl) return null;\n\n      var canvasW = zoneCfg.canvas.width;\n      var canvasH = zoneCfg.canvas.height;\n\n      var thumb = document.createElement('span');\n      thumb.className = 'ft-ob__pill-thumb';\n      var img = document.createElement('img');\n      img.src = tplUrl;\n      img.alt = '';\n      img.setAttribute('data-pill-thumb-side', mapping.side);\n      thumb.appendChild(img);\n\n      var box = document.createElement('span');\n      box.className = 'ft-ob__pill-zone';\n      box.style.left = (zone.rect.x / canvasW * 100) + '%';\n      box.style.top = (zone.rect.y / canvasH * 100) + '%';\n      box.style.width = (zone.rect.width / canvasW * 100) + '%';\n      box.style.height = (zone.rect.height / canvasH * 100) + '%';\n      thumb.appendChild(box);\n\n      return thumb;\n    }\n\n    // Re-points every pill thumbnail at the newly-selected colour's\n    // template \u2014 called from selectColor() so switching colour keeps the\n    // garment shown in the pills consistent with the rest of the widget,\n    // same pattern as ft-mockup-builder.js's updateLocationChoiceThumbs().\n    function updatePillThumbColours() {\n      if (!zoneCfg) return;\n      locationsEl.querySelectorAll('img[data-pill-thumb-side]').forEach(function (img) {\n        var sideId = img.getAttribute('data-pill-thumb-side');\n        var sideCfg = zoneCfg.sides && zoneCfg.sides[sideId];\n        if (!sideCfg) return;\n        var colourId = colourIdForLabel(selectedColor);\n        img.src = (colourId && sideCfg.templates[colourId]) || sideCfg.templates._default;\n      });\n    }\n\n    function renderLocationPills() {\n      var options = document.querySelectorAll('.pls-option[data-location][data-price]');\n      locationsEl.innerHTML = '';\n      options.forEach(function (el) {\n        var location = el.getAttribute('data-location');\n        var price = parseFloat(el.getAttribute('data-price'));\n        var titleEl = el.querySelector('.pls-option-title') || el.querySelector('.pls-promo-locked-text strong');\n        var label = titleEl ? titleEl.textContent.trim() : location;\n        var checkbox = document.getElementById(PLS_CHECKBOX_IDS[location]);\n        if (!checkbox) return;\n\n        var pill = document.createElement('button');\n        pill.type = 'button';\n        pill.className = 'ft-ob__pill';\n        pill.setAttribute('data-location', location);\n        if (checkbox.checked) pill.classList.add('is-selected');\n\n        var thumb = buildPillThumb(location);\n        if (thumb) { pill.classList.add('has-thumb'); pill.appendChild(thumb); }\n\n        var text = document.createElement('span');\n        text.className = 'ft-ob__pill-text';\n        text.textContent = label + ' (+' + formatMoney(Math.round(price * 100)) + ')';\n        pill.appendChild(text);\n\n        // Design-status sub-label (\"Needs a design\" / \"\u2713 Design added\")\n        // is owned entirely by recomputeSelectedLocations() below, not\n        // here \u2014 that's the function that actually runs on every\n        // selection change (via the printlocation:pricechange listener),\n        // while THIS function only runs once at init plus once more if\n        // the zone-config fetch resolves late, always before the\n        // customer has selected anything. Building the status span here,\n        // gated on checkbox.checked, meant it could only ever be created\n        // in a state where checked was false \u2014 so it silently never\n        // existed for any pill a customer actually selected (confirmed\n        // live, 2026-09-04, cost real debugging time to track down).\n\n        pill.addEventListener('click', function () {\n          checkbox.checked = !checkbox.checked;\n          checkbox.dispatchEvent(new Event('change', { bubbles: true }));\n          // If the customer used the top-of-page \"design it with AI\n          // first\" entry point, there's a design waiting to be attached \u2014\n          // apply it to THIS location the instant they pick it, rather\n          // than silently waiting until they click all the way through to\n          // the design/upload step (2026-09-04, Roland's feedback: not\n          // clear the design would actually get used). No-ops harmlessly\n          // if there's no pending design, or this location already has\n          // real art attached.\n          if (checkbox.checked) {\n            var mbRoot = document.querySelector('[data-ft-mockup-builder]');\n            var mapping = LOCATION_TO_ZONE[location];\n            if (mbRoot && mbRoot.__ftApplyPendingAiDesign && mapping) {\n              // Visible feedback right where the customer's eyes already\n              // are \u2014 the pill they just pressed \u2014 on top of the top-of-\n              // page banner's own \"Attaching\u2026\" state. This attach is a\n              // real network round trip (a few seconds, longer if the\n              // print-quality upgrade has to fail over), and with nothing\n              // changing on screen during that window a customer could\n              // reasonably think the click didn't register (2026-09-04,\n              // Roland's usability audit).\n              pill.classList.add('is-applying-design');\n              mbRoot.__ftApplyPendingAiDesign(mapping.side).finally(function () {\n                pill.classList.remove('is-applying-design');\n                // Re-scans every selected pill's real hasArt() state and\n                // creates/updates/removes each one's status span as\n                // needed \u2014 same function driving the badge on every other\n                // selection change, so this attach's completion is just\n                // one more trigger of the one real code path instead of a\n                // separate one-off update.\n                recomputeSelectedLocations();\n              });\n            }\n          }\n        });\n\n        locationsEl.appendChild(pill);\n      });\n      recomputeSelectedLocations();\n    }\n\n    // The one function that actually runs on every selection change (the\n    // printlocation:pricechange listener below calls this on every\n    // checkbox change, not just at init) \u2014 so it's also the right place\n    // to own each pill's \"Needs a design\" / \"\u2713 Design added\" status\n    // span: create it the first time a location's selected, update it\n    // whenever hasArt() changes (e.g. once a pending AI design finishes\n    // attaching), remove it if the location gets deselected.\n    function recomputeSelectedLocations() {\n      selectedLocations = {};\n      Object.keys(PLS_CHECKBOX_IDS).forEach(function (loc) {\n        var checkbox = document.getElementById(PLS_CHECKBOX_IDS[loc]);\n        selectedLocations[loc] = !!(checkbox && checkbox.checked);\n      });\n      var mbRoot = document.querySelector('[data-ft-mockup-builder]');\n      var controller = mbRoot && mbRoot.__ftMockupController;\n      locationsEl.querySelectorAll('.ft-ob__pill').forEach(function (pill) {\n        var loc = pill.getAttribute('data-location');\n        var isSelected = !!selectedLocations[loc];\n        pill.classList.toggle('is-selected', isSelected);\n\n        var statusEl = pill.querySelector('.ft-ob__pill-status');\n        var mapping = LOCATION_TO_ZONE[loc];\n        if (isSelected && mapping) {\n          if (!statusEl) {\n            statusEl = document.createElement('span');\n            statusEl.className = 'ft-ob__pill-status';\n            pill.appendChild(statusEl);\n          }\n          var hasArtNow = !!(controller && controller.hasArt(mapping.side));\n          statusEl.textContent = hasArtNow ? '\u2713 Design added' : 'Needs a design';\n          statusEl.classList.toggle('is-done', hasArtNow);\n        } else if (statusEl) {\n          statusEl.remove();\n        }\n      });\n    }\n\n    document.addEventListener('printlocation:pricechange', function (e) {\n      printExtra = e.detail.extra || 0;\n      recomputeSelectedLocations();\n      updateSummary();\n    });\n\n    // ---------- Cart ----------\n    function getProperties() {\n      var form = root.closest('form[action*=\"/cart/add\"]') || document;\n      var props = {};\n      form.querySelectorAll('input[name^=\"properties[\"], select[name^=\"properties[\"], textarea[name^=\"properties[\"]').forEach(function (input) {\n        var match = input.name.match(/^properties\\[(.+)\\]$/);\n        if (match && input.value) props[match[1]] = input.value;\n      });\n      return props;\n    }\n\n    function buildBaseItems(properties, totalQty) {\n      var items = [];\n      tbody.querySelectorAll('.ft-ob__qty-input').forEach(function (input) {\n        var qty = parseInt(input.value, 10) || 0;\n        if (qty > 0) {\n          items.push({ id: parseInt(input.getAttribute('data-variant-id'), 10), quantity: qty, properties: properties });\n        }\n      });\n      if (totalQty > 0) {\n        ['front', 'large_front', 'back', 'left_sleeve', 'right_sleeve'].forEach(function (loc) {\n          if (selectedLocations[loc]) {\n            items.push({\n              id: PRINT_VARIANTS[loc],\n              quantity: totalQty,\n              properties: { 'Order reference': properties['T-Shirt Print Location'] || loc }\n            });\n          }\n        });\n      }\n      return items;\n    }\n\n    function showMessage(text) {\n      if (!messageEl) return;\n      messageEl.textContent = text;\n      messageEl.hidden = false;\n      setTimeout(function () { messageEl.hidden = true; }, 5000);\n    }\n\n    async function sendItemsToCart(items) {\n      if (!items.length) return;\n      if (addBtn) {\n        addBtn.disabled = true;\n        addBtn.dataset.origText = addBtn.dataset.origText || addBtn.textContent;\n        addBtn.textContent = 'Adding to cart\u2026';\n      }\n      try {\n        var response = await fetch('/cart/add.js', {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n          body: JSON.stringify({ items: items })\n        });\n        if (!response.ok) {\n          var err = await response.json();\n          showMessage(err.description || 'Error adding to cart');\n          if (addBtn) { addBtn.textContent = addBtn.dataset.origText; updateAddBtnState(getTotalQty()); }\n        } else {\n          window.location.href = '/cart';\n        }\n      } catch (e) {\n        showMessage('Network error \u2014 please try again');\n        if (addBtn) { addBtn.textContent = addBtn.dataset.origText; updateAddBtnState(getTotalQty()); }\n      }\n    }\n\n    async function addToCart() {\n      var properties = getProperties();\n      var totalQty = getTotalQty();\n      var items = buildBaseItems(properties, totalQty);\n      if (!items.length) return;\n      await sendItemsToCart(items);\n    }\n\n    var addBtn = document.getElementById('pls-main-add-btn');\n    var hasWizard = !!document.querySelector('[data-ft-mockup-builder]');\n    function updateAddBtnState(totalQty) {\n      if (!addBtn) return;\n      // When the mockup wizard is present it owns this button's disabled\n      // state (syncFormProperties -> blocked, which correctly requires\n      // real uploaded artwork per chosen print location before allowing\n      // checkout, on top of its own copyright-confirmation gate) \u2014 a\n      // simpler qty-only check here would race it and sometimes win,\n      // letting the customer add to cart before they've actually designed\n      // anything. Only take control of enablement ourselves when there's\n      // no wizard on the page at all.\n      if (hasWizard) return;\n      addBtn.disabled = !(totalQty > 0);\n    }\n    if (addBtn) addBtn.addEventListener('click', addToCart);\n\n    // Safety net: #pls-main-add-btn is a plain <button type=\"button\">\n    // specifically so it never natively submits \u2014 real submissions are\n    // meant to go through addToCart() above. But the underlying <form\n    // action=\"/cart/add\"> is still a real, submittable form, and anything\n    // that triggers a native submit bypasses addToCart() (and its\n    // getProperties()/buildBaseItems() logic) entirely, hitting Shopify's\n    // cart-add with next to nothing attached. Same fix applied to\n    // snippets/size-quantity-matrix.liquid 2026-08-12 after real \"Special\"\n    // package-deal orders came through with quantity 1 and zero custom\n    // attributes \u2014 this widget shares the identical pattern (same shared\n    // button, same non-submit type), so it carries the same structural\n    // risk even though it hasn't been observed here yet.\n    if (addBtn) {\n      var pageForm = addBtn.closest('form[action*=\"/cart/add\"]');\n      if (pageForm) {\n        pageForm.addEventListener('submit', function (e) {\n          e.preventDefault();\n          if (!addBtn.disabled) {\n            // Deferred, not called inline \u2014 clicking synchronously from\n            // within a 'submit' handler was observed (real testing,\n            // 2026-08-12) to silently swallow the click on the sibling\n            // widget's identical button/form combination.\n            setTimeout(function () { addBtn.click(); }, 0);\n          }\n        }, true);\n      }\n    }\n\n    renderSwatches();\n    buildMatrix(selectedColor);\n    renderLocationPills();\n  }\n\n  document.addEventListener('DOMContentLoaded', function () {\n    document.querySelectorAll('[data-ft-order-builder]').forEach(initOrderBuilder);\n    // print-location-selector.liquid's own script may run after this one in\n    // document order (both `defer`, execution order matches document\n    // order) but its checkboxes are already in the DOM by DOMContentLoaded\n    // regardless \u2014 renderLocationPills() above reads them synchronously.\n  });\n})();\n"],
  "mappings": "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",
  "names": []
}
