{"version":3,"file":"UrlCleaner.1jiVXaHI.mjs","names":["useState","React.useRef","__legacyOverrideHOC_DataObserverContext","_jsx"],"sources":["https:/framerusercontent.com/modules/vj7bFUjvEQFgEzNBkdoG/vf3CKm378wlVcBk7IhSU/createStore.js","https:/framer.com/m/framer/store.js@^1.0.0","https:/framerusercontent.com/modules/lgBoQxNllKFfCc4ryt8E/WkjacZyb0aHv6bG7Ttea/profileStore.js","https:/framerusercontent.com/modules/WLuJkjHL2FVf9e5rg4Bt/nWUbu5VgwV1zqQFadDC4/cartStore.js","https:/framerusercontent.com/modules/6XP7Q2uMwCNydLEakM1u/S7U0HWM4zsiU1wkCO9V8/constants.js","https:/framerusercontent.com/modules/pBL9xlYciLON0IYG5ZYl/Fipr2hsePg07IbR1SI79/apiClient.js","https:/framerusercontent.com/modules/5hyk9zz6yhVVgtfy0kQh/EXV4UI5SRaR4G0pCmiDg/subscriptionStore.js","https:/framerusercontent.com/modules/hknhN1f0aHw8OTik8uTf/88SrjDGmECwBMum0A3sB/BootsrapProvider.js","https:/framerusercontent.com/modules/NxuXdAARWIdVTnPTLWjX/eDdd1u4BOkLfWCQLV85h/SessionProvider.js","https:/framerusercontent.com/modules/45K9gEfOBCSyDFZYZVKH/Ory57u4s5WBDcy61Mq1G/UrlCleaner.js"],"sourcesContent":["import{useState,useEffect}from\"react\";import{Data,useObserveData}from\"framer\";export function createStore(state1){// Use Data so that a Preview reload resets the state\nconst dataStore=Data({state:Object.freeze({...state1})});// Create a set function that updates the state\nconst setDataStore=newState=>{// If the state is an object, make sure we copy it\nif(typeof newState===\"function\"){newState=newState(dataStore.state);}dataStore.state=Object.freeze({...dataStore.state,...newState});};// Store the initial state, copy the object if it's an object\nlet storeState=typeof state1===\"object\"?Object.freeze({...state1}):state1;// Keep a list of all the listeners, in the form of React hook setters\nconst storeSetters=new Set();// Create a set function that updates all the listeners / setters\nconst setStoreState=newState=>{// If the state is an object, make sure we copy it\nif(typeof newState===\"function\"){newState=newState(storeState);}storeState=typeof newState===\"object\"?Object.freeze({...storeState,...newState}):newState;// Update all the listeners / setters with the new value\nstoreSetters.forEach(setter=>setter(storeState));};// Create the actual hook based on everything above\nfunction useStore(){// Create the hook we are going to use as a listener\nconst[state,setState]=useState(storeState);// If we unmount the component using this hook, we need to remove the listener\n// @ts-ignore\nuseEffect(()=>{// But right now, we need to add the listener\nstoreSetters.add(setState);return()=>storeSetters.delete(setState);},[]);// If Data context exists, use Data, otherwise use vanilla React state\nif(useObserveData()===true){useObserveData();return[dataStore.state,setDataStore];}else{// Return the state and a function to update the central store\nreturn[state,setStoreState];}}return useStore;}\nexport const __FramerMetadata__ = {\"exports\":{\"createStore\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./createStore.map","/*\n * createStore (framer/store@1.0.1)\n *\n * Learn More: https://www.framer.com/asset-urls\n */\n\nexport * from \"https://framerusercontent.com/modules/vj7bFUjvEQFgEzNBkdoG/vf3CKm378wlVcBk7IhSU/createStore.js\"\n","/**\n * FILE: profileStore.ts\n * LOCATION: framer/stores/profileStore.ts\n * LAYER: Store (Domain State – Profile & Session)\n *\n * RESPONSIBILITY:\n * - Hold authenticated user state\n * - Store profile fields (name, email, address)\n * - Track authentication status (authenticated, loading, fetched)\n *\n * DOES NOT:\n * - Validate session (SessionProvider owns that)\n * - Handle login form draft state (authStore owns that)\n * - Perform profile mutations directly\n *\n * AUTHORITY:\n * - Session validity: GET /auth/me\n * - Profile data: GET /profile\n *\n * DATA FLOW:\n * SessionProvider / ProfileProvider → profileStore → Profile & Nav UI\n */import{createStore}from\"https://framer.com/m/framer/store.js@^1.0.0\";export const useProfileStore=createStore({loading:true,fetched:false,authenticated:false,bootstrapTrigger:0,email:undefined,firstName:undefined,lastName:undefined,displayName:undefined,defaultAddress:undefined,profileComplete:false,error:undefined});/**\n * Call retryBootstrap(setProfile) from any component to trigger a full\n * bootstrap re-fetch without reloading the page. Resets fetched and loading\n * flags so components show the loading state during the retry.\n *\n * Usage (in any override or code component):\n *   const [, setProfile] = useProfileStore()\n *   retryBootstrap(setProfile)\n */export function retryBootstrap(setState){setState(prev=>({...prev,loading:true,fetched:false,error:undefined,bootstrapTrigger:(prev.bootstrapTrigger??0)+1}));}\nexport const __FramerMetadata__ = {\"exports\":{\"useProfileStore\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"retryBootstrap\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DefaultAddress\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"ProfileState\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./profileStore.map","/**\n * FILE: cartStore.ts\n * LOCATION: framer/stores/cartStore.ts\n * LAYER: Store (Domain State – Cart)\n *\n * RESPONSIBILITY:\n * - Hold current cart state (lines, totals, metadata)\n * - Track cart loading and error states\n * - Provide reactive cart state to UI\n *\n * DOES NOT:\n * - Call cart API directly (CartActions owns mutations)\n * - Perform checkout logic\n * - Persist cart outside application lifecycle\n *\n * AUTHORITY:\n * - Canonical cart state defined by backend cart endpoints\n *\n * DATA FLOW:\n * CartProvider / CartActions → cartStore → Cart UI\n */import{createStore}from\"https://framer.com/m/framer/store.js@^1.0.0\";export const useCartStore=createStore({cart:null,status:\"idle\",error:null});\nexport const __FramerMetadata__ = {\"exports\":{\"useCartStore\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"CartStatus\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"CartState\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./cartStore.map","/**\n * FILE: constants.ts\n * LOCATION: framer/api/constants.ts\n * LAYER: API (Configuration)\n *\n * RESPONSIBILITY:\n * - Define shared API-related constants\n * - Centralize endpoint paths or configuration values\n *\n * DOES NOT:\n * - Perform HTTP calls\n * - Store application state\n * - Contain domain logic\n *\n * AUTHORITY:\n * - Static frontend configuration only\n */export const API_BASE=\"https://api.importa-coffee.com\";export const AUTH_ME_PATH=\"/auth/me\";export const AUTH_START_PATH=\"/auth/start\";export const AUTH_LOGOUT_PATH=\"/auth/logout\";export const PRODUCT_CACHE_KEY=\"importa_product_cache\";export const CATALOG_CACHE_KEY=\"importa_catalog_information_v1\";export const CATALOG_CACHE_TTL=10*60*1e3;export const PRODUCT_CACHE_TTL=60*60*1e3;\nexport const __FramerMetadata__ = {\"exports\":{\"AUTH_ME_PATH\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"API_BASE\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"AUTH_START_PATH\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"CATALOG_CACHE_TTL\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"PRODUCT_CACHE_KEY\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"AUTH_LOGOUT_PATH\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"CATALOG_CACHE_KEY\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"PRODUCT_CACHE_TTL\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./constants.map","/**\n * FILE: apiClient.ts\n * LOCATION: framer/api/apiClient.ts\n * LAYER: API (HTTP Transport Layer)\n *\n * RESPONSIBILITY:\n * - Provide a centralized wrapper around fetch\n * - Apply base API URL configuration\n * - Ensure credentials: \"include\" for cookie-based auth\n * - Normalize error handling for frontend\n *\n * DOES NOT:\n * - Store application state\n * - Contain business logic\n * - Transform domain data\n *\n * AUTHORITY:\n * - Backend API at https://api.importa-coffee.com\n *\n * DATA FLOW:\n * Override / Controller → apiClient → Backend API → JSON Response\n */import{API_BASE}from\"https://framerusercontent.com/modules/6XP7Q2uMwCNydLEakM1u/S7U0HWM4zsiU1wkCO9V8/constants.js\";export async function apiFetch(path,options={}){try{const res=await fetch(`${API_BASE}${path}`,{credentials:\"include\",headers:{Accept:\"application/json\",\"Content-Type\":\"application/json\",...options.headers||{}},...options});const data=await res.json().catch(()=>({}));return{ok:res.ok,status:res.status,data};}catch(error){return{ok:false,status:0,data:{error:\"network_error\"}};}}/* =========================================================\n   fetchWithRetry\n   Wraps any async fetch function with exponential-backoff retry.\n   Retries when the fetch throws OR when retryIf(result) returns true.\n   Default: up to 3 attempts, 1s / 2s / 4s delays, retry on !ok.\n========================================================= */export async function fetchWithRetry(fn,{attempts=3,baseDelayMs=1e3,// Only retry network errors (status 0) and 5xx server errors.\n// Do NOT retry 4xx — a 401 is a legitimate auth response, not a transient failure.\nretryIf=result=>!result.ok&&(result.status===0||result.status>=500)}={}){let lastResult={ok:false,status:0,data:null};for(let i=0;i<attempts;i++){try{lastResult=await fn();if(!retryIf(lastResult))return lastResult;}catch(e){// apiFetch never throws, but guard anyway.\n// On the last attempt re-throw so callers can catch.\nif(i===attempts-1)throw e;}// Exponential backoff: 1s → 2s → 4s\nawait new Promise(r=>setTimeout(r,baseDelayMs*2**i));}return lastResult;}\nexport const __FramerMetadata__ = {\"exports\":{\"fetchWithRetry\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"apiFetch\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./apiClient.map","import{createStore}from\"https://framer.com/m/framer/store.js@^1.0.0\";import{apiFetch,fetchWithRetry}from\"https://framerusercontent.com/modules/pBL9xlYciLON0IYG5ZYl/Fipr2hsePg07IbR1SI79/apiClient.js\";export const useSubscriptionStore=createStore({status:\"idle\",error:null,hasSubscription:false,cadence:null,nextChargeDate:null,subscriptions:[],subscriptionStartDate:null,totalBagsDelivered:null,totalSpentThisMonth:null,shipmentsThisMonth:null,draft:{cadence:null,items:{},scope:\"all_future\"},saving:false,saveError:null});const CADENCE_TO_INTERVAL={weekly:{intervalFrequency:1,intervalUnit:\"week\"},biweekly:{intervalFrequency:2,intervalUnit:\"week\"},monthly:{intervalFrequency:1,intervalUnit:\"month\"}};function getInitialDraft(state){return{cadence:state.cadence,items:{},scope:\"all_future\"};}export function getDraftQuantity(state,subscriptionId,fallbackQuantity){return state.draft.items[subscriptionId]?.quantity??fallbackQuantity;}export function hasUnsavedChanges(state){if(state.draft.cadence!==state.cadence)return true;return Object.keys(state.draft.items).length>0;}/**\n * IMPORTANT:\n * Do not call hooks (useSubscriptionStore) inside this function.\n * Pass setState in from an Override/component.\n */export async function loadSubscriptions(setState){setState(prev=>({...prev,status:\"loading\",error:null,saveError:null}));try{const{ok,data}=await fetchWithRetry(()=>apiFetch(\"/subscription/preferences\"),{attempts:3,baseDelayMs:1e3});if(ok&&data?.ok){setState({status:\"loaded\",error:null,hasSubscription:data.hasSubscription,cadence:data.cadence??null,nextChargeDate:data.nextChargeDate??null,subscriptions:data.subscriptions??[],subscriptionStartDate:data.subscriptionStartDate??null,totalBagsDelivered:data.totalBagsDelivered??null,totalSpentThisMonth:data.totalSpentThisMonth??null,shipmentsThisMonth:data.shipmentsThisMonth??null,draft:{cadence:data.cadence??null,items:{},scope:\"all_future\"},saving:false,saveError:null});return;}setState(prev=>({...prev,status:\"error\",error:\"Failed to load subscription\",hasSubscription:false,cadence:null,nextChargeDate:null,subscriptions:[],subscriptionStartDate:null,totalBagsDelivered:null,totalSpentThisMonth:null,shipmentsThisMonth:null,draft:getInitialDraft({cadence:null})}));}catch{setState(prev=>({...prev,status:\"error\",error:\"Failed to load subscription\",hasSubscription:false,cadence:null,nextChargeDate:null,subscriptions:[],subscriptionStartDate:null,totalBagsDelivered:null,totalSpentThisMonth:null,shipmentsThisMonth:null,draft:getInitialDraft({cadence:null})}));}}export function setDraftCadence(setState,cadence){setState(prev=>({...prev,draft:{...prev.draft,cadence},saveError:null}));}export function setDraftScope(setState,scope){setState(prev=>({...prev,draft:{...prev.draft,scope},saveError:null}));}export function setDraftItemQuantity(setState,subscriptionId,quantity){setState(prev=>{const subscription=prev.subscriptions.find(item=>item.subscriptionId===subscriptionId);if(!subscription)return prev;const safeQuantity=Math.max(1,Math.floor(quantity));const serverQuantity=subscription.quantity;const nextItems={...prev.draft.items};if(safeQuantity===serverQuantity){delete nextItems[subscriptionId];}else{nextItems[subscriptionId]={...nextItems[subscriptionId],quantity:safeQuantity};}return{...prev,draft:{...prev.draft,items:nextItems},saveError:null};});}export function resetDraft(setState){setState(prev=>({...prev,draft:getInitialDraft(prev),saveError:null}));}export async function saveSubscriptionChanges(setState){let snapshot=null;setState(prev=>{snapshot=prev;return{...prev,saving:true,saveError:null};});const state=snapshot;if(!state)return;const cadenceChanged=state.draft.cadence!==state.cadence;const itemChanges=Object.keys(state.draft.items).length>0;if(!cadenceChanged&&!itemChanges){setState(prev=>({...prev,saving:false}));return;}// Current backend only supports cadence changes.\n// Keep quantity drafts in frontend state for now, but do not attempt\n// to save them until the backend contract supports it.\nif(itemChanges){setState(prev=>({...prev,saving:false,saveError:\"Quantity changes are not available yet. Please save cadence changes only for now.\"}));return;}const nextCadence=state.draft.cadence;if(!nextCadence){setState(prev=>({...prev,saving:false,saveError:\"Please select a delivery frequency.\"}));return;}const{ok}=await apiFetch(\"/subscription/update\",{method:\"POST\",body:JSON.stringify({action:\"change_cadence\",interval:nextCadence})});if(!ok){setState(prev=>({...prev,saving:false,saveError:\"Failed to update subscription. Please try again.\"}));return;}const{intervalFrequency,intervalUnit}=CADENCE_TO_INTERVAL[nextCadence];setState(prev=>({...prev,saving:false,saveError:null,cadence:nextCadence,draft:{cadence:nextCadence,items:{},scope:prev.draft.scope},subscriptions:(prev.subscriptions??[]).map(sub=>({...sub,intervalFrequency,intervalUnit}))}));}\nexport const __FramerMetadata__ = {\"exports\":{\"resetDraft\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DraftItem\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"setDraftCadence\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"setDraftScope\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"setDraftItemQuantity\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"SubscriptionItem\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"loadSubscriptions\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"SubscriptionScope\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"saveSubscriptionChanges\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"SubscriptionCadence\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"useSubscriptionStore\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getDraftQuantity\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"hasUnsavedChanges\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}","/**\n * FILE: BootstrapProvider.tsx\n * LOCATION: framer/providers/BootstrapProvider.tsx\n * LAYER: Provider (Global Bootstrap – Aggregated Init)\n *\n * RESPONSIBILITY:\n * - Call GET /bootstrap once on mount (and on retry)\n * - Hydrate profileStore, cartStore, and subscriptionStore in parallel\n *   from a single network response\n *\n * DOES NOT:\n * - Handle session validation (SessionProvider owns that)\n * - Fetch orders (OrdersProvider owns that)\n * - Mutate any store after initial hydration\n *\n * RETRY:\n * - fetchWithRetry: 5 attempts, 2s base delay — gives Lambda up to ~30s to warm\n * - retryIf: only 5xx and network errors (status 0) — never retries 4xx\n * - retryBootstrap(setProfile) can be called by any component to re-trigger\n *   a full bootstrap without a page reload\n *\n * DATA FLOW:\n * Mount / bootstrapTrigger → GET /bootstrap → profileStore + cartStore + subscriptionStore\n */import{jsx as _jsx}from\"react/jsx-runtime\";import*as React from\"react\";import{RenderTarget}from\"framer\";import{useProfileStore}from\"https://framerusercontent.com/modules/lgBoQxNllKFfCc4ryt8E/WkjacZyb0aHv6bG7Ttea/profileStore.js\";import{useCartStore}from\"https://framerusercontent.com/modules/WLuJkjHL2FVf9e5rg4Bt/nWUbu5VgwV1zqQFadDC4/cartStore.js\";import{useSubscriptionStore,loadSubscriptions}from\"https://framerusercontent.com/modules/5hyk9zz6yhVVgtfy0kQh/EXV4UI5SRaR4G0pCmiDg/subscriptionStore.js\";import{apiFetch,fetchWithRetry}from\"https://framerusercontent.com/modules/pBL9xlYciLON0IYG5ZYl/Fipr2hsePg07IbR1SI79/apiClient.js\";function buildDisplayName(firstName,lastName,email){const full=`${firstName??\"\"} ${lastName??\"\"}`.trim();return full||email||\"Account\";}/**\n * @framerIntrinsicWidth 1\n * @framerIntrinsicHeight 1\n */export default function BootstrapProvider(){const[profile,setProfile]=useProfileStore();const[,setCart]=useCartStore();const[,setSubscription]=useSubscriptionStore();// Guards against double-invocation within a single trigger value\n// (React StrictMode mounts effects twice with the same deps).\nconst triggerRef=React.useRef(-1);React.useEffect(()=>{// Canvas: inject mock data so design looks good\nif(RenderTarget.current()===RenderTarget.canvas){setProfile({loading:false,fetched:true,authenticated:true,bootstrapTrigger:0,email:\"customer@example.com\",firstName:\"Test\",lastName:\"Customer\",displayName:\"Test Customer\",profileComplete:false,defaultAddress:{address1:\"\",city:\"\",provinceCode:\"\",countryCode:\"\",zip:\"\"},error:undefined});setCart({cart:null,status:\"loaded\",error:null});setSubscription({status:\"loaded\",error:null,hasSubscription:false,cadence:null,nextChargeDate:null,subscriptions:[],subscriptionStartDate:null,totalBagsDelivered:null,totalSpentThisMonth:null,shipmentsThisMonth:null,draft:{cadence:null,items:{},scope:\"all_future\"},saving:false,saveError:null});return;}// Prevent re-running the same trigger twice (StrictMode guard)\nif(triggerRef.current===profile.bootstrapTrigger)return;triggerRef.current=profile.bootstrapTrigger;let cancelled=false;let subscriptionFailed=false;(async()=>{// Mark all three domains as loading\nsetProfile(prev=>({...prev,loading:true,error:undefined}));setCart({cart:null,status:\"loading\",error:null});setSubscription(prev=>({...prev,status:\"loading\",error:null}));try{const{ok,data}=await fetchWithRetry(()=>apiFetch(\"/bootstrap\"),{// 5 attempts with 2s base delay: 2s → 4s → 8s → 16s gaps\n// gives Lambda up to ~30s to cold-start before giving up.\nattempts:5,baseDelayMs:2e3});if(cancelled)return;if(!ok){// Network failure or 5xx after all retries — real server error.\n// Do NOT set fetched: true — components must stay in loading state\n// rather than permanently show empty fallback values.\nsetProfile(prev=>({...prev,loading:false,fetched:false,authenticated:false,error:\"Could not reach server. Please reload.\"}));setCart({cart:null,status:\"error\",error:\"Bootstrap failed\"});setSubscription(prev=>({...prev,status:\"error\",error:\"Bootstrap failed\"}));return;}if(!data?.ok){// Server responded cleanly — user is not authenticated.\n// fetched: true is correct here — we know the state of auth.\nsetProfile(prev=>({...prev,loading:false,fetched:true,authenticated:false,error:undefined}));setCart({cart:null,status:\"loaded\",error:null});setSubscription(prev=>({...prev,status:\"loaded\",error:null,hasSubscription:false,subscriptions:[]}));return;}/* — Profile — */const profileData=data.profile;if(profileData?.ok){const c=profileData.customer||{};const email=c.email;const firstName=c.firstName;const lastName=c.lastName;const displayName=buildDisplayName(firstName,lastName,email);// Use functional form to always preserve bootstrapTrigger\n// regardless of what retryBootstrap may have written mid-flight.\nsetProfile(prev=>({loading:false,fetched:true,authenticated:true,bootstrapTrigger:prev.bootstrapTrigger,email,firstName,lastName,displayName,defaultAddress:c.defaultAddress||undefined,profileComplete:!!profileData.profileComplete,error:undefined}));}else{setProfile(prev=>({...prev,loading:false,fetched:true,authenticated:false,error:undefined}));}/* — Cart — */const cartData=data.cart;if(cartData?.ok!==false){setCart({cart:cartData?.cart??null,status:\"loaded\",error:null});}else{setCart({cart:null,status:\"error\",error:\"Failed to load cart\"});}/* — Subscriptions — */const subData=data.subscriptions;if(subData?.ok){setSubscription(prev=>({status:\"loaded\",error:null,hasSubscription:subData.hasSubscription,cadence:subData.cadence??null,nextChargeDate:subData.nextChargeDate??null,subscriptions:subData.subscriptions??[],subscriptionStartDate:subData.subscriptionStartDate??null,totalBagsDelivered:subData.totalBagsDelivered??null,totalSpentThisMonth:subData.totalSpentThisMonth??null,shipmentsThisMonth:subData.shipmentsThisMonth??null,draft:{...prev.draft,cadence:subData.cadence??null},saving:false,saveError:null}));}else{subscriptionFailed=true;setSubscription(prev=>({...prev,status:\"error\",error:\"Subscription data unavailable\"}));}}catch(e){if(cancelled)return;// fetchWithRetry re-throws only on the last attempt failing with\n// an exception (rare since apiFetch never throws, but guard anyway).\nsetProfile(prev=>({...prev,loading:false,fetched:false,authenticated:false,error:\"Could not reach server. Please reload.\"}));setCart({cart:null,status:\"error\",error:\"Bootstrap failed\"});setSubscription(prev=>({...prev,status:\"error\",error:\"Bootstrap failed\"}));subscriptionFailed=true;}if(subscriptionFailed&&!cancelled){await loadSubscriptions(setSubscription);}})();return()=>{cancelled=true;};// Re-run when retryBootstrap() increments bootstrapTrigger.\n// eslint-disable-next-line react-hooks/exhaustive-deps\n},[profile.bootstrapTrigger]);return /*#__PURE__*/_jsx(\"div\",{style:{width:1,height:1,opacity:0}});}\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"BootstrapProvider\",\"slots\":[],\"annotations\":{\"framerIntrinsicHeight\":\"1\",\"framerContractVersion\":\"1\",\"framerIntrinsicWidth\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./BootsrapProvider.map","/**\n * FILE: SessionProvider.tsx\n * LOCATION: framer/providers/SessionProvider.tsx\n * LAYER: Provider (Global Session Bootstrap)\n *\n * RESPONSIBILITY:\n * - Call GET /auth/me on mount\n * - Determine whether a valid session cookie exists\n * - Hydrate profileStore with authenticated state\n * - Expose session loading/error status to UI\n *\n * DOES NOT:\n * - Handle login form submission\n * - Store tokens manually\n * - Persist session outside profileStore\n *\n * AUTHORITY:\n * - Session validity is determined exclusively by backend:\n *   GET /auth/me\n *\n * DATA FLOW:\n * Cookie → /auth/me → profileStore → UI (Navigation, Guards, etc.)\n */import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect}from\"react\";import{useProfileStore}from\"https://framerusercontent.com/modules/lgBoQxNllKFfCc4ryt8E/WkjacZyb0aHv6bG7Ttea/profileStore.js\";import{apiFetch,fetchWithRetry}from\"https://framerusercontent.com/modules/pBL9xlYciLON0IYG5ZYl/Fipr2hsePg07IbR1SI79/apiClient.js\";/**\n * @framerIntrinsicWidth 1\n * @framerIntrinsicHeight 1\n */export default function SessionProvider(){const[,setState]=useProfileStore();useEffect(()=>{let cancelled=false;async function checkSession(){setState(prev=>({...prev,loading:true,error:undefined}));try{const{ok,data}=await fetchWithRetry(()=>apiFetch(\"/auth/me\"),{attempts:3,baseDelayMs:1e3});if(cancelled)return;setState(prev=>({...prev,authenticated:ok&&data?.authenticated===true,loading:false,fetched:true,// Distinguish network failure from legitimate logged-out state\n    error:!ok?\"Could not reach server. Please reload.\":undefined}));}catch{if(cancelled)return;setState(prev=>({...prev,loading:false,fetched:true,authenticated:false,error:\"Could not reach server. Please reload.\"}));}}checkSession();return()=>{cancelled=true;};},[]);return /*#__PURE__*/_jsx(\"div\",{style:{width:1,height:1,opacity:0,pointerEvents:\"none\"}});}\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"SessionProvider\",\"slots\":[],\"annotations\":{\"framerIntrinsicWidth\":\"1\",\"framerContractVersion\":\"1\",\"framerIntrinsicHeight\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}","import{jsx as _jsx}from\"react/jsx-runtime\";import*as React from\"react\";export function UrlCleaner(){React.useEffect(()=>{if(!window.location.pathname.includes(\"/product\")){const params=new URLSearchParams(window.location.search);if(params.has(\"handle\")){params.delete(\"handle\");const newSearch=params.toString();history.replaceState(null,\"\",newSearch?`?${newSearch}`:window.location.pathname);}}},[]);return{};}import{useContext as __legacyOverrideHOC_useContext}from\"react\";import{DataObserverContext as __legacyOverrideHOC_DataObserverContext}from\"framer\";export function withUrlCleaner(C){return props=>{__legacyOverrideHOC_useContext(__legacyOverrideHOC_DataObserverContext);return _jsx(C,{...props,...UrlCleaner(props)});};}withUrlCleaner.displayName=\"UrlCleaner\";\nexport const __FramerMetadata__ = {\"exports\":{\"UrlCleaner\":{\"type\":\"override\",\"name\":\"UrlCleaner\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withUrlCleaner\":{\"type\":\"reactHoc\",\"name\":\"withUrlCleaner\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./UrlCleaner.map"],"mappings":"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"}