"use strict";(()=>{var $e=null;function _n(){return $e??=new AbortController().signal,$e}function X(e){let t=e?.signal;return vn(t)?t:_n()}function vn(e){return typeof e=="object"&&e!==null&&typeof Reflect.get(e,"aborted")=="boolean"&&typeof Reflect.get(e,"addEventListener")=="function"}function de(e){return e.reason??Sn()}function Sn(){if(typeof DOMException=="function")return new DOMException("Tool execution was aborted.","AbortError");let e=new Error("Tool execution was aborted.");return e.name="AbortError",e}function De(e){if(e.aborted)throw de(e)}function Z(e){return typeof e=="object"&&e!==null&&Reflect.get(e,"name")==="AbortError"}function Ne(e,t){return e.aborted?(t(),()=>{}):(e.addEventListener("abort",t,{once:!0}),()=>e.removeEventListener("abort",t))}var Tn=[["analyticsProcessingAllowed","USER_CONSENT_TYPE_ANALYTICS"],["marketingAllowed","USER_CONSENT_TYPE_MARKETING"],["preferencesProcessingAllowed","USER_CONSENT_TYPE_PREFERENCES"],["saleOfDataAllowed","USER_CONSENT_TYPE_SALE_OF_DATA"]];function Cn(e){return Tn.filter(([t])=>e[t]).map(([,t])=>({consentType:t}))}function Ue(e){let{send:t,context:n,dataOriginator:r="DATA_ORIGINATOR_MERCHANT",flushDelayMs:o=5e3,registerLifecycle:i=!1}=e,a=[],s;function c(){s!==void 0||typeof setTimeout!="function"||(s=setTimeout(()=>{s=void 0,l()},o))}function u(d){let b=n.consent();b.analyticsProcessingAllowed&&(a.length>=50&&a.shift(),a.push({eventClass:"EVENT_CLASS_EVENT",source:"EVENT_APP_STOREFRONT",dataOriginator:r,user:{type:"USER_TYPE_BUYER",...n.browserId===void 0?{}:{domainScopedBrowserId:{value:n.browserId}}},...n.shopId===void 0?{}:{shop:{id:{lowid:n.shopId}}},...n.sessionToken===void 0?{}:{session:{clientSessionToken:n.sessionToken}},userConsents:Cn(b),client:{browser:{href:An(n.pageUrl())}},payload:d}),c())}function l(){if(s!==void 0&&(clearTimeout(s),s=void 0),a.length===0)return;if(!n.consent().analyticsProcessingAllowed){a.length=0;return}let d=JSON.stringify({events:a});a.length=0;try{t(d,!0)}catch{}}return i&&typeof document<"u"&&typeof window<"u"&&typeof window.addEventListener=="function"&&(document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&l()}),window.addEventListener("pagehide",()=>l())),{produce:u,flush:l}}var wn="/.well-known/shopify/fec/produce";function ke(e=wn){return(t,n)=>{try{if(typeof fetch!="function")return;fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:t,keepalive:n}).catch(()=>{})}catch{}}}function An(e){let t;try{t=new URL(e)}catch{return""}return t.pathname=t.pathname.replace(/(\/account\/(?:reset|activate)\/[^/]+\/)[^/]+/,"$1[redacted]"),t.toString()}var Pn=[5,10,25,50,100,250,500,1e3,2500,5e3,1e4],Rn=5e3,qe=1;function Fe(e){return Object.keys(e).sort().map(t=>`${t}\0${String(e[t])}`).join("")}function En(e){return Object.entries(e).map(([t,n])=>({key:t,value:{stringValue:String(n)}}))}function On(e){return Object.entries(e).map(([t,n])=>typeof n=="boolean"?{key:t,value:{boolValue:n}}:typeof n=="number"?{key:t,value:{doubleValue:n}}:{key:t,value:{stringValue:String(n)}})}var Mn={info:{number:9,text:"INFO"},warn:{number:13,text:"WARN"},error:{number:17,text:"ERROR"}};function xn(e,t){for(let n=0;n({timeUnixNano:r.timeUnixNano,observedTimeUnixNano:r.timeUnixNano,severityNumber:r.severityNumber,severityText:r.severityText,body:{stringValue:r.body},attributes:On(r.attributes)}))}]}]}}var $n=100;function We(e){let{serviceName:t,send:n,sendLogs:r,scopeName:o="@shopify/webmcp",scopeVersion:i="0.0.0",flushDelayMs:a=Rn,now:s=Date.now,registerLifecycle:c=!1}=e,u={name:o,version:i},l=new Map,d=[],b=s(),p;function I(){p!==void 0||typeof setTimeout!="function"||(p=setTimeout(()=>{p=void 0,J()},a))}function S(P,_,R={},w="1"){if(!Number.isFinite(_))return;let N=`c${P}${w}${Fe(R)}`,U=l.get(N);U&&U.kind==="counter"?U.value+=_:l.set(N,{kind:"counter",name:P,unit:w,attributes:R,value:_}),I()}function hn(P,_,R={},w="1",N=Pn){if(!Number.isFinite(_))return;let U=`h${P}${w}${Fe(R)}`,ue=l.get(U),A;ue&&ue.kind==="histogram"?A=ue:(A={kind:"histogram",name:P,unit:w,attributes:R,bounds:N,count:0,sum:0,min:_,max:_,bucketCounts:Array.from({length:N.length+1},()=>0)},l.set(U,A)),A.count+=1,A.sum+=_,A.min=Math.min(A.min,_),A.max=Math.max(A.max,_),A.bucketCounts[xn(A.bounds,_)]+=1,I()}function bn(P,_={},R="info"){if(!r)return;d.length>=$n&&d.shift();let{number:w,text:N}=Mn[R];d.push({timeUnixNano:pe(s()),severityNumber:w,severityText:N,body:P,attributes:_}),I()}function J(){p!==void 0&&(clearTimeout(p),p=void 0);let P=l.size>0,_=d.length>0;if(!P&&!_)return;let R=s();if(P){let w=In(t,u,l.values(),pe(R),pe(b));l.clear();try{n(JSON.stringify(w),!0)}catch{}}if(_&&r){let w=Ln(t,u,d);d.length=0;try{r(JSON.stringify(w),!0)}catch{}}b=R}return c&&typeof document<"u"&&typeof window<"u"&&typeof window.addEventListener=="function"&&(document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&J()}),window.addEventListener("pagehide",()=>J())),{counter:S,histogram:hn,log:bn,flush:J}}function fe(e){return(t,n)=>{try{if(typeof fetch!="function")return;fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:t,keepalive:n}).catch(()=>{})}catch{}}}var q={analyticsProcessingAllowed:!1,marketingAllowed:!1,preferencesProcessingAllowed:!1,saleOfDataAllowed:!1},Dn=/\/(\d+)(?:\?.*)?$/;function Be(e){return typeof e=="number"?Number.isSafeInteger(e)?String(e):void 0:e===void 0||e===""?void 0:/^\d+$/.test(e)?e:Dn.exec(e)?.[1]}function Nn(e){try{return decodeURIComponent(e)}catch{return e}}function Un(e){if(!(typeof document>"u"||typeof document.cookie!="string"))for(let t of document.cookie.split("; ")){let n=t.indexOf("=");if(n===-1||t.slice(0,n)!==e)continue;let r=t.slice(n+1);return r===""?void 0:Nn(r)}}var kn="00000000-0000-0000-0000-000000000000",je="00000000-0000-0000-5000-000000000000";function ye(e){if(!(typeof e!="string"||e==="")&&!(e===kn||e===je))return e}var ee={token:void 0,denied:!1};function qn(e){try{if(typeof document>"u")return ee;let t=document.querySelector(`meta[name="${e}"]`);if(!t)return ee;let n=Number(t.getAttribute("data-expiration"));if(!Number.isFinite(n)||n<=Date.now())return ee;let r=t.getAttribute("content");return r===je?{token:void 0,denied:!0}:{token:ye(r),denied:!1}}catch{return ee}}function Ve(e,t,n){try{let o=window.Shopify?.customerPrivacy?.__internal,i=o?.[n];if(typeof i=="function")return ye(i.call(o,{generateFallback:!1,tag:"webmcp_storefront_context"}))}catch{return}let r=qn(e);if(!r.denied)return r.token!==void 0?r.token:ye(Un(t))}function te(e){try{return e?.()===!0}catch{return!1}}function ge(e){return typeof e=="object"&&e!==null}function Fn(e){return!ge(e)||e.analytics===""&&e.marketing===""&&e.preferences===""}function Wn(){try{if(!ge(window.privacyBanner))return!1;let e=window.Shopify?.customerPrivacy,t=e?.shouldShowBanner;return typeof t!="function"?!0:t()&&Fn(e?.currentVisitorConsent?.())}catch{return!0}}function me(){let e=window.Shopify?.customerPrivacy;if(!e||Wn())return q;try{if(e.consentStatus!=="loaded")return q;let t=e.currentVisitorConsent?.();if(ge(t)&&t.analytics==="no")return q}catch{return q}return{analyticsProcessingAllowed:te(e.analyticsProcessingAllowed),marketingAllowed:te(e.marketingAllowed),preferencesProcessingAllowed:te(e.preferencesProcessingAllowed),saleOfDataAllowed:te(e.saleOfDataAllowed)}}function Vn(){try{return Be(window.Shopify?.analytics?.getConfig().shop?.shopId)}catch{return}}function Bn(){try{if(typeof document>"u")return;let t=document.getElementById("shopify-features")?.textContent;if(typeof t!="string"||t==="")return;let n=JSON.parse(t);if(typeof n!="object"||n===null)return;let r=Reflect.get(n,"shopId");return typeof r=="string"||typeof r=="number"?Be(r):void 0}catch{return}}function jn(){return Vn()??Bn()}function Hn(){return window.location?.href??""}function He(){return{shopId:jn(),browserId:Ve("shopify-y","_shopify_y","uniqueToken"),sessionToken:Ve("shopify-s","_shopify_s","visitToken"),pageUrl:Hn,consent:me}}var Qn="https://otlp-http-production.shopifysvc.com/v1/metrics",Gn="https://otlp-http-production.shopifysvc.com/v1/logs",Yn="storefront_webmcp",Kn=!0,zn={localhost:!0,"127.0.0.1":!0,"0.0.0.0":!0,"[::1]":!0,"localtest.me":!0};function Ke(){if(!Kn||typeof window>"u"||typeof document>"u")return!1;let e=window.location?.host??"";return e!==""&&!zn[e]&&!e.includes(":")}var he=null,Qe=!1;function ze(){return Qe||(Qe=!0,Ke()&&(he=We({serviceName:Yn,send:fe(Qn),sendLogs:fe(Gn),registerLifecycle:!0}))),he}var be=null,Ge=!1;function Je(){return Ge||(Ge=!0,Ke()&&(be=Ue({send:ke(),context:He(),registerLifecycle:!0}))),be}var Jn="type.googleapis.com/shopify.buyer_activity.agent.WebMcpToolCallEvent";function Xn(e){return e.aborted===!0?"OUTCOME_ABORTED":e.isError?e.errorClass==="tool_error"?"OUTCOME_TOOL_ERROR":"OUTCOME_EXCEPTION":"OUTCOME_SUCCESS"}function Zn(e){let t=e.aborted===!0;return{"@type":Jn,eventType:"EVENT_TYPE_WEB_MCP_TOOL_CALL_COMPLETED",surface:"AGENT_SURFACE_STOREFRONT_WEBMCP",toolName:e.tool,outcome:Xn(e),durationMs:Math.max(0,Math.round(e.durationMs)),occurredAt:new Date().toISOString(),...e.errorClass===void 0?{}:{errorClass:e.errorClass},...t?{resultDiscarded:e.resultDiscarded===!0}:{}}}function er(e,t=ze(),n=Je()){if(tr(e,n),!t)return;let{tool:r,durationMs:o,isError:i,errorClass:a,errorMessage:s,aborted:c,resultDiscarded:u}=e;try{nr(e,t),t.log(`webmcp ${r} ${c?"aborted":i?"error":"ok"}`,{tool_name:r,duration_ms:Math.round(o),is_error:i,error_class:a??"none",...c?{aborted:!0,result_discarded:u===!0}:{},...s===void 0||!me().analyticsProcessingAllowed?{}:{error_message:s}},i?"error":"info")}catch{}}function tr(e,t){if(t)try{t.produce(Zn(e))}catch{}}function nr(e,t){let{tool:n,durationMs:r,isError:o,errorClass:i,aborted:a,resultDiscarded:s}=e,c={tool_name:n,is_error:o,error_class:i??"none"};a?t.counter("webmcp_tool_call_aborted_total",1,{tool_name:n,result_discarded:s===!0}):t.histogram("webmcp_tool_call_duration_ms",r,c,"ms"),t.counter("webmcp_tool_call_total",1,c),o&&t.counter("webmcp_tool_call_errors_total",1,{tool_name:n,error_class:i??"unknown"})}function rr(e){return typeof e=="object"&&e!==null&&typeof Reflect.get(e,"then")=="function"}function or(e){return e instanceof Error&&typeof e.name=="string"&&e.name.length>0?e.name:"Error"}function ir(e){return typeof e=="object"&&e!==null&&Reflect.get(e,"isError")===!0}var Ye=300;function Xe(e){return e.length>Ye?`${e.slice(0,Ye)}\u2026`:e}function ar(e){if(e instanceof Error&&typeof e.message=="string"&&e.message.length>0)return Xe(e.message)}function sr(e){if(typeof e!="object"||e===null)return;let t=Reflect.get(e,"structuredContent");if(typeof t!="object"||t===null)return;let n=Reflect.get(t,"error");return typeof n=="string"&&n.length>0?Xe(n):void 0}function Ze(e,t,n=ze(),r=Je()){return(o,i)=>{let a=X(i),s=performance.now(),c=p=>{er({tool:e,durationMs:performance.now()-s,...p},n,r)},u=p=>c({isError:!1,errorClass:"aborted",aborted:!0,resultDiscarded:p}),l=p=>{if(a.aborted)throw u(!0),de(a);let I=ir(p);return c({isError:I,errorClass:I?"tool_error":void 0,errorMessage:I?sr(p):void 0}),p},d=p=>{throw a.aborted||Z(p)?u(!1):c({isError:!0,errorClass:or(p),errorMessage:ar(p)}),p},b;try{b=t(o,i)}catch(p){return d(p)}return rr(b)?b.then(l,d):l(b)}}var et={checkout:()=>F("/checkout"),accountOrders:()=>F("/account/orders"),product:e=>F(`/products/${e}`),collection:e=>F(`/collections/${e}`),search:e=>F(`/search?q=${encodeURIComponent(e)}`)};function F(e){let t=cr(),n=e.startsWith("/")?e.slice(1):e;return t+n}function L(e){let n=tt()?.match?.(e);if(n?.route==="product"||n?.route==="productInCollection"){let o=n.params?.productHandle;if(o)return o}let r=e.match(/\/products\/([^/?#]+)/);return r?.[1]?lr(r[1]):""}function cr(){if(typeof window>"u")return"/";let t=tt()?.root;return typeof t!="string"?"/":t}function tt(){if(!(typeof window>"u"))return window.Shopify?.routes}function lr(e){try{return decodeURIComponent(e)}catch{return""}}var nt={type:"object",description:`A price. amount is in the currency's minor units (e.g. cents), NOT whole units: {"amount": 39800, "currency": "USD"} is $398.00. Use display for a human-readable price.`,properties:{amount:{type:"integer",description:"Price in the currency's minor units (cents for USD, so 39800 means 398.00). Not whole currency units."},currency:{type:"string",description:"ISO 4217 currency code."},display:{type:"string",description:'The price formatted for display, e.g. "$398.00".'}}},E={type:["object","null"],description:nt.description,properties:nt.properties},at={type:"object",properties:{name:{type:"string"},values:{type:"array",items:{type:"string"}}}},W={type:"object",properties:{name:{type:"string"},value:{type:"string"}}},rt={type:"object",properties:{id:{type:"string",description:"Storefront API Product GID. Pass as catalog.id to get_product."},title:{type:"string"},handle:{type:"string",description:"Product handle. Can be passed to add_to_cart as line_items[].handle."},url:{type:"string"},price_range:E,image:{type:"string"},available:{type:"boolean"},variant_count:{type:"integer",description:"Number of variants on this product record. Some stores split one item across several linked products (e.g. one product per color), so options can list more values than variant_count suggests; use get_product to see where each option value lives."},options:{type:"array",description:"Product option names and possible values. These values do not guarantee every combination is purchasable; call get_product for available variants.",items:at},product_type:{type:"string"},vendor:{type:"string"}}},st={type:"object",description:"Product + variant information for the line, sufficient to name and link to the item without an extra get_product call.",properties:{id:{type:"string",description:"Storefront API ProductVariant GID. Pass to add_to_cart as line_items[].item.id to add this variant."},title:{type:"string",description:'Product title (e.g. "Classic Hoodie").'},variant_title:{type:"string",description:'Variant title (e.g. "Large / Black"). Empty or "Default Title" for single-variant products.'},handle:{type:"string"},url:{type:"string",description:"Direct URL to the product page with the variant preselected."},image:{type:"string"},unit_price:E}},ur={type:"object",properties:{id:{type:"string",description:"Cart line GID from get_cart. Pass back to update_cart_lines as line_items[].id to update or remove this line."},item:st,quantity:{type:"integer"},line_price:{...E,description:"Total price for the line (quantity \xD7 unit_price)."}}},ot={type:"object",properties:{item:st,quantity:{type:"integer",description:"Actual quantity on the cart line after the mutation. May differ from requested_quantity if the line merged with an existing entry or availability capped the add."},requested_quantity:{type:"integer",description:"Quantity the caller asked to add."}}},it={type:"object",properties:{updated:{type:"boolean"},deduped:{type:"boolean",description:"True when this exact add was applied moments ago and was skipped to avoid a duplicate. When true, nothing changed on this call and updated is false."},item_count:{type:"integer"},total_price:E,line_items:{type:"array",description:"Items affected by this mutation, with product/variant details filled in from the post-mutation cart.",items:ot},unresolved_items:{type:"array"},resolved_items:{type:"array",description:"Present only on the clarification-needed path (nothing was applied). Items that could have been added, with pre-mutation lookup titles when available.",items:ot},warnings:{type:"array",items:{type:"string"}}}},ct={searchCatalog:{name:"search_catalog",annotations:{readOnlyHint:!0,untrustedContentHint:!0},description:"Search the store catalog for products, collections, articles, and pages. Does NOT add anything to the cart; use add_to_cart for cart changes. If the user asks for a specific product variant, call get_product after search_catalog to get its variant ID for add_to_cart, or use show_variant to display it.",inputSchema:{type:"object",required:["catalog"],properties:{catalog:{type:"object",required:["query"],properties:{query:{type:"string",description:"Search query string."},pagination:{type:"object",properties:{limit:{type:"integer",description:"Max results per type (1-10). Defaults to 5.",default:5,minimum:1,maximum:10}}}}}}},outputSchema:{type:"object",properties:{products:{type:"array",items:rt},collections:{type:"array"},articles:{type:"array"},pages:{type:"array"},search_url:{type:"string",description:"Full search results page URL."}}}},browseStore:{name:"browse_store",annotations:{readOnlyHint:!1,untrustedContentHint:!0},description:'Browse OR navigate to store collections. Set navigate=true whenever the user wants to be taken to a collection page in the browser (triggers: "browse to", "go to", "show me", "open", "take me to", "navigate to" a collection or category). With navigate=false (default), returns collection or product data without changing the page \u2014 use this only when the user is asking a question about the catalog, not asking to view it. Without a collection handle, lists all collections. With a handle, returns products from that collection; use "all" to browse everything. Does NOT add anything to the cart; use add_to_cart for cart changes. Prefer this over search_catalog when the user names a category, collection, or wants to explore. With navigate=true this MOVES the browser to the collection page; the tool result confirms the destination, and no further navigation is needed to show it.',inputSchema:{type:"object",properties:{collection:{type:"string",description:'Collection handle to browse (e.g. "best-sellers", "new-arrivals"). Omit to list all collections. Use "all" to browse every product.'},navigate:{type:"boolean",description:'When true, navigate the browser to the collection page after loading data. Set true for user intents like "browse to", "go to", "show me", "open", "take me to" a collection. Requires a collection handle. Defaults to false.'},sort_by:{type:"string",description:"Sort order. Options: best-selling (default), price-ascending, price-descending, title-ascending, title-descending, created-descending, created-ascending."},page:{type:"number",description:"Page number for pagination (starts at 1). Each page returns up to 30 products."}}},outputSchema:{type:"object",properties:{collections:{type:"array",items:{type:"object",properties:{title:{type:"string"},handle:{type:"string"},url:{type:"string"},description:{type:"string"}}}},products:{type:"array",items:rt},collection_title:{type:"string"},page:{type:"number"},sort_by:{type:"string"},navigated:{type:"boolean"},url:{type:"string"}}}},getProduct:{name:"get_product",annotations:{readOnlyHint:!1,untrustedContentHint:!0},description:`Get product details, OR navigate the browser to the product page. Set catalog.navigate=true whenever the user wants to see/view the product in the browser (triggers: "show me", "open", "view", "go to", "take me to", "navigate to" a product). Set catalog.navigate=false (default) only when you need data (description, options, variants, prices, availability) to answer a question or to prepare an add_to_cart call \u2014 the browser stays on the current page. Defaults to the current page's product if no catalog.id is provided. Does NOT add anything to the cart; use add_to_cart for that. To view a specific variant (color/size/etc.) in the browser, use show_variant instead \u2014 it accepts partial option selections like "purple" without needing every option. To add a specific variant to the cart, call get_product with catalog.selected_options to get its variant id. With catalog.navigate=true this MOVES the browser to the product page; the tool result confirms the destination, and no further navigation is needed to show it.`,inputSchema:{type:"object",properties:{catalog:{type:"object",description:"Product detail parameters.",properties:{id:{type:"string",description:"Storefront API Product GID, product handle, or product URL path. Custom app product paths and Shopify standard /products/ paths are supported. The id field from search_catalog or browse_store can be passed directly. If omitted, uses the current page's product."},navigate:{type:"boolean",description:'When true, navigate the browser to the product page after fetching details. Set true for user intents like "show me", "open", "view", "go to", "take me to" a product. Defaults to false. If the user specified partial options (e.g. only a color), prefer show_variant with selected_options instead.'},selected_options:{type:"array",description:"Known product option selections to filter available_options. Use exact option names and values from search_catalog options or a prior get_product available_options entry.",items:{type:"object",properties:{name:{type:"string",description:'Option name, e.g. "Size" or "Color".'},value:{type:"string",description:'Option value, e.g. "160cm" or "Fiberglass".'}},required:["name","value"]}}}}}},outputSchema:{type:"object",properties:{id:{type:"string",description:"Storefront API Product GID."},title:{type:"string"},handle:{type:"string"},description:{type:"object",properties:{html:{type:"string"}}},vendor:{type:"string"},type:{type:"string"},tags:{type:"array",items:{type:"string"}},url:{type:"string"},price_range:{type:"object",properties:{min:E,max:E}},available:{type:"boolean"},options:{type:"array",description:"All product option names and possible values. Use available_options to identify purchasable combinations.",items:at},variants:{type:"array",description:"Resolved variant records. When catalog.selected_options contains a complete option combination, this contains the matching variant. Pass an available variant id to add_to_cart as line_items[].item.id.",items:{type:"object",properties:{id:{type:"string",description:"Storefront API ProductVariant GID. Pass to show_variant as catalog.variant_id to display it, or add_to_cart as line_items[].item.id to add it."},title:{type:"string"},options:{type:"array",items:W},price:E,list_price:E,availability:{type:"object",properties:{available:{type:"boolean"}}},sku:{type:"string"},product_handle:{type:"string",description:"Present only when this variant belongs to a different product than the one requested \u2014 some stores sell each option value (e.g. each color) as its own product, linked as options. Pass it to show_variant as catalog.handle to display the variant."}}}},available_options:{type:"array",description:"Available option combinations, optionally filtered by catalog.selected_options. Use one full combination to call get_product again when variants[] is empty.",items:{type:"array",items:W}},available_options_count:{type:"integer",description:"Total available option combinations matching catalog.selected_options."},available_options_truncated:{type:"boolean",description:"True when more available option combinations exist than were returned."},available_options_filter:{type:"array",description:"The selected_options filter applied to available_options, when provided.",items:W},images:{type:"array",items:{type:"string"}}}}},showVariant:{name:"show_variant",annotations:{readOnlyHint:!1,untrustedContentHint:!0},description:'Navigate the browser to a product page, with a specific variant OR a partial option filter selected. Use for view intents: "show me", "open", "view", "go to", "take me to" a specific product configuration. Accepts EITHER variant_id (fully specified variant) OR selected_options (partial, e.g. only Color=Purple) \u2014 with partial options the first matching available variant is picked automatically, so DO NOT ask the user for missing options when their intent is to view. Does NOT add anything to the cart; use add_to_cart for cart changes. For cart operations you still need a full variant_id \u2014 call get_product with the full option combination first. This MOVES the browser to the exact variant page with the variant pre-selected; the tool result confirms the destination, and no further navigation is needed to show it.',inputSchema:{type:"object",required:["catalog"],properties:{catalog:{type:"object",description:"Provide EITHER variant_id OR selected_options. Handle is required unless the user is already on the product page.",properties:{handle:{type:"string",description:"Product handle. If omitted, uses the current product page's handle."},variant_id:{type:["string","number"],description:'ProductVariant ID from get_product variants[].id, e.g. "gid://shopify/ProductVariant/123", or the numeric variant ID. Use when the user picked a specific fully-specified variant. Omit when using selected_options.'},selected_options:{type:"array",description:'Partial (or full) option selections, e.g. [{"name":"Color","value":"Purple"}]. Use when the user names some options but not all (e.g. "show me the purple shoe" \u2014 pass only Color). The first matching available variant will be selected automatically. Use exact option names and values from get_product available_options or search_catalog options.',items:W}}}}},outputSchema:{type:"object",properties:{handle:{type:"string",description:"Handle of the product page that was shown. Can differ from the requested handle when the variant is sold as a separate, linked product (e.g. one product per color)."},variant_id:{type:"string"},url:{type:"string"},navigated:{type:"boolean"},selected_options:{type:"array",description:"The option selections that were resolved to a variant, if provided.",items:W}}}},getCart:{name:"get_cart",annotations:{readOnlyHint:!0,untrustedContentHint:!0},description:"Get the current shopping cart contents \u2014 line items with product titles, variant titles, handles, URLs, images, unit prices, quantities, and totals. Everything needed to describe the cart to the user in natural language, without a follow-up get_product call per line. Works from any page.",inputSchema:{type:"object",properties:{}},outputSchema:{type:"object",properties:{id:{type:"string",description:"Cart GID."},item_count:{type:"integer"},total_price:E,currency:{type:"string"},line_items:{type:"array",items:ur}}}},addToCart:{name:"add_to_cart",annotations:{readOnlyHint:!1,untrustedContentHint:!0},description:`Add products to the cart. Call this as soon as the user asks to ADD items (triggers: "add ... to my cart", "buy", "I'll take", "put ... in my basket") \u2014 in ONE call listing every item they named, up to the 10-entry limit. That request IS the authorization: do NOT ask the user to confirm before calling, and do NOT stop after search_catalog or get_product merely to report the variant you found \u2014 make the change, then tell the user it is done. Batch every item for ONE request into a SINGLE call \u2014 line_items accepts up to 10 entries; do NOT call add_to_cart once per item. Batching applies WITHIN a single request: each new thing the user asks for later is its own call. If one request names more than 10 items, split just that request into as few calls as possible. Do NOT retry a call that already returned a result: adds are cumulative, so repeating a call adds duplicate items. Use line_items[].item.id with a ProductVariant GID when the exact variant is known. Use handle or query only when adding the selected or first available variant. To change a quantity or remove something already in the cart, use update_cart_lines instead \u2014 this tool can only add.`,inputSchema:{type:"object",required:["cart"],properties:{cart:{type:"object",required:["line_items"],properties:{line_items:{type:"array",description:"Items to add (1-10).",minItems:1,maxItems:10,items:{type:"object",properties:{item:{type:"object",description:"The merchandise to add.",properties:{id:{type:"string",description:'ProductVariant GID from get_product variants[].id, e.g. "gid://shopify/ProductVariant/123".'}}},handle:{type:"string",description:"Product handle. Adds the selected or first available variant; call get_product first if the user requested specific options."},query:{type:"string",description:"Search query to find and add the selected or first available variant. For specific variants, call search_catalog/get_product first and pass item.id."},quantity:{type:"integer",description:"How many to add. Defaults to 1.",minimum:1,default:1}}}}}}}},outputSchema:it},updateCartLines:{name:"update_cart_lines",annotations:{readOnlyHint:!1,untrustedContentHint:!0},description:"Change the quantity of items already in the cart, or remove them. Every change here addresses an existing cart line by its id, so call get_cart first unless you already have line_items[].id from an earlier get_cart in this conversation. Pass the ABSOLUTE target quantity, not a delta \u2014 quantity 2 means the line ends up at 2 regardless of what it was. Use quantity 0 to remove the line entirely. Batch every change for ONE request into a SINGLE call \u2014 line_items accepts up to 10 entries; do NOT call update_cart_lines once per line. Batching applies WITHIN a single request: each new thing the user asks for later is its own call. This tool cannot add new merchandise. To add something not already in the cart, use add_to_cart. To empty the whole cart at once, use cancel_cart.",inputSchema:{type:"object",required:["cart"],properties:{cart:{type:"object",required:["line_items"],properties:{line_items:{type:"array",description:"Existing cart lines to update or remove (1-10).",minItems:1,maxItems:10,items:{type:"object",required:["id","quantity"],properties:{id:{type:"string",description:"Existing cart line id from get_cart line_items[].id. Required \u2014 this tool cannot resolve products by name."},quantity:{type:"integer",description:"Absolute target quantity for this line (not a delta). 0 removes the line.",minimum:0}}}}}}}},outputSchema:it},cancelCart:{name:"cancel_cart",annotations:{readOnlyHint:!1},description:"Remove all items from the cart in one step. Use when the user wants to empty their cart or start over.",inputSchema:{type:"object",properties:{}},outputSchema:{type:"object",properties:{cleared:{type:"boolean"},previous_item_count:{type:"number"}}}},createCheckout:{name:"proceed_to_checkout",annotations:{readOnlyHint:!1},description:"Proceed to checkout. Verifies the cart is not empty, then MOVES the browser to the checkout page. The tool result confirms the destination, and no further navigation is needed to show it.",inputSchema:{type:"object",properties:{}},outputSchema:{type:"object",properties:{navigating_to:{type:"string"},item_count:{type:"integer"},total_price:E}}},manageOrders:{name:"manage_orders",annotations:{readOnlyHint:!1},description:"Navigate to the customer's order history page. Use when the user asks about past orders, order status, tracking, or returns. The user will be prompted to log in if not already authenticated. This MOVES the browser to the order history page; the tool result confirms the destination, and no further navigation is needed to show it.",inputSchema:{type:"object",properties:{}}},searchShopPoliciesAndFaqs:{name:"search_shop_policies_and_faqs",annotations:{readOnlyHint:!0,untrustedContentHint:!0},description:`Used to get facts about the store's policies, FAQ, or contact details. When the question is about specific policy kinds, set policy_types to those kinds; leave it unset for general FAQ questions. Some examples of questions you can ask are: - What is your return policy? (policy_types: ["refund"]) - What is your shipping policy? (policy_types: ["shipping"]) - What is your phone number? (policy_types: ["contact"]) - What are your hours of operation? (policy_types: ["contact"]) - Do you offer gift wrapping? (general FAQ, no specific policy kind \u2014 leave policy_types unset) `,inputSchema:{type:"object",properties:{query:{type:"string",description:"A natural language query. Searches FAQ pages and articles, and routes policies by keyword when policy_types is omitted."},policy_types:{type:"array",description:`Policy kinds to fetch, chosen from the user's question \u2014 e.g. ["refund"] for returns/exchanges, ["contact"] for phone/hours/address. Include every kind the question touches. Omit when no specific policy is relevant (e.g. a general FAQ question).`,items:{type:"string",enum:["refund","shipping","privacy","terms_of_service","terms_of_sale","subscription","legal_notice","contact"]}}},required:["query"]},outputSchema:{type:"object",properties:{policies:{type:"array",description:"Store policies and contact information matching the query.",items:{type:"object",properties:{type:{type:"string",description:"Policy kind: refund, shipping, privacy, terms_of_service, terms_of_sale, subscription, legal_notice, or contact."},title:{type:"string"},url:{type:"string"},body:{type:"string",description:"The policy text (may contain HTML)."}}}},pages:{type:"array",description:"Store pages (e.g. FAQ, help) matching the query.",items:{type:"object",properties:{title:{type:"string"},handle:{type:"string"},url:{type:"string"},body:{type:"string",description:"The page body (may contain HTML) for the top matched pages."}}}},articles:{type:"array",description:"Blog articles matching the query.",items:{type:"object",properties:{title:{type:"string"},handle:{type:"string"},url:{type:"string"},excerpt:{type:"string"}}}}}}},getUcpProfile:{name:"get_ucp_profile",annotations:{readOnlyHint:!0,untrustedContentHint:!0},description:"Get this store's Universal Commerce Protocol (UCP) profile, as served at /.well-known/ucp: the UCP version, the services the store offers with their endpoints (e.g. the store's UCP MCP server), its capabilities, and its payment handlers. Use it to discover how to continue a purchase with this store over UCP, or to check which platform operates the store. Read-only; works from any page.",inputSchema:{type:"object",properties:{}},outputSchema:{type:"object",properties:{ucp:{type:"object",description:"The UCP profile exactly as served. Keys include version, supported_versions (older versions keyed to their profile URLs), services (keyed by service name, e.g. dev.ucp.shopping; each a list of bindings with version, spec, transport, endpoint and schema), capabilities (keyed by capability name), and payment_handlers (keyed by handler name)."}}}}};var g=((e,t)=>{let n=e;if(t){let r=new Set;for(let o of t)r.has(o)||(r.add(o),n+=` `+o)}return n});var lt="2026-04";function ut(e){return e?e.startsWith("v1_")?dr(e.replace(/^v1_/,"")):(typeof console<"u"&&console.warn(`[webmcp] Unsupported variant encoding: "${e}"`),[]):[]}function dr(e){let t=/[ :,-]/g,n={currentOptionValue:[],decodedOptions:[],depth:0,index:0,rangeStart:null},r;for(;r=t.exec(e);)pr(e,n,r,t);return gr(e,n),n.decodedOptions}function pr(e,t,n,r){let o=n[0],i=Number.parseInt(e.slice(t.index,n.index),10)||0;dt(t,i),t.currentOptionValue[t.depth]=i,o==="-"?t.rangeStart=i:o===":"?t.depth++:fr(e,t,n,o),t.index=r.lastIndex}function fr(e,t,n,r){yr(e,n,r)&&t.decodedOptions.push([...t.currentOptionValue]),r===","&&(t.currentOptionValue.pop(),t.depth--)}function yr(e,t,n){return n===" "||n===","&&e[t.index-1]!==","}function gr(e,t){let n=e.match(/\d+$/g)?.[0];if(n===void 0)return;let r=Number.parseInt(n,10);if(t.rangeStart!==null){dt(t,r+1);return}t.currentOptionValue[t.depth]=r,t.decodedOptions.push([...t.currentOptionValue])}function dt(e,t){let n=e.rangeStart;if(n!==null){for(let r=n;r{let o=e;return n&&(o+=` ${n}`),r&&(o+=` Next steps: ${r}`),{content:[{type:"text",text:o}],structuredContent:t}},yt="This add has been applied: item_count and total in this result reflect the cart after the update. Adds are cumulative, so calling add_to_cart again for these same items would add duplicates. Lines already in the cart can be changed or removed with update_cart_lines.",gt="This change has been applied: item_count and total in this result reflect the cart after the update, so there is no need to re-run it to confirm. Items not yet in the cart can be added with add_to_cart.",mt="The cart has been emptied: this result reflects its current state, so calling cancel_cart again would have no effect. New items can be added with add_to_cart.",V=(e,t,n)=>{let r=n?` ${n}`:"";return{content:[{type:"text",text:`${e}${r}`}],structuredContent:t}},O=(e,t)=>{let{summary:n,navigated:r,destination:o,keyFields:i}=e,a=o?`the ${o} page`:"the requested page",c=`${r?`This tool has navigated the browser to ${a}, so the shopper will be looking at it without any further navigation. Navigating to the same page again would only reload it.`:`The browser was already on ${a}, so no navigation was needed.`} ${n}`;return i&&(c+=` ${i}`),{content:[{type:"text",text:c}],structuredContent:t}},f=(e,t)=>{let n=`Error: ${e}`;return t&&(n+=` Recovery: ${t}`),{content:[{type:"text",text:n}],structuredContent:{error:e},isError:!0}},y=(e,t,n,r)=>{if(t.aborted||Z(e))throw e;return f(e instanceof Error?e.message:n,r)},B=()=>{let e=window.Shopify?.actions;if(!e?.getCart||!e.updateCart)throw new Error("Standard Actions are not available. Ensure Shopify Standard Actions are available before calling cart tools.");return e},$=async(e,t=B())=>(await t.getCart(void 0,{signal:e})).cart??{},ne=e=>{De(e)},re=e=>{let t=e.userErrors?.map(n=>n.message).filter(Boolean);if(t?.length)throw new Error(t.join(", "))},oe=e=>e.warnings?.map(t=>t.message).filter(_e)??[],ht=e=>e.lines?.nodes??[],D=e=>e.totalQuantity??0,pt=new Map,bt=e=>{let t=String(e??"").toUpperCase();if(!t)return 2;let n=pt.get(t);if(n!=null)return n;try{let r=new Intl.NumberFormat("en",{style:"currency",currency:t}).resolvedOptions().maximumFractionDigits??2;return pt.set(t,r),r}catch{return 2}},h=e=>{if(e?.amount==null||!e.currencyCode)return null;let t=Number(e.amount);if(!Number.isFinite(t))return null;let n={amount:Math.round(t*10**bt(e.currencyCode)),currency:e.currencyCode},r=v(n);return r?{...n,display:r}:n},v=e=>{if(!e)return"";let t=bt(e.currency),n=e.amount/10**t;try{return new Intl.NumberFormat("en-US",{style:"currency",currency:e.currency}).format(n)}catch{return`${n.toFixed(t)} ${e.currency}`}},_e=e=>typeof e=="string"&&e.length>0,M=e=>{if(typeof window>"u")return!1;let t=new URL(window.location.href);return t.pathname+t.search===e},x=(e,t,n=0)=>{let{signal:r}=e;if(r.aborted)return;let o=setTimeout(()=>{r.aborted||e.navigate(t),i()},n),i=Ne(r,()=>clearTimeout(o))},ft="gid://shopify/ProductVariant/";function T(e){if(e===void 0)return"";let t=String(e).trim(),n=t.startsWith(ft)?t.slice(ft.length):t;return/^\d+$/.test(n)?n:""}var mr=`/api/${lt}/graphql.json`,ve=30,hr=50,_t=50,br="gid://shopify/Product/",Se=g("fragment WebMcpMoney on MoneyV2{amount currencyCode}"),Te=g("fragment WebMcpProductCard on Product{id title handle vendor productType availableForSale onlineStoreUrl featuredImage{url altText}priceRange{minVariantPrice{...WebMcpMoney}}variantsCount{count}options{name optionValues{name}}}",[Se]),Ct=g("fragment WebMcpProductForCart on Product{title handle selectedOrFirstAvailableVariant{id title availableForSale}}"),_r=g("fragment WebMcpCartDetails on Cart{id totalQuantity cost{totalAmount{...WebMcpMoney}}lines(first:250){nodes{id quantity cost{totalAmount{...WebMcpMoney}}merchandise{__typename ...on ProductVariant{id title image{url altText}price{...WebMcpMoney}product{id title handle onlineStoreUrl}}}}}}",[Se]),vr=g("fragment WebMcpProductVariant on ProductVariant{id title availableForSale sku price{...WebMcpMoney}compareAtPrice{...WebMcpMoney}selectedOptions{name value}product{handle}}",[Se]),wt=g("fragment WebMcpProductDetails on Product{id title handle descriptionHtml vendor productType tags availableForSale onlineStoreUrl featuredImage{url altText}priceRange{minVariantPrice{...WebMcpMoney}maxVariantPrice{...WebMcpMoney}}variantsCount{count}encodedVariantAvailability selectedOrFirstAvailableVariant{...WebMcpProductVariant}options{name optionValues{name}}images(first:20){nodes{url altText}}}",[vr]),Sr=g("query WebMcpSearchCatalog($query:String!$types:[PredictiveSearchType!]$limit:Int!){predictiveSearch(query:$query types:$types limit:$limit){products{...WebMcpProductCard}collections{title handle description onlineStoreUrl}articles{title handle excerpt onlineStoreUrl}pages{title handle onlineStoreUrl}}}",[Te]),Tr=g("query WebMcpSearchPoliciesAndFaqs($query:String!$types:[PredictiveSearchType!]$limit:Int!$includeRefund:Boolean!$includeShipping:Boolean!$includePrivacy:Boolean!$includeTermsOfService:Boolean!$includeTermsOfSale:Boolean!$includeSubscription:Boolean!$includeLegalNotice:Boolean!$includeContact:Boolean!){shop{refundPolicy@include(if:$includeRefund){title body url}shippingPolicy@include(if:$includeShipping){title body url}privacyPolicy@include(if:$includePrivacy){title body url}termsOfService@include(if:$includeTermsOfService){title body url}termsOfSale@include(if:$includeTermsOfSale){title body url}subscriptionPolicy@include(if:$includeSubscription){title body url}legalNotice@include(if:$includeLegalNotice){title body url}contactInformation@include(if:$includeContact){title body url}}predictiveSearch(query:$query types:$types limit:$limit){articles{title handle excerpt onlineStoreUrl}pages{title handle onlineStoreUrl}}}"),Cr=3,wr=g("query WebMcpPageBodies($h1:String$h2:String$h3:String){p1:page(handle:$h1){title body}p2:page(handle:$h2){title body}p3:page(handle:$h3){title body}}"),Ar=g("query WebMcpListCollections($first:Int!){collections(first:$first){nodes{title handle description onlineStoreUrl}}}"),Pr=g("query WebMcpBrowseProducts($first:Int!$sortKey:ProductSortKeys$reverse:Boolean!){products(first:$first sortKey:$sortKey reverse:$reverse){nodes{...WebMcpProductCard}}}",[Te]),Rr=g("query WebMcpBrowseCollectionProducts($handle:String!$first:Int!$sortKey:ProductCollectionSortKeys$reverse:Boolean!){collection(handle:$handle){title handle description onlineStoreUrl products(first:$first sortKey:$sortKey reverse:$reverse){nodes{...WebMcpProductCard}}}}",[Te]),Er=g("query WebMcpProductByHandle($handle:String!$selectedOptions:[SelectedOptionInput!]!$hasSelectedOptions:Boolean!){product(handle:$handle){...WebMcpProductDetails variantBySelectedOptions(selectedOptions:$selectedOptions caseInsensitiveMatch:true)@include(if:$hasSelectedOptions){...WebMcpProductVariant}}}",[wt]),Or=g("query WebMcpProductById($id:ID!$selectedOptions:[SelectedOptionInput!]!$hasSelectedOptions:Boolean!){node(id:$id){__typename ...on Product{...WebMcpProductDetails variantBySelectedOptions(selectedOptions:$selectedOptions caseInsensitiveMatch:true)@include(if:$hasSelectedOptions){...WebMcpProductVariant}}}}",[wt]),Mr=g("query WebMcpVariantProductHandle($id:ID!$handle:String!){node(id:$id){__typename ...on ProductVariant{product{id handle}}}requested:product(handle:$handle){id}}"),xr=g("query WebMcpProductForCartByHandle($handle:String!){product(handle:$handle){...WebMcpProductForCart}}",[Ct]),Ir=g("query WebMcpCartDetails($id:ID!){cart(id:$id){...WebMcpCartDetails}}",[_r]),Lr=g("query WebMcpSearchProductForCart($query:String!){predictiveSearch(query:$query types:[PRODUCT]limit:1){products{...WebMcpProductForCart}}}",[Ct]);async function At(e,t,n){let r=await C(Sr,{query:e,types:["PRODUCT","COLLECTION","ARTICLE","PAGE"],limit:t},n);return{predictiveSearch:kr(r.predictiveSearch)}}var Pt=[{type:"refund",field:"refundPolicy",include:"includeRefund"},{type:"shipping",field:"shippingPolicy",include:"includeShipping"},{type:"privacy",field:"privacyPolicy",include:"includePrivacy"},{type:"terms_of_service",field:"termsOfService",include:"includeTermsOfService"},{type:"terms_of_sale",field:"termsOfSale",include:"includeTermsOfSale"},{type:"subscription",field:"subscriptionPolicy",include:"includeSubscription"},{type:"legal_notice",field:"legalNotice",include:"includeLegalNotice"},{type:"contact",field:"contactInformation",include:"includeContact"}],Ce=Pt.map(e=>e.type);async function Rt(e,t,n,r){let o=new Set(n),i=await C(Tr,{query:e,types:["ARTICLE","PAGE"],limit:t,includeRefund:o.has("refund"),includeShipping:o.has("shipping"),includePrivacy:o.has("privacy"),includeTermsOfService:o.has("terms_of_service"),includeTermsOfSale:o.has("terms_of_sale"),includeSubscription:o.has("subscription"),includeLegalNotice:o.has("legal_notice"),includeContact:o.has("contact")},r),a=(i.predictiveSearch?.pages??[]).map(Pe),s=(i.predictiveSearch?.articles??[]).map(Ae);return{policies:$r(i.shop),articles:s,pages:await Dr(a,r)}}function $r(e){return e?Pt.flatMap(({type:t,field:n})=>{let r=e[n];return r?[{type:t,title:r.title??"",url:r.url??"",body:r.body??""}]:[]}):[]}async function Dr(e,t){let n=e.filter(s=>s.handle).slice(0,Cr);if(!n.length)return e;let r=n.map(s=>s.handle),o=await C(wr,{h1:r[0]??null,h2:r[1]??null,h3:r[2]??null},t),i=[o.p1,o.p2,o.p3],a=new Map;return n.forEach((s,c)=>{let u=i[c]?.body;u&&a.set(s.handle,u)}),e.map(s=>{let c=a.get(s.handle);return c?{...s,body:c}:s})}async function Et(e){return{collections:{nodes:(await C(Ar,{first:hr},e)).collections?.nodes?.map(we)??[]}}}async function Ot(e){let t=await C(Pr,{first:Lt(e.page),...Nr(e.sortBy)},e.signal);return{products:$t(t.products?.nodes??[],e.page).map(j),title:"All products"}}async function Mt(e){let t=e.handle.trim(),n=await C(Rr,{handle:t,first:Lt(e.page),...Ur(e.sortBy)},e.signal),r=n.collection?we(n.collection):null;return{collection:r,products:$t(n.collection?.products?.nodes??[],e.page).map(j),title:r?.title??t}}async function H(e,t){let n=Re(e);if(!n)return null;let r=Dt(t.selected_options),o=r.length>0;if(ro(n)){let s=(await C(Or,{id:n,selectedOptions:r,hasSelectedOptions:o},t.signal)).node;return s?.__typename==="Product"?Tt(j(s),t):null}let i=await C(Er,{handle:n,selectedOptions:r,hasSelectedOptions:o},t.signal);return i.product?Tt(j(i.product),t):null}async function xt(e,t,n){let r=await C(Mr,{id:e,handle:t},n),o=r.node;if(o?.__typename!=="ProductVariant")return null;let i=o.product;if(!i?.handle)return null;let a=!!i.id&&i.id===r.requested?.id;return{handle:i.handle,sameProduct:a}}async function Q(e,t,n){let r=e.trim();if(!r)return null;let i=(await C(Ir,{id:r},n)).cart;return i?{id:i.id??r,item_count:i.totalQuantity??0,total_price:h(i.cost?.totalAmount),currency:i.cost?.totalAmount?.currencyCode??"",line_items:(i.lines?.nodes??[]).map(a=>qr(a,t))}:null}async function It(e){if(e.handle?.trim()){let t=await C(xr,{handle:e.handle.trim()},e.signal);return t.product?vt(t.product):null}if(e.query?.trim()){let n=(await C(Lr,{query:e.query.trim()},e.signal)).predictiveSearch?.products?.[0];return n?vt(n):null}return null}async function C(e,t,n){let r=await fetch(mr,{method:"POST",headers:{accept:"application/json","content-type":"application/json"},body:JSON.stringify({query:e,variables:t}),signal:n});if(!r.ok)throw new Error(`Storefront API request failed (${r.status})`);let o=await r.json();if(o.errors?.length)throw new Error(o.errors.map(i=>i.message).filter(Boolean).join(", "));if(!o.data)throw new Error("Storefront API response did not include data.");return o.data}function Lt(e){return Math.min(Math.max(1,e)*ve,250)}function $t(e,t){let n=(Math.max(1,t)-1)*ve;return e.slice(n,n+ve)}function Nr(e){switch(e){case"price-ascending":return{sortKey:"PRICE",reverse:!1};case"price-descending":return{sortKey:"PRICE",reverse:!0};case"title-ascending":return{sortKey:"TITLE",reverse:!1};case"title-descending":return{sortKey:"TITLE",reverse:!0};case"created-ascending":return{sortKey:"CREATED_AT",reverse:!1};case"created-descending":return{sortKey:"CREATED_AT",reverse:!0};case"best-selling":default:return{sortKey:"BEST_SELLING",reverse:!1}}}function Ur(e){switch(e){case"price-ascending":return{sortKey:"PRICE",reverse:!1};case"price-descending":return{sortKey:"PRICE",reverse:!0};case"title-ascending":return{sortKey:"TITLE",reverse:!1};case"title-descending":return{sortKey:"TITLE",reverse:!0};case"created-ascending":return{sortKey:"CREATED",reverse:!1};case"created-descending":return{sortKey:"CREATED",reverse:!0};case"best-selling":default:return{sortKey:"BEST_SELLING",reverse:!1}}}function kr(e){return{products:(e?.products??[]).map(j),collections:(e?.collections??[]).map(we),articles:(e?.articles??[]).map(Yr),pages:(e?.pages??[]).map(Kr)}}function j(e){let t=e.selectedOrFirstAvailableVariant?St(e.selectedOrFirstAvailableVariant):null,n=e.variantBySelectedOptions?St(e.variantBySelectedOptions):null;return{id:e.id,title:e.title,handle:e.handle,descriptionHtml:e.descriptionHtml,vendor:e.vendor,productType:e.productType,tags:e.tags,availableForSale:e.availableForSale,onlineStoreUrl:e.onlineStoreUrl,featuredImage:e.featuredImage??null,priceRange:e.priceRange,variantCount:e.variantsCount?.count??0,selectedOrFirstAvailableVariant:t,variantBySelectedOptions:n,encodedVariantAvailability:e.encodedVariantAvailability,options:jr(e.options),images:Qr(e.images?.nodes)}}function qr(e,t){return{id:e.id??"",quantity:e.quantity??0,line_price:h(e.cost?.totalAmount),item:Fr(e,t)}}function Fr(e,t){let n=Wr(e),r=n.product;return{id:n.id,title:r.title,variant_title:n.title,handle:r.handle,url:Br({handle:r.handle,onlineStoreUrl:r.onlineStoreUrl},n.id,t),image:n.image,unit_price:h(n.price)}}function Wr(e){let t=e.merchandise,n=t?.__typename==="ProductVariant"?t:null;return{id:n?.id??"",title:n?.title??"",image:n?.image?.url??"",price:n?.price,product:Vr(n?.product)}}function Vr(e){return{id:e?.id??"",title:e?.title??"",handle:e?.handle??"",onlineStoreUrl:e?.onlineStoreUrl}}function Br(e,t,n){let r=Y(e,a=>n.product(a));if(!r)return"";let o=t.split("/").pop();if(!o)return r;let i=r.includes("?")?"&":"?";return`${r}${i}variant=${encodeURIComponent(o)}`}function vt(e){let t=e.selectedOrFirstAvailableVariant;return!t?.id||!t.availableForSale?null:{product:{title:e.title,handle:e.handle},variant:{merchandise_id:t.id,title:t.title}}}function jr(e){return e?.map(t=>({name:t.name??"",values:t.optionValues?.map(n=>n.name)??[]}))??[]}function Hr(e){return e?.map(t=>({name:t.name??"",value:t.value??""}))??[]}function Qr(e){return e?.filter(Gr)??[]}function St(e){return{id:e.id??"",title:e.title??"",availableForSale:!!e.availableForSale,price:e.price,compareAtPrice:e.compareAtPrice,sku:e.sku,selectedOptions:Hr(e.selectedOptions),productHandle:e.product?.handle??void 0}}function Gr(e){return e!=null}function we(e){return{title:e.title,handle:e.handle,description:e.description,onlineStoreUrl:e.onlineStoreUrl}}function Yr(e){return{title:e.title,handle:e.handle,excerpt:e.excerpt,onlineStoreUrl:e.onlineStoreUrl}}function Kr(e){return{title:e.title,handle:e.handle,onlineStoreUrl:e.onlineStoreUrl}}function G(e,t){let n=oo(e);return{id:e.id??"",title:e.title??"",handle:n,url:zr(e,n,t),price_range:h(e.priceRange?.minVariantPrice),image:Ut(e.featuredImage),available:!!e.availableForSale,variant_count:e.variantCount??0,options:e.options??[],product_type:e.productType??"",vendor:e.vendor??""}}function zr(e,t,n){return Y({handle:t,onlineStoreUrl:e.onlineStoreUrl},r=>n.product(r))}function Tt(e,t){let n=G(e,t.routes),r=e.options??[],o=Dt(t.selected_options),i=Xr(r,e,o),a=Jr(e,o);return{...n,description:{html:e.descriptionHtml??""},type:e.productType??"",tags:e.tags??[],price_range:{min:h(e.priceRange?.minVariantPrice),max:h(e.priceRange?.maxVariantPrice)},variants:a.map(s=>no(s,n.handle)),available_options:i.options,available_options_count:i.count,available_options_truncated:i.truncated,available_options_filter:o.length?o:void 0,images:e.images?.map(Ut).filter(_e)??[]}}function Jr(e,t){return t.length?e.variantBySelectedOptions?[e.variantBySelectedOptions]:[]:e.selectedOrFirstAvailableVariant?[e.selectedOrFirstAvailableVariant]:[]}function Xr(e,t,n){let r=ut(t.encodedVariantAvailability),o=[];for(let s of r){let c=Zr(e,s);c&&eo(c,n)&&o.push(c)}let a=n.length>0||o.length<=_t?o.slice(0,_t):[];return{options:a,count:o.length,truncated:o.length>a.length}}function Zr(e,t){if(!e.length||t.length!==e.length)return null;let n=[];for(let[r,o]of e.entries()){let i=o.values[t[r]];if(!i)return null;n.push({name:o.name,value:i})}return n}function eo(e,t){return t.every(n=>e.some(r=>to(r,n)))}function to(e,t){return ie(e.name)===ie(t.name)&&ie(e.value)===ie(t.value)}function Dt(e){return e?.map(t=>({name:t.name?.trim()??"",value:t.value?.trim()??""})).filter(t=>t.name&&t.value)??[]}function ie(e){return e?.trim().toLowerCase()??""}function no(e,t){let n=e.productHandle&&e.productHandle!==t?e.productHandle:void 0;return{id:e.id??"",title:e.title??"",options:e.selectedOptions??[],price:h(e.price),list_price:h(e.compareAtPrice),availability:{available:!!e.availableForSale},sku:e.sku??void 0,...n?{product_handle:n}:{}}}function ae(e,t){let n=e.handle??"";return{title:e.title??"",handle:n,url:Y(e,r=>t.collection(r)),description:e.description??""}}function Ae(e){return{title:e.title??"",handle:e.handle??"",url:Y(e),excerpt:e.excerpt??""}}function Pe(e){return{title:e.title??"",handle:e.handle??"",url:Y(e)}}function Y(e,t){let n=Nt(e.onlineStoreUrl);if(n)return n;let r=e.handle?.trim();return r?t?.(r)??"":""}function Re(e){let t=e?.trim();return t?L(t)||t:""}function ro(e){return e.startsWith(br)}function oo(e){return e.handle??L(Nt(e.onlineStoreUrl))}function Nt(e){if(!e)return"";if(e.startsWith("/"))return e;try{let t=new URL(e);return e.replace(t.origin,"")}catch{return e}}function Ut(e){return e?.url??""}var io=new Set(["best-selling","price-ascending","price-descending","title-ascending","title-descending","created-ascending","created-descending"]),qt=async(e,t)=>{try{let n=e.collection?.trim(),r=e.navigate===!0;if(!n)return so(await Et(t.signal),t.routes,r);let o=Math.max(1,Number(e.page)||1),i=lo(e.sort_by),a=await ao(n,i,o,t.signal);return co(n,a,i,o,t,r)}catch(n){return y(n,t.signal,"Failed to browse store","Try browsing without a collection to list available collections.")}};async function ao(e,t,n,r){return e==="all"?Ot({page:n,sortBy:t,signal:r}):Mt({handle:e,page:n,sortBy:t,signal:r})}function so(e,t,n){let r=e.collections?.nodes?.map(i=>ae(i,t))??[],o=n?'A collection handle is required to navigate. Ask the user which collection, or call browse_store again with a specific collection handle (or "all") and navigate=true.':'Call browse_store with a collection handle, or with collection "all" to browse products. Set navigate=true to take the user to the collection page.';return m(`Found ${r.length} collection${r.length!==1?"s":""}.`,{collections:r,products:[],navigated:!1},uo(r),o)}function co(e,t,n,r,o,i){let{routes:a}=o;if(e!=="all"&&!t.collection)return f(`Collection "${e}" was not found.`,"Call browse_store without a collection to list available collections.");let s=t.products.map(l=>G(l,a)),c=a.collection(e),u={collections:[],products:s,collection_title:t.title,page:r,sort_by:n,url:c};if(i){let l=!M(c);return l&&x(o,c),O({summary:l?`Showing the ${t.title} collection.`:`Already showing the ${t.title} collection.`,navigated:l,destination:`${t.title} collection`,keyFields:kt(s)},{...u,navigated:l})}return m(`Showing ${s.length} product${s.length!==1?"s":""} from ${t.title}.`,{...u,navigated:!1},kt(s),"If the user asked to be taken to this collection, call browse_store again with navigate=true. If the user wants the selected or first available variant, call add_to_cart with cart.line_items using the product handle. If the user requested a specific color, size, material, or other option, call get_product with catalog.id and any known catalog.selected_options, then use the matching variants[].id with add_to_cart, OR call show_variant with selected_options to just navigate to that variant.")}function lo(e){return e&&io.has(e)?e:"best-selling"}function uo(e){return e.length?`Collections: ${e.map(t=>`- ${t.title} (${t.handle})`).join(` `)}`:null}function kt(e){return e.length?`Products: ${e.map(t=>`- ${t.title} (id: ${t.id}, handle: ${t.handle}) - ${v(t.price_range)||"price unavailable"}`).join(` `)}`:null}var Ft=10,Wt=async(e,t)=>{let n=e.cart?.line_items;if(!Array.isArray(n)||n.length===0)return f("No line_items provided.","Call add_to_cart with cart.line_items.");let r=n.slice(0,Ft);try{let o=await Promise.all(r.map((a,s)=>fo(a??{},s,t.signal))),i=o.filter(Qt);return i.length?jt(i,o,r.length):await Bt(o.filter(Gt),t,yt)}catch(o){return y(o,t.signal,"Cart update failed","Call get_cart to verify cart state, then retry add_to_cart with an explicit line_items[].item.id.")}},Vt=async(e,t)=>{let n=e.cart?.line_items;if(!Array.isArray(n)||n.length===0)return f("No line_items provided.","Call get_cart, then call update_cart_lines with cart.line_items[].id and the target quantity.");let r=n.slice(0,Ft),o=r.map((a,s)=>po(a??{},s)),i=o.filter(Qt);if(i.length)return jt(i,o,r.length);try{return await Bt(o.filter(Gt),t,gt)}catch(a){return y(a,t.signal,"Cart update failed","Call get_cart to verify cart state, then retry update_cart_lines with the current line_items[].id.")}};async function Bt(e,t,n){let r=e.filter(se),o=await Eo(r,t),i=new Set(o.map(({add:S})=>T(S.merchandiseId))),a=e.filter(S=>!(S.type==="add"&&i.has(T(S.merchandiseId))));if(k("decision",{requested:e.length,skippedAsDuplicate:o.length,willWrite:a.length}),a.length===0)return Mo(o);ne(t.signal);let c=await B().updateCart({lines:a.map(S=>S.type==="update"?{id:S.id,quantity:S.quantity}:{merchandiseId:S.merchandiseId,quantity:S.quantity})});re(c);let u=a.filter(se);u.length?Po(u):Me();let l=oe(c),d=c.cart??{},b=h(d.cost?.totalAmount),p=await bo(u,d.id,t),I=V([_o(a,D(d),b,l),xo(o)].filter(Boolean).join(" "),{updated:!0,...o.length?{deduped:!0}:{},item_count:D(d),total_price:b,line_items:p,warnings:l.length?l:void 0},n);return u.length&&!t.signal.aborted&&Ro(u),I}function po(e,t){if(!e.id)return{type:"unresolved",item:t+1,kind:"needs-cart-line",reason:"update_cart_lines needs the cart line's id. Call get_cart and pass line_items[].id, or use add_to_cart if this item is not in the cart yet."};let n=Oe(e.quantity);return n===null?{type:"unresolved",item:t+1,kind:"needs-cart-line",reason:`line_items[${t}] is missing a readable quantity. update_cart_lines needs the ABSOLUTE target quantity for the line (0 removes it); it cannot assume one.`}:n<0?{type:"unresolved",item:t+1,kind:"needs-cart-line",reason:`line_items[${t}] has a negative quantity (${n}). update_cart_lines takes the ABSOLUTE target quantity, not a delta \u2014 pass the quantity the line should end up at, or 0 to remove it.`}:{type:"update",id:e.id,quantity:n}}async function fo(e,t,n){let r=go(e.quantity),o=yo(e);if(o)return{type:"unresolved",item:t+1,kind:"needs-cart-line",reason:`line_items[${t}] has a cart line id ("${o}"), so it is already in the cart. add_to_cart only adds new merchandise \u2014 call update_cart_lines with that id to change its quantity or remove it.`,query:e.query,handle:e.handle};if(mo(e.quantity))return{type:"unresolved",item:t+1,kind:"needs-cart-line",reason:"add_to_cart can only add. To remove an item or set its quantity to 0, call get_cart for the line id and then update_cart_lines.",query:e.query,handle:e.handle};if(e.item?.id)return{type:"add",merchandiseId:e.item.id,quantity:r};let i=await It({handle:e.handle,query:e.query,signal:n});return i?{type:"add",merchandiseId:i.variant.merchandise_id,quantity:r,productTitle:i.product.title,variantTitle:i.variant.title}:{type:"unresolved",item:t+1,kind:"lookup-failed",reason:e.handle?`Could not resolve product handle "${e.handle}".`:e.query?`Could not find a product for query "${e.query}".`:"Missing item.id, handle, or query.",query:e.query,handle:e.handle}}function yo(e){let t=e.id;return typeof t=="string"&&t.trim()!==""?t:void 0}function Oe(e){let t=typeof e=="number"?e:typeof e=="string"&&e.trim()!==""?Number(e):Number.NaN;return Number.isFinite(t)?Math.floor(t):null}function go(e){let t=Oe(e);return t===null?1:Math.max(1,t)}function mo(e){let t=Oe(e);return t!==null&&t<=0}function jt(e,t,n){let r=t.filter(se),o=e.map(i=>`- Item ${i.item}: ${i.reason}`).join(` `);return m(`Need clarification for ${e.length} of ${n} line_item${n===1?"":"s"}. Nothing changed.`,{updated:!1,unresolved_items:e,resolved_items:r.map(Ht)},o,ho(e))}function ho(e){let t=[];return e.some(({kind:n})=>n==="lookup-failed")&&t.push("NOTHING was added \u2014 not even the line items that resolved. Resolve the problem above (search_catalog or get_product for an explicit product or variant id), then call add_to_cart again with the COMPLETE set of line items for this request, including the ones listed as resolved: re-sending only the failed one would drop the rest. For specific variant requests prefer line_items[].item.id from get_product variants[].id."),e.some(({kind:n})=>n==="needs-cart-line")&&t.push("To change or remove something already in the cart, call get_cart and pass that line's line_items[].id to update_cart_lines with the ABSOLUTE target quantity (0 removes the line). A handle or query can never remove or reduce a line."),t.join(" ")}async function bo(e,t,n){let r=e.map(Ht);if(!t||e.length===0)return r;let o;try{o=await Q(t,n.routes,n.signal)}catch{return r}if(!o)return r;let i=new Map;for(let a of o.line_items){let s=T(a.item.id);s&&i.set(s,a)}return e.map((a,s)=>{let c=i.get(T(a.merchandiseId));return c?{item:c.item,quantity:c.quantity,requested_quantity:a.quantity}:r[s]})}function Ht(e){return{item:{id:e.merchandiseId,title:e.productTitle??"",variant_title:e.variantTitle??"",handle:"",url:"",image:"",unit_price:null},quantity:e.quantity,requested_quantity:e.quantity}}function _o(e,t,n,r){let o=e.filter(se),i=e.filter(vo),a=o.reduce((l,d)=>l+d.quantity,0),s=[];o.length&&s.push(`Added ${a} item${a===1?"":"s"} across ${o.length} product${o.length===1?"":"s"}`),i.length&&s.push(`updated ${i.length} line${i.length===1?"":"s"}`);let c=`Cart now has ${t} item${t===1?"":"s"}${n?` totaling ${v(n)}`:""}.`,u=r.length?` Warnings: ${r.join("; ")}.`:"";return`${s.join(" and ")}. ${c}${u}`}function Qt(e){return e.type==="unresolved"}function Gt(e){return e.type==="add"||e.type==="update"}function se(e){return e.type==="add"}function vo(e){return e.type==="update"}var So=6e4,Yt="shopify.webmcp.recentAdds",Ee=new Map;function To(e){if(typeof e!="object"||e===null)return!1;let t=e;return typeof t.merchandiseId=="string"&&typeof t.quantity=="number"&&typeof t.at=="number"&&typeof t.confirmed=="boolean"}function K(){let e=Co();return e&&e.size>0?e:new Map(Ee)}function Co(){try{let e=window.sessionStorage.getItem(Yt);if(!e)return;let t=JSON.parse(e);if(typeof t!="object"||t===null)return;let n=new Map;for(let[r,o]of Object.entries(t)){if(!To(o))continue;let i=T(r);i&&n.set(i,o)}return n}catch{return}}function z(e){Ee.clear();for(let[t,n]of e)Ee.set(t,n);try{window.sessionStorage.setItem(Yt,JSON.stringify(Object.fromEntries(e)))}catch{}}function Me(){z(new Map)}function wo(e){let t=K(),n=t.get(e);if(n){if(Date.now()-n.at>=So){t.delete(e),z(t);return}return n}}function Ao(e){let t=K();t.delete(e)&&z(t)}function Po(e){let t=K(),n=Date.now();for(let r of e)t.set(T(r.merchandiseId),{merchandiseId:r.merchandiseId,quantity:r.quantity,at:n,confirmed:!1});z(t),k("remember",{merchandiseIds:e.map(r=>r.merchandiseId)})}function Ro(e){let t=K(),n=!1;for(let r of e){let o=t.get(T(r.merchandiseId));o&&(o.confirmed=!0,n=!0)}n&&z(t)}function k(e,t){try{if(typeof window>"u"||!Reflect.get(window,"__WEBMCP_CART_DEBUG__"))return;console.warn(`[webmcp:cart-guard] ${e}`,t)}catch{}}async function Eo(e,t){let n=e.flatMap(o=>{let i=wo(T(o.merchandiseId));return i?[{add:o,remembered:i}]:[]});if(k("requested",{requested:e.map(o=>o.merchandiseId),remembered:[...K().keys()],suspected:n.map(({add:o})=>o.merchandiseId)}),n.length===0)return[];let r=await Oo(t);return k("cart-lookup",{conclusive:r!==void 0,merchandiseInCart:r?[...r.keys()]:null}),r?n.flatMap(({add:o,remembered:i})=>{let a=r.get(T(o.merchandiseId));return a?(k("duplicate",{merchandiseId:o.merchandiseId,cartLineId:a.cartLineId}),[{add:o,remembered:i,cartLineId:a.cartLineId,cartQuantity:a.quantity}]):(k("released",{merchandiseId:o.merchandiseId,reason:"positively absent from a conclusive cart lookup"}),Ao(T(o.merchandiseId)),[])}):n.map(({add:o,remembered:i})=>({add:o,remembered:i,cartLineId:void 0,cartQuantity:i.quantity}))}async function Oo(e){try{let t=await $(e.signal);if(!t.id)return;let n=await Q(t.id,e.routes,e.signal);if(!n)return;let r=new Map,o=0;for(let i of n.line_items){let a=T(i.item.id);if(!a){o+=1;continue}let s=r.get(a);r.set(a,s?{cartLineId:void 0,quantity:s.quantity+i.quantity}:{cartLineId:i.id,quantity:i.quantity})}return o>0||r.size===0&&D(t)>0?void 0:r}catch{return}}function Mo(e){let n=e.some(({remembered:r})=>!r.confirmed)?"These items are ALREADY in the cart. The earlier add_to_cart call was cancelled, but the cart update had already been applied before the cancellation, so it was never reported back. I did not add them again (that would duplicate them).":"An identical add was just applied \u2014 the cart already includes these items, so I did not add them again (this prevents accidental duplicates).";return m(n,{updated:!1,deduped:!0},Kt(e)||null,`Call get_cart if you need the authoritative post-update cart contents. ${zt(e)} Otherwise do NOT repeat this call \u2014 the previous update already succeeded.`)}function xo(e){return e.length===0?"":`Skipped ${e.length} line item${e.length===1?"":"s"} already added to this cart, to avoid duplicating ${e.length===1?"it":"them"}: ${Kt(e)} ${zt(e)}`}function Kt(e){return e.map(({add:t,cartLineId:n,cartQuantity:r})=>{let o=t.productTitle?`${t.productTitle}${t.variantTitle?` (${t.variantTitle})`:""}`:t.merchandiseId,i=n?`, cart line id ${n}`:"";return`- ${o}: already in the cart with quantity ${r}${i}`}).join(` `)}function zt(e){return e.every(({cartLineId:n})=>n)?"If the shopper truly wants MORE of the same item, call update_cart_lines with the cart line id above and the ABSOLUTE total quantity they want (not the number to add).":"If the shopper truly wants MORE of the same item, call get_cart and set that line's ABSOLUTE total quantity with update_cart_lines."}var Jt=async(e,t)=>{try{let n=B(),r=await $(t.signal,n),o=D(r);if(o===0)return V("Cart is already empty.",{cleared:!0,previous_item_count:0});let i=ht(r).filter(u=>u.id).map(u=>({id:u.id,quantity:0}));ne(t.signal);let a=await n.updateCart({lines:i});re(a),Me();let s=oe(a),c=s.length?` Warnings: ${s.join("; ")}.`:"";return V(`Cart cleared. Removed ${o} item${o!==1?"s":""}.${c}`,{cleared:!0,previous_item_count:o,...s.length&&{warnings:s}},mt)}catch(n){return y(n,t.signal,"Failed to clear cart","Try update_cart_lines with each line_items[].id and quantity 0 to remove items individually.")}};var Xt=async(e,t)=>{try{let n=await $(t.signal),r=D(n);if(r===0)return f("Cart is empty. Add items before checking out.","Use search_catalog or add_to_cart to add products first.");let o=h(n.cost?.totalAmount),i=t.routes.checkout(),a=!M(i);a&&x(t,i);let s=o?` totaling ${v(o)}`:"",c=a?`Taken you to checkout with ${r} item${r!==1?"s":""}${s}.`:`Already on the checkout page with ${r} item${r!==1?"s":""}${s}.`;return O({summary:c,navigated:a,destination:"checkout"},{navigating_to:i,item_count:r,total_price:o})}catch(n){return y(n,t.signal,"Failed to initiate checkout","Call get_cart to verify cart contents, then retry.")}};var en=async(e,t)=>{try{let n=await $(t.signal);if((n.totalQuantity??0)===0||!n.id)return Io(n);let o=await Q(n.id,t.routes,t.signal);return Zt(o||No(n,t.routes))}catch(n){return y(n,t.signal,"Failed to fetch cart","Try again - this is usually a transient error.")}},Io=e=>{let t={id:e.id??"",item_count:0,total_price:h(e.cost?.totalAmount),currency:e.cost?.totalAmount?.currencyCode??"",line_items:[]};return m("Cart is empty.",t,null,"Use search_catalog or browse_store to help the user find products to add. Then call add_to_cart with cart.line_items.")},Zt=e=>m(Lo(e),e,$o(e.line_items),"To modify quantities, call update_cart_lines with the line_items[].id from this response and the new quantity. To remove an item, call update_cart_lines with quantity 0. To proceed, use proceed_to_checkout."),Lo=e=>{let t=e.line_items.slice(0,3).map(tn).join(", "),n=e.line_items.length>3?` and ${e.line_items.length-3} more`:"",r=e.item_count===1?"":"s",o=v(e.total_price)||"unknown total";return`Cart has ${e.item_count} item${r} totaling ${o}: ${t}${n}.`},$o=e=>`Cart line items: `+e.map(Do).join(` `),Do=e=>{let t=v(e.line_price)||"price unavailable";return`- ${e.id}: "${tn(e)}" - ${t}`},tn=e=>{let t=e.item.title||e.item.handle||e.item.id||"item",n=e.item.variant_title,r=n&&n!=="Default Title"?` (${n})`:"";return`${t}${r} x${e.quantity}`};function No(e,t){return{id:e.id??"",item_count:e.totalQuantity??0,total_price:h(e.cost?.totalAmount),currency:e.cost?.totalAmount?.currencyCode??"",line_items:(e.lines?.nodes??[]).map(n=>({id:n.id??"",quantity:n.quantity??0,line_price:h(n.cost?.totalAmount),item:{id:"",title:"",variant_title:"",handle:"",url:"",image:"",unit_price:null}}))}}var nn=async(e,t)=>{let n=e.catalog,r=Re(n?.id)||Wo();if(!r)return f("Product catalog.id is required.","Call search_catalog or browse_store to find a product id or handle first.");try{return await Uo(r,n,t)}catch(o){return y(o,t.signal,"Failed to load product details","Try again with a product id or handle from search_catalog or browse_store.")}};async function Uo(e,t,n){let r=t?.selected_options,o=r?.length?[...r]:void 0,i=await H(e,{selected_options:o,routes:n.routes,signal:n.signal});return i?t?.navigate===!0?qo(i,n):Fo(i,!!o?.length):ko(e)}function ko(e){return f(`Product "${e}" was not found.`,"Call search_catalog or browse_store to find an available product.")}function qo(e,t){let n=e.url,r=!M(n);return r&&x(t,n),O({summary:r?`Showing ${e.title}.`:`Already showing ${e.title}.`,navigated:r,destination:e.title},e)}function Fo(e,t){return m(`${e.title} has ${e.variant_count} variant${e.variant_count!==1?"s":""}.`,e,Vo(e),Bo(e,t))}function Wo(){return typeof window>"u"?"":L(window.location.href)}function Vo(e){if(!e.variants.length)return null;let t=e.variants.filter(r=>r.availability.available);return`Variants: `+(t.length?t:e.variants.slice(0,10)).map(r=>{let o=r.options.map(s=>`${s.name}: ${s.value}`).join(", "),i=v(r.price)||"price unavailable",a=r.availability.available?"available":"unavailable";return`- ${r.title} (id: ${r.id}) - ${o||"no options"} - ${i} - ${a}`}).join(` `)}function Bo(e,t){let n=e.variants.filter(o=>o.availability.available),r="TO VIEW (show/open/go to): call show_variant with catalog.selected_options set to whatever options the user specified (even partial like just Color) \u2014 do NOT ask for missing options.";if(n.length&&t)return`${r} TO ADD TO CART: use the matching variants[].id from this result with add_to_cart line_items[].item.id.`;if(n.length){let o=e.available_options_truncated?" (available_options is truncated \u2014 narrow with catalog.selected_options if needed).":"";return`${r}${o} TO ADD TO CART: if the user did not request specific options, use variants[0].id or the product handle with add_to_cart. If they requested specific options, pick one complete available_options entry (or call get_product again with catalog.selected_options) to get the exact variants[].id.`}return e.available_options_count>0?`${r} TO ADD TO CART: you need a full option combination \u2014 pick one complete available_options entry, or ask the user for missing options, then call get_product again with catalog.selected_options set to that full combination to get the exact variants[].id.`:e.available_options_truncated?"Available option combinations were truncated. Call get_product again with catalog.selected_options for any options the user already specified to narrow the result before choosing a variant.":"No available option combinations matched. Ask the user to choose different product options or search for another product."}var jo="/.well-known/ucp",rn=async(e,t)=>{try{let n=await fetch(jo,{headers:{accept:"application/json"},signal:t.signal});if(!n.ok)throw new Error(`UCP profile request failed (${n.status})`);let r=await n.json(),o=Ho(r);if(!o)throw new Error("UCP profile response did not include a ucp object.");return m(Qo(o),{ucp:o},Go(o),"Use the UCP service endpoints in this profile to continue the purchase over UCP. Call get_cart for the current cart id.")}catch(n){return y(n,t.signal,"Failed to fetch UCP profile","Try again - this is usually a transient error.")}};function Ho(e){return!ce(e)||!ce(e.ucp)?null:e.ucp}function Qo(e){let t=typeof e.version=="string"?` (version ${e.version})`:"",n=Object.keys(xe(e.services)),r=Object.keys(xe(e.capabilities)),o=n.length?n.join(", "):"none",i=r.length?r.join(", "):"none";return`Fetched this store's UCP profile${t}. Services: ${o}. Capabilities: ${i}.`}function Go(e){let t=Object.entries(xe(e.services)).flatMap(([n,r])=>Yo(r).filter(o=>o.endpoint).map(o=>`- ${n} (${o.transport??"unknown"}): ${o.endpoint}`));return t.length?`UCP service endpoints: ${t.join(` `)}`:null}function Yo(e){return Array.isArray(e)?e.filter(ce).map(t=>({transport:typeof t.transport=="string"?t.transport:void 0,endpoint:typeof t.endpoint=="string"?t.endpoint:void 0})):[]}function xe(e){return ce(e)?e:{}}function ce(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}var on=(e,t)=>{let n=t.routes.accountOrders(),r=!M(n);return r&&x(t,n,10),O({summary:r?"Taken you to your order history. You may need to log in if not already authenticated.":"Already on your order history page. You may need to log in if not already authenticated.",navigated:r,destination:"order history"},{navigating_to:n})};var an=async(e,t)=>{let n=e.catalog?.query?.trim();if(!n)return f("Search query is required.","Call search_catalog with catalog.query.");try{let r=ti(Number(e.catalog?.pagination?.limit)||5,1,10),o=await At(n,r,t.signal);return zo(n,Ko(o.predictiveSearch,t.routes),t.routes)}catch(r){return y(r,t.signal,"Search failed","Try again with a simpler catalog.query, or use browse_store to inspect collections.")}};function Ko(e,t){return{products:e.products.map(n=>G(n,t)),collections:e.collections.map(n=>ae(n,t)),articles:e.articles.map(Ae),pages:e.pages.map(Pe)}}function zo(e,t,n){let r=t.products.length+t.collections.length+t.articles.length+t.pages.length,o={...t,search_url:n.search(e)};return r===0?m(`No search results found for "${e}".`,o,null,"Try browse_store to inspect collections or search_catalog with a broader catalog.query."):m(`Found ${Jo(t).join(", ")} for "${e}".`,o,Zo(t),Xo(t))}function Jo(e){return[le("product",e.products.length),le("collection",e.collections.length),le("article",e.articles.length),le("page",e.pages.length)].filter(Boolean)}function le(e,t){return t?`${t} ${e}${t===1?"":"s"}`:""}function Xo(e){return e.products.length?"If the user wants the selected or first available variant, call add_to_cart with cart.line_items using the product handle or query. If the user requested a specific color, size, material, or other option, call get_product with catalog.id and any known catalog.selected_options to filter available_options, then use the matching variants[].id with add_to_cart.":e.collections.length||e.articles.length||e.pages.length?"No products matched, but other catalog results were found. Share the relevant collection, article, or page URL with the user, or call browse_store for product collections.":"Use browse_store to inspect products by collection."}function Zo(e){let t=[ei(e.products),Ie("Collections",e.collections),Ie("Articles",e.articles),Ie("Pages",e.pages)].filter(Boolean);return t.length?t.join(` `):null}function ei(e){return e.length?`Products: `+e.map(t=>`- ${t.title} (id: ${t.id}, handle: ${t.handle}) - ${v(t.price_range)||"price unavailable"}`).join(` `):null}function Ie(e,t){return t.length?`${e}: `+t.map(n=>`- ${n.title}${n.handle?` (${n.handle})`:""}: ${n.url}`).join(` `):null}function ti(e,t,n){return Math.min(n,Math.max(t,e))}var ni=5,ri=300,oi=5,ii=[{type:"refund",patterns:[/\brefund/i,/\breturn/i,/\bmoney\s+back/i,/\bexchange/i,/\breimburse/i]},{type:"shipping",patterns:[/\bship/i,/\bdeliver/i,/\bdispatch/i,/\bfulfil/i,/\bfulfill/i,/\bpostage/i,/\btracking/i,/\bcourier/i]},{type:"privacy",patterns:[/\bprivacy/i,/\bdata/i,/\bcookie/i,/\bgdpr/i,/\bpersonal\s+information/i,/\bpersonal\s+data/i]},{type:"terms_of_service",patterns:[/\bterms\s+of\s+service/i,/\bterms\s+of\s+use/i,/\btos/i,/\bterms/i]},{type:"terms_of_sale",patterns:[/\bterms\s+of\s+sale/i,/\bpurchase\s+terms/i]},{type:"subscription",patterns:[/\bsubscription/i,/\bsubscribe/i,/\brecurring/i]},{type:"legal_notice",patterns:[/\blegal\s+notice/i,/\bimprint/i,/\bcompany\s+info/i]},{type:"contact",patterns:[/\bphone/i,/\bcall/i,/\bcontact/i,/\bemail/i,/\baddress/i,/\bhours/i,/\bopening/i,/\blocation/i,/\breach/i,/\bsupport/i]}],cn=async(e,t)=>{let n=e.query?.trim();if(!n)return f("A search query is required.","Call search_shop_policies_and_faqs with a query, e.g. 'return policy' or 'shipping'.");try{let r=ai(e.policy_types,n),o=await Rt(n,ni,r,t.signal);return ci(n,o.policies,o.articles,o.pages)}catch(r){return y(r,t.signal,"Policy and FAQ search failed","Rephrase the query (e.g. 'return policy', 'shipping', 'contact') and try again.")}};function ai(e,t){let n=new Set(Ce),o=(Array.isArray(e)?e:[]).filter(i=>typeof i=="string"&&n.has(i));return o.length?o:si(t)}function si(e){let t=ii.flatMap(({type:n,patterns:r})=>r.some(o=>o.test(e))?[n]:[]);return t.length?t:/\bpolic(?:y|ies)\b/i.test(e)?[...Ce]:[]}function ci(e,t,n,r){let o={policies:t,articles:n,pages:r};return t.length+n.length+r.length===0?m(`No policies or FAQ content found for "${e}".`,o,null,"The store may not have published this content; a rephrased query, or the store's contact page, may help."):m(li(e,t,n,r),o,ui(t,n,r),pi(t,n,r))}function li(e,t,n,r){return`Found ${[t.length?`${t.length} polic${t.length===1?"y":"ies"}`:null,r.length?`${r.length} page${r.length===1?"":"s"}`:null,n.length?`${n.length} article${n.length===1?"":"s"}`:null].filter(Boolean).join(", ")||"no results"} for "${e}".`}function ui(e,t,n){let r=[e.length?`Policies: `+e.map(di).join(` `):null,n.length?`Pages: `+n.map(o=>`- ${o.title}: ${o.url}`).join(` `):null,t.length?`Articles: `+t.map(o=>`- ${o.title}: ${o.url}`).join(` `):null].filter(Boolean);return r.length?r.join(` `):null}function di(e){let t=ln(e.body);return t?t.kind==="empty"?`- ${e.title}: ${e.url} (the policy body is empty)`:`- ${e.title}: ${e.url} (short policy body that links to: ${t.links.join(", ")})`:`- ${e.title}: ${e.url}`}function pi(e,t,n){if(e.length){let r=e.flatMap(i=>{let a=ln(i.body);return a?a.kind==="empty"?[`${i.title} has an empty policy body.`]:[`${i.title} has a short policy body that links to other pages (listed above); the full details may be on those pages.`]:[]});if(r.length===0)return"The full policy text is in the structured content (policies[].body).";let o=n.length||t.length?" Matching store pages and articles are also included in the structured content.":"";return`The policy text is in the structured content (policies[].body). ${r.join(" ")}${o}`}return n.length||t.length?"The store has no matching policy. The structured content includes the matching pages' bodies and article excerpts, with their URLs.":"No matching policy or FAQ content was found; the store may not have published it, or a rephrased query may match."}function ln(e){let t=[...new Set([...e.matchAll(/]*\bhref\s*=\s*["']([^"']+)["']/gi)].map(r=>sn(r[1]??"").trim()).filter(r=>r&&!r.startsWith("#")&&!/^(?:javascript|mailto|tel):/i.test(r)))],n=sn(e.replace(/<[^>]*>/g," ")).replace(/https?:\/\/\S+/g," ").replace(/\s+/g," ").trim();return!n&&t.length===0?{kind:"empty"}:t.length>0&&n.length")}var Le="gid://shopify/ProductVariant/",un=async(e,t)=>{let n=fi(e);if("error"in n)return n.error;let{handle:r,rawVariantId:o,selectedOptions:i}=n,a=await yi(r,o,i,t);if("error"in a)return a.error;let{variantId:s,resolvedOptions:c}=a,u=a.productHandle||r,l=c?[u,r]:[u],d=Pi(t.routes.product(u),s,l),b=!M(d);return b&&x(t,d),mi({handle:u,requestedHandle:r,variantId:s,url:d,navigated:b,resolvedOptions:c})};function fi(e){let t=e.catalog.variant_id,n=Si(e.catalog.selected_options);if(t==null&&!n.length)return{error:f("Provide either catalog.variant_id or catalog.selected_options.","For a specific variant, pass variant_id from get_product variants[].id. For a partial match like a color only, pass selected_options.")};let r=Ti(e.catalog.handle);return r?wi(r)?{handle:r,rawVariantId:t??void 0,selectedOptions:n}:{error:f(`Product handle "${r}" is not valid.`,"Use a product handle from search_catalog, browse_store, or get_product.")}:{error:f("Product handle is required.","Pass catalog.handle, or call show_variant from a product page.")}}async function yi(e,t,n,r){let o=t!=null?pn(t):"";if(o){let i=await gi(o,e,r);return"error"in i?i:{variantId:o,resolvedOptions:void 0,productHandle:i.sameProduct?void 0:i.handle}}if(n.length){let i=await hi(e,n,r);return"error"in i?i:{variantId:i.variantId,resolvedOptions:i.options,productHandle:i.productHandle}}return{error:f("Product variant_id could not be resolved.","Call get_product to find an available variants[].id, then retry show_variant.")}}async function gi(e,t,n){try{let r=await xt(`${Le}${e}`,t,n.signal);return r||{error:f(`Product variant ${e} was not found on this store.`,"Call get_product to find an available variants[].id, then retry show_variant.")}}catch(r){return{error:y(r,n.signal,"Failed to look up the product variant.","Call get_product to find an available variants[].id, then retry show_variant.")}}}function mi(e){let{handle:t,requestedHandle:n,variantId:r,url:o,navigated:i,resolvedOptions:a}=e,s=a?.length?` (${a.map(u=>`${u.name}: ${u.value}`).join(", ")})`:"",c=t===n?"":a?` This variant is sold as a separate product (${t}), linked to ${n} as an option, so its own product page is shown.`:` This variant belongs to a different product (${t}), so that product's page is shown.`;return O({summary:i?`Showing the selected variant${s}.${c}`:`Already showing the selected variant${s}.${c}`,navigated:i,destination:t,keyFields:`Variant id: ${r}`},{handle:t,variant_id:r,url:o,navigated:i,selected_options:a})}async function hi(e,t,n){try{let r=await H(e,{selected_options:t,routes:n.routes,signal:n.signal});if(!r)return{error:vi(e)};let o=bi(r);if(o)return o;let i=await _i(r,e,n);return i||{error:f("No available variant matched the selected options.","Call get_product with the same selected_options to see available_options, then pick one and retry.")}}catch(r){return{error:y(r,n.signal,"Failed to resolve variant from selected_options.","Call get_product first to inspect available variants, then retry show_variant with a variant_id.")}}}function bi(e){let t=e.variants.filter(n=>n.availability.available);return dn(t[0]??e.variants[0])}function dn(e){return e?.id?{variantId:pn(e.id),options:e.options,...e.product_handle?{productHandle:e.product_handle}:{}}:null}async function _i(e,t,n){let r=e.available_options?.[0];if(!r?.length)return null;let o=await H(t,{selected_options:r,routes:n.routes,signal:n.signal});return dn(o?.variants?.find(i=>i.availability.available)??o?.variants?.[0])}function vi(e){return f(`Product "${e}" was not found.`,"Call search_catalog or browse_store to find an available product.")}function Si(e){return e?.length?e.map(t=>({name:String(t?.name??"").trim(),value:String(t?.value??"").trim()})).filter(t=>t.name&&t.value):[]}function pn(e){let t=String(e).trim();if(!t)return"";let n=t.startsWith(Le)?t.slice(Le.length):t;return/^\d+$/.test(n)?n:""}function Ti(e){return e?.trim()?Ci(e):fn()}function Ci(e){let t=e?.trim();return t?L(t)||Ai(t):""}function fn(){return typeof window>"u"?"":L(window.location.href)}function wi(e){return!!e&&!/[/?#\\]/.test(e)&&e!=="."&&e!==".."}function Ai(e){try{return decodeURIComponent(e)}catch{return""}}function Pi(e,t,n){let r=new URL(e,Ei());if(r.searchParams.set("variant",t),n.includes(fn())){let o=Ri().searchParams.get("selling_plan");o&&r.searchParams.set("selling_plan",o)}return r.pathname+r.search}function Ri(){return typeof window>"u"?new URL("https://shopify.local/"):new URL(window.location.href)}function Ei(){return typeof window>"u"?"https://shopify.local":window.location.origin}var yn={add_to_cart:Wt,browse_store:qt,cancel_cart:Jt,proceed_to_checkout:Xt,get_cart:en,get_product:nn,get_ucp_profile:rn,manage_orders:on,search_catalog:an,search_shop_policies_and_faqs:cn,show_variant:un,update_cart_lines:Vt};var gn=Symbol.for("shopify.webmcp.registered"),Oi=Object.values(ct).map(e=>({...e,execute:yn[e.name]}));function mn(){let e=xi();if(!e||Ii())return!1;let t=[];for(let n of Oi){let r=$i(n);t.push(e.registerTool(r))}return Li(),Promise.allSettled(t),!0}function Mi(e){let t=window.Shopify?.routes?.navigate;if(typeof t=="function")return t(e);window.location.href=e}function xi(){return typeof document<"u"&&"modelContext"in document?document.modelContext??null:typeof navigator<"u"&&"modelContext"in navigator?navigator.modelContext??null:null}function Ii(){return typeof window>"u"?!1:Reflect.get(window,gn)===!0}function Li(){typeof window>"u"||Reflect.set(window,gn,!0)}function $i(e){let{execute:t,...n}=e;return{...n,execute:Ze(e.name,(r,o)=>t(r,{routes:et,navigate:Mi,signal:X(o)}))}}(function(){typeof window>"u"||mn()})();})();