{
  "version": 3,
  "sources": ["/cdn/shop/t/33/assets/auto-gift.js?nocache=1792179021142"],
  "sourcesContent": ["/*\n * Auto Gift\n * Adds/removes gift items for active \"Auto Gift Rule\" metaobjects.\n * Rules are output by snippets/auto-gift-rules.liquid as window.AUTO_GIFT_RULES.\n * The matching Buy X Get Y discount makes the gift free; this script only manages the cart line.\n * Debug: run `window.AUTO_GIFT_DEBUG = true` in the console.\n */\n(function () {\n  'use strict';\n\n  var RULES = (window.AUTO_GIFT_RULES || []).filter(function (r) {\n    return r && r.gift && r.buy && r.buy.length;\n  });\n  if (!RULES.length || window.__autoGiftLoaded) return;\n  window.__autoGiftLoaded = true;\n\n  var PROP = 'Promo'; // shown to the shopper on the gift line, e.g. \"Promo: Free 12V Charger\"\n  var STATE_KEY = 'tbn_auto_gift_state';\n  var nativeFetch = window.fetch;\n  var syncing = false;\n  var pending = false;\n  var timer = null;\n  var lastCart = null;\n\n  function log() {\n    if (!window.AUTO_GIFT_DEBUG) return;\n    var args = Array.prototype.slice.call(arguments);\n    args.unshift('[Auto Gift]');\n    console.log.apply(console, args);\n  }\n\n  function readState() {\n    try { return JSON.parse(sessionStorage.getItem(STATE_KEY) || '{}'); } catch (e) { return {}; }\n  }\n\n  function writeState(state) {\n    try { sessionStorage.setItem(STATE_KEY, JSON.stringify(state)); } catch (e) {}\n  }\n\n  function request(url, body) {\n    var opts = { credentials: 'same-origin', headers: { 'Accept': 'application/json' } };\n    if (body) {\n      opts.method = 'POST';\n      opts.headers['Content-Type'] = 'application/json';\n      opts.body = JSON.stringify(body);\n    }\n    return nativeFetch.call(window, url, opts).then(function (res) {\n      if (!res.ok) throw new Error(url + ' ' + res.status);\n      return res.json();\n    });\n  }\n\n  function getCart() {\n    return request('/cart.js');\n  }\n\n  // Work out what each rule needs: add gifts, trim auto-added gifts, or nothing.\n  function plan(cart, state) {\n    var ops = [];\n    RULES.forEach(function (rule) {\n      var giftId = String(rule.gift);\n      var buySet = {};\n      rule.buy.forEach(function (id) { buySet[String(id)] = true; });\n\n      var qualifying = 0;\n      var giftUnits = 0;\n      var autoLines = [];\n      cart.items.forEach(function (item) {\n        var vid = String(item.variant_id);\n        if (vid === giftId) {\n          giftUnits += item.quantity;\n          if (item.properties && item.properties[PROP]) autoLines.push(item);\n        } else if (buySet[vid]) {\n          qualifying += item.quantity;\n        }\n      });\n\n      var autoUnits = autoLines.reduce(function (n, l) { return n + l.quantity; }, 0);\n      var target = qualifying * (parseInt(rule.per, 10) || 1);\n      var s = state[rule.handle] || {};\n\n      // Shopper removed/reduced an auto-added gift without changing qualifying items: respect it.\n      if (s.last && s.last.qualifying === qualifying && autoUnits < s.last.auto) {\n        s.declined = qualifying;\n      }\n      if (s.declined !== undefined && s.declined !== qualifying) delete s.declined;\n      var declined = s.declined !== undefined && qualifying > 0;\n\n      log(rule.handle, { qualifying: qualifying, target: target, giftUnits: giftUnits, autoUnits: autoUnits, declined: declined });\n\n      if (giftUnits < target && !declined) {\n        ops.push({ type: 'add', rule: rule, qty: target - giftUnits });\n        autoUnits += target - giftUnits;\n      } else if (giftUnits > target && autoUnits > 0) {\n        var excess = Math.min(giftUnits - target, autoUnits);\n        autoUnits -= excess;\n        for (var i = autoLines.length - 1; i >= 0 && excess > 0; i--) {\n          var take = Math.min(excess, autoLines[i].quantity);\n          ops.push({ type: 'change', key: autoLines[i].key, qty: autoLines[i].quantity - take });\n          excess -= take;\n        }\n      }\n\n      s.last = { qualifying: qualifying, auto: autoUnits };\n      state[rule.handle] = s;\n    });\n    return ops;\n  }\n\n  function runOps(ops) {\n    return ops.reduce(function (chain, op) {\n      return chain.then(function () {\n        if (op.type === 'add') {\n          var props = {};\n          props[PROP] = op.rule.title || op.rule.handle;\n          return request('/cart/add.js?auto_gift=1', { items: [{ id: op.rule.gift, quantity: op.qty, properties: props }] });\n        }\n        return request('/cart/change.js?auto_gift=1', { id: op.key, quantity: op.qty });\n      }).catch(function (e) {\n        console.warn('[Auto Gift]', e);\n        return null;\n      });\n    }, Promise.resolve(null));\n  }\n\n  function refreshUI(cart) {\n    if (/\\/cart\\/?$/.test(window.location.pathname)) {\n      window.location.reload();\n      return;\n    }\n    if (typeof window.refreshCart === 'function') {\n      try { window.refreshCart(cart); } catch (e) { log('refreshCart failed', e); }\n    }\n    document.dispatchEvent(new CustomEvent('cart:updated', { bubbles: true, detail: { cart: cart } }));\n  }\n\n  function isCart(obj) {\n    return obj && Array.isArray(obj.items) && obj.token !== undefined;\n  }\n\n  // cartIn: optional cart JSON we already have (e.g. from the theme's change.js response).\n  function sync(cartIn) {\n    if (syncing) { pending = true; return; }\n    syncing = true;\n    var state = readState();\n    (isCart(cartIn) ? Promise.resolve(cartIn) : getCart())\n      .then(function (cart) {\n        lastCart = cart;\n        var ops = plan(cart, state);\n        writeState(state);\n        if (!ops.length) return null;\n        return runOps(ops)\n          .then(function (res) { return isCart(res) ? res : getCart(); })\n          .then(function (updated) {\n            lastCart = updated;\n            // Re-baseline so our own change is not mistaken for the shopper's.\n            plan(updated, state);\n            writeState(state);\n            refreshUI(updated);\n          });\n      })\n      .catch(function (e) { console.warn('[Auto Gift]', e); })\n      .then(function () {\n        syncing = false;\n        if (pending) { pending = false; schedule(); }\n      });\n  }\n\n  function schedule() {\n    clearTimeout(timer);\n    timer = setTimeout(function () { sync(); }, 100);\n  }\n\n  function isCartMutation(url) {\n    url = String(url || '');\n    if (url.indexOf('auto_gift=1') !== -1) return false; // our own requests\n    return /\\/cart\\/(add|change|update|clear)(\\.js)?(\\?|$)/.test(url);\n  }\n\n  // Watch every network request (fetch, jQuery/XHR, any app) for cart changes.\n  // PerformanceObserver can't be overridden by other scripts that wrap fetch/XHR.\n  if ('PerformanceObserver' in window) {\n    try {\n      new PerformanceObserver(function (list) {\n        var hit = list.getEntries().some(function (e) { return isCartMutation(e.name); });\n        if (hit) schedule();\n      }).observe({ type: 'resource', buffered: false });\n    } catch (e) { log('observer unavailable', e); }\n  }\n\n  if (window.jQuery && window.jQuery.ajaxPrefilter) {\n    var $ = window.jQuery;\n\n    // Real time: when the theme adds a qualifying item (Turbo uses $.ajax + form data),\n    // add the gift in the same /cart/add.js request so both appear together.\n    $.ajaxPrefilter(function (options) {\n      try {\n        var url = String(options.url || '');\n        if (!/\\/cart\\/add(\\.js)?(\\?|$)/.test(url) || url.indexOf('auto_gift=1') !== -1) return;\n        if (typeof options.data !== 'string') return;\n        var params = new URLSearchParams(options.data);\n        var id = params.get('id');\n        if (!id || params.has('items[0][id]')) return;\n        var qty = parseInt(params.get('quantity') || '1', 10) || 1;\n\n        var extras = [];\n        RULES.forEach(function (rule) {\n          var match = rule.buy.some(function (b) { return String(b) === String(id); });\n          if (!match) return;\n          var giftQty = qty * (parseInt(rule.per, 10) || 1);\n          var stock = parseInt(rule.stock, 10);\n          if (!isNaN(stock) && stock >= 0) {\n            var inCart = 0;\n            if (lastCart) lastCart.items.forEach(function (it) { if (String(it.variant_id) === String(rule.gift)) inCart += it.quantity; });\n            if (inCart + giftQty > stock) return; // not enough stock: never block the main item; background sync handles it\n          }\n          extras.push({ rule: rule, qty: giftQty });\n        });\n        if (!extras.length) return;\n\n        var out = new URLSearchParams();\n        params.forEach(function (v, k) {\n          if (k === 'id' || k === 'quantity' || k === 'selling_plan') out.append('items[0][' + k + ']', v);\n          else if (k.indexOf('properties[') === 0) out.append('items[0][properties]' + k.slice(10), v);\n          else out.append(k, v);\n        });\n        extras.forEach(function (x, i) {\n          var n = i + 1;\n          out.append('items[' + n + '][id]', x.rule.gift);\n          out.append('items[' + n + '][quantity]', x.qty);\n          out.append('items[' + n + '][properties][' + PROP + ']', x.rule.title || x.rule.handle);\n        });\n        options.data = out.toString();\n        log('gift attached to add request', extras);\n      } catch (e) { log('prefilter skipped', e); }\n    });\n\n    // Faster removal: change/update responses already contain the cart, so reuse it.\n    $(document).ajaxSuccess(function (e, xhr, settings, data) {\n      if (isCartMutation(settings && settings.url) && isCart(data)) {\n        clearTimeout(timer);\n        sync(data);\n      }\n    });\n  }\n\n  // Cart forms that do a full page submit (e.g. update button) reload the page, and sync runs on load.\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', sync);\n  } else {\n    sync();\n  }\n})();\n"],
  "mappings": "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",
  "names": []
}
