{
  "version": 3,
  "sources": ["/cdn/shop/t/171/assets/joy82-variant-switches.js?cachebust=1792696206046"],
  "sourcesContent": ["/**\n * JOY-82 \u2014 per-variant switches (announcement banner + Alia popup copy)\n *\n * Scope: Hard+ 3-month subscription A/B/C test (Linear JOY-82, QA\n * follow-ups in JOY-93).\n *\n * Reads the Intelligems test group once and applies two variant-specific\n * tweaks:\n *   1. Announcement banner copy \u2014 \"Unlock Up To <N>% Off Your First Order\"\n *      \u2192 50% (Variant B) or 40% (Variant C). Updates every marquee\n *      duplicate; skips the Prime Day entry.\n *   2. Alia popup copy \u2014 the existing Evergreen campaign (41505, 5% scroll\n *      trigger) keeps firing as-is for every arm. On B/C a MutationObserver\n *      rewrites every \"25%\" inside `#alia-root-*` to \"50%\" / \"40%\" as the\n *      popup mounts and re-renders (scratch reveal, etc.). The underlying\n *      discount code (`WELCOME2JOY`) is unchanged \u2014 per-variant subscription\n *      selling-plan pricing delivers the actual discount server-side.\n *\n * The Klaviyo `ig_discount_variant` property is pushed via Alia so welcome\n * flows can branch on the arm.\n *\n * Dashboard-disableable: pausing the test in Intelligems makes\n * `getTestGroup` return null, both branches no-op, control copy stays.\n *\n * Control / test off / unassigned visitors: no mutations.\n *\n * This file is test-scoped. When the test ends:\n *   1. Delete this file.\n *   2. Delete the `<script src=\"joy82-variant-switches.js\" ...>` line in\n *      `layout/theme.liquid`.\n */\n\n(() => {\n  const EXPERIMENT_ID = 'd3a6f675-237a-4b5c-8d3a-7d0b13c93e47';\n  const VARIANT_B_GROUP_ID = 'd2ddb247-0672-4d33-af05-bc0ca882304c';\n  const VARIANT_C_GROUP_ID = '6a32922b-c5ce-4c44-a3b4-1bd921226280';\n\n  const CONFIG_BY_GROUP = {\n    [VARIANT_B_GROUP_ID]: { discountPercent: 46 },\n    [VARIANT_C_GROUP_ID]: { discountPercent: 37 },\n  };\n\n  // Anchored on \"Unlock Up To\" so the Prime Day banner\n  // (\"PRIME DAY IS LIVE! Up To 40% Off Your First Order\u2026\") is not matched\n  // even though it shares the \"40%\" number with Variant C.\n  const BANNER_REGEX = /Unlock Up To \\d+% Off Your First Order/;\n\n  const swapBannerCopy = (discountPercent) => {\n    const replacement = `Unlock Up To ${discountPercent}% Off Your First Order`;\n    const entries = document.querySelectorAll('.announcement-bar-marquee__entry');\n    entries.forEach((entry) => {\n      const leaf = entry.querySelector('a, span, button') || entry;\n      const current = leaf.textContent;\n      const next = current.replace(BANNER_REGEX, replacement);\n      if (next !== current) leaf.textContent = next;\n    });\n  };\n\n  // Any \"25%\" inside an Alia popup root is the Evergreen discount \u2014 the HTML\n  // has no other \"25%\" strings. Matching bare percent (not \"25% off\") covers\n  // both the pre-scratch state (\"25% off\") and the uppercase aria-label /\n  // sr-only announcement (\"YOU'VE GOT 25% OFF\") with one pass.\n  const POPUP_PERCENT_REGEX = /25%/g;\n\n  const swapPopupText = (root, discountPercent) => {\n    const replacement = `${discountPercent}%`;\n\n    const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n    let node;\n    while ((node = walker.nextNode())) {\n      const next = node.nodeValue.replace(POPUP_PERCENT_REGEX, replacement);\n      if (next !== node.nodeValue) node.nodeValue = next;\n    }\n\n    root.querySelectorAll('[aria-label*=\"25%\"]').forEach((el) => {\n      const current = el.getAttribute('aria-label');\n      const next = current.replace(POPUP_PERCENT_REGEX, replacement);\n      if (next !== current) el.setAttribute('aria-label', next);\n    });\n  };\n\n  // The Alia popup mounts under `#alia-root-<triggerId>` and re-renders its\n  // subtree as the visitor interacts (scratch reveal, claim state). We attach\n  // a per-root observer so the swap runs on every DOM update, not just mount.\n  const watchAliaPopups = (discountPercent) => {\n    const attach = (root) => {\n      if (root.dataset.joy82Watched === 'true') return;\n      root.dataset.joy82Watched = 'true';\n      swapPopupText(root, discountPercent);\n      const subtreeObserver = new MutationObserver(() => {\n        swapPopupText(root, discountPercent);\n      });\n      subtreeObserver.observe(root, { childList: true, subtree: true, characterData: true });\n    };\n\n    document.querySelectorAll('[id^=\"alia-root-\"]').forEach(attach);\n\n    const bodyObserver = new MutationObserver((mutations) => {\n      for (const mutation of mutations) {\n        mutation.addedNodes.forEach((node) => {\n          if (node.nodeType !== 1) return;\n          // SVGElement.id is an SVGAnimatedString, not a plain string, so\n          // calling .startsWith on it throws. Facebook's fbevents.js injects\n          // tracking SVGs through our body observer. Guard the typeof.\n          if (typeof node.id === 'string' && node.id.startsWith('alia-root-')) attach(node);\n          if (node.querySelectorAll) {\n            node.querySelectorAll('[id^=\"alia-root-\"]').forEach(attach);\n          }\n        });\n      }\n    });\n    bodyObserver.observe(document.body, { childList: true, subtree: true });\n  };\n\n  // Intelligems drains `window.onIgReady` exactly once at load via\n  // `window.igData.executeIgReadyCallbacks`. Any push after that drain\n  // silently never fires \u2014 our deferred script race-loses on fast IG\n  // loads (observed in production 2026-10-22). So: if\n  // `window.igData.user.getTestGroup` is already present, IG has already\n  // drained; run synchronously. Otherwise push and let IG drain us on load.\n  const runWhenIgReady = (fn) => {\n    if (window.igData && window.igData.user && typeof window.igData.user.getTestGroup === 'function') {\n      fn();\n      return;\n    }\n    window.onIgReady = window.onIgReady || [];\n    if (typeof window.onIgReady === 'function') window.onIgReady = [window.onIgReady];\n    window.onIgReady.push(fn);\n  };\n\n  runWhenIgReady(() => {\n    const group = window.igData.user.getTestGroup(EXPERIMENT_ID);\n    if (!group) return;\n\n    const config = CONFIG_BY_GROUP[group.id];\n    if (!config) return;\n\n    window.alia = window.alia || [];\n    window.alia.push({\n      type: 'setProperties',\n      properties: { ig_discount_variant: group.name },\n    });\n\n    swapBannerCopy(config.discountPercent);\n    watchAliaPopups(config.discountPercent);\n  });\n})();\n"],
  "mappings": "CAgCC,IAAM,CACL,MAAM,cAAgB,uCAChB,mBAAqB,uCACrB,mBAAqB,uCAErB,gBAAkB,CACtB,CAAC,kBAAkB,EAAG,CAAE,gBAAiB,EAAG,EAC5C,CAAC,kBAAkB,EAAG,CAAE,gBAAiB,EAAG,CAC9C,EAKM,aAAe,yCAEf,eAAkB,iBAAoB,CAC1C,MAAM,YAAc,gBAAgB,eAAe,yBACnC,SAAS,iBAAiB,kCAAkC,EACpE,QAAS,OAAU,CACzB,MAAM,KAAO,MAAM,cAAc,iBAAiB,GAAK,MACjD,QAAU,KAAK,YACf,KAAO,QAAQ,QAAQ,aAAc,WAAW,EAClD,OAAS,UAAS,KAAK,YAAc,KAC3C,CAAC,CACH,EAMM,oBAAsB,OAEtB,cAAgB,CAAC,KAAM,kBAAoB,CAC/C,MAAM,YAAc,GAAG,eAAe,IAEhC,OAAS,SAAS,iBAAiB,KAAM,WAAW,SAAS,EACnE,IAAI,KACJ,KAAQ,KAAO,OAAO,SAAS,GAAI,CACjC,MAAM,KAAO,KAAK,UAAU,QAAQ,oBAAqB,WAAW,EAChE,OAAS,KAAK,YAAW,KAAK,UAAY,KAChD,CAEA,KAAK,iBAAiB,qBAAqB,EAAE,QAAS,IAAO,CAC3D,MAAM,QAAU,GAAG,aAAa,YAAY,EACtC,KAAO,QAAQ,QAAQ,oBAAqB,WAAW,EACzD,OAAS,SAAS,GAAG,aAAa,aAAc,IAAI,CAC1D,CAAC,CACH,EAKM,gBAAmB,iBAAoB,CAC3C,MAAM,OAAU,MAAS,CACvB,GAAI,KAAK,QAAQ,eAAiB,OAAQ,OAC1C,KAAK,QAAQ,aAAe,OAC5B,cAAc,KAAM,eAAe,EACX,IAAI,iBAAiB,IAAM,CACjD,cAAc,KAAM,eAAe,CACrC,CAAC,EACe,QAAQ,KAAM,CAAE,UAAW,GAAM,QAAS,GAAM,cAAe,EAAK,CAAC,CACvF,EAEA,SAAS,iBAAiB,oBAAoB,EAAE,QAAQ,MAAM,EAEzC,IAAI,iBAAkB,WAAc,CACvD,UAAW,YAAY,UACrB,SAAS,WAAW,QAAS,MAAS,CAChC,KAAK,WAAa,IAIlB,OAAO,KAAK,IAAO,UAAY,KAAK,GAAG,WAAW,YAAY,GAAG,OAAO,IAAI,EAC5E,KAAK,kBACP,KAAK,iBAAiB,oBAAoB,EAAE,QAAQ,MAAM,EAE9D,CAAC,CAEL,CAAC,EACY,QAAQ,SAAS,KAAM,CAAE,UAAW,GAAM,QAAS,EAAK,CAAC,CACxE,GAQwB,IAAO,CAC7B,GAAI,OAAO,QAAU,OAAO,OAAO,MAAQ,OAAO,OAAO,OAAO,KAAK,cAAiB,WAAY,CAChG,GAAG,EACH,MACF,CACA,OAAO,UAAY,OAAO,WAAa,CAAC,EACpC,OAAO,OAAO,WAAc,aAAY,OAAO,UAAY,CAAC,OAAO,SAAS,GAChF,OAAO,UAAU,KAAK,EAAE,CAC1B,GAEe,IAAM,CACnB,MAAM,MAAQ,OAAO,OAAO,KAAK,aAAa,aAAa,EAC3D,GAAI,CAAC,MAAO,OAEZ,MAAM,OAAS,gBAAgB,MAAM,EAAE,EAClC,SAEL,OAAO,KAAO,OAAO,MAAQ,CAAC,EAC9B,OAAO,KAAK,KAAK,CACf,KAAM,gBACN,WAAY,CAAE,oBAAqB,MAAM,IAAK,CAChD,CAAC,EAED,eAAe,OAAO,eAAe,EACrC,gBAAgB,OAAO,eAAe,EACxC,CAAC,CACH,GAAG",
  "names": []
}
