THE NUTCRACKER COLLECTION

The John Muir
Country Store

£0.00

Select from our Range of  Products

  • TRIPLE PATÉ SET
  • < link rel="stylesheet" media="all" id="ecom-vendors-css_ecomposer_base" href="https://cdn.ecomposer.app/vendors/css/ecom-base.css?v=1.6" />
  • Shop Shop All Cheese
Flavoured Cheese
Dunbar Hamper

Opens in a new window. Dunbar Hamper window.hextom_fsb_meta = { p1: [ ], p2: { }, p3: [ ], p4:null, p5:[], p6:null, }; window.hextom_fsb_config = {"shop_active":"yes","record":false,"bars":[],"theme":{"theme_id":"156626583859","is_xhr":false}};

window.EcomSend.appStatus.main_script_status = 'failed'; }; if (null === document.getElementById(ele.id)) { document.head.appendChild(ele); isEcomSendInitialized = true; return true; } return false; }; function EcomsendOnMobxLoaded() { // Load main script in EcomSend namespace context setTimeout(() => { // Try to use namespace context if (window.withEcomSendContext) { window.withEcomSendContext(() => { createEcomSendMainJSEle(); }); } else { // Fallback to direct loading createEcomSendMainJSEle(); } }, 100); }; let checkCount = 0; const maxChecks = 20; function EcomsendBackupCheck() { if (isEcomSendInitialized) return; checkCount++; // First check dependencies in namespace if (window.EcomSend && window.EcomSend.React && window.EcomSend.ReactDOM && window.EcomSend.mobx && window.EcomSend.React.useContext && wi ndow.EcomSend.React.createElement) { // Use namespace context if (window.withEcomSendContext) { window.withEcomSendContext(() => { if (createEcomSendMainJSEle()) { return; } }); } } // Fallback to checking global dependencies else if (window.React && window.ReactDOM && window.mobx && window.React.useContext && window.React.createElement && window.ReactDOM.createRoot) { if (createEcomSendMainJSEle()) { return; } } if (checkCount < £14.50 maxChecks) { setTimeout(EcomsendBackupCheck, 1000); } else { createEcomSendMainJSEle(); } } setTimeout(EcomsendBackupCheck, 2000);
//EcomSend APPS COMMON JS CODE window.EcomSendApps = window.EcomSendApps || {} window.EcomSendApps.design_mode = false window.EcomSendApps.common = window.EcomSendApps.common || {} window.EcomSendApps.common.shop = { permanent_domain: 'john-muir-country.myshopify.com', currency: "GBP", money_format: "£{{amount}}", id: 80637690163, } window.EcomSendApps.common.customer = { id: null, tags: null, email: null, accepts_marketing: null, first_name: null, } window.EcomSendApps.common.template = 'collection' Add to cart window.shopLocale = 'en'
/** * EcomSend Namespace Encapsulation * This script encapsulates React and MobX dependencies within the EcomSend namespace * to prevent conflicts with other applications' dependencies. */ // Save original global variables (if they exist) window._EcomSendNamespace = { _originalReact: window.React, _originalReactDOM: window.ReactDOM, _originalMobx: window.mobx, } // Create EcomSend namespace window.EcomSend = window.EcomSend || {} // Initialize app status tracker window.EcomSend.appStatus = { react_status: 'pending', reactdom_status: 'pending', mobx_status: 'pending', main_script_status: 'pending', initialization_status: 'pending', // Helper method to get overall status getOverallStatus: function() { const statuses = [ this.react_status, this.reactdom_status, this.mobx_status, this.main_script_status ]; if (statuses.includes('failed')) { return 'failed'; } if (statuses.includes('loading')) { return 'loading'; } if (statuses.every(s => s === 'loaded') && this.main_script_status === 'loaded') { return 'ready'; } if (statuses.includes('loaded')) { return 'loading'; } return 'pending'; } } // Define initialization method window.initializeEcomSendNamespace = function(React, ReactDOM, mobx) { // Save dependencies to Ecom
Send namespace window.EcomSend.React = React window.EcomSend.ReactDOM = ReactDOM window.EcomSend.mobx = mobx // Trigger ready event const event = new CustomEvent("EcomSendNamespaceReady") window.dispatchEvent(event) return { React: React, ReactDOM: ReactDOM, mobx: mobx, } } // Provide context switching method window.withEcomSendContext = function(callback) { // Save current global variables const originalReact = window.React const originalReactDOM = window.ReactDOM const originalMobx = window.mobx // Set EcomSend's version to global window.React = window.EcomSend.React window.ReactDOM = window.EcomSend.ReactDOM window.mobx = window.EcomSend.mobx try { // Execute callback in EcomSend context return callback() } finally { // Restore original global variables window.React = originalReact window.ReactDOM = originalReactDOM window.mobx = originalMobx } } // A dd method to restore original global variables window.restoreOriginalGlobals = function() { window.React = window._EcomSendNamespace._originalReact window.ReactDOM = window._EcomSendNamespace._originalReactDOM window.mobx = window._EcomSendNamespace._originalMobx }
function loadReactDependencies() { return new Promise((resolve, reject) => { // Check if React is already loaded by other apps const existingReact = window.React; const existingReactDOM = window.ReactDOM; // If React already exists, use it and initialize namespace if (existingReact && existingReactDOM) { window.EcomSend = window.EcomSend || {}; window.EcomSend.React = existingReact; window.EcomSend.ReactDOM = existingReactDOM; window.EcomSend.appStatus.react_status = 'loaded'; window.EcomSend.appStatus.reactdom_status = 'loaded'; resolve(); return; } window.EcomSend.appStatus.react_status = 'loading'; window.EcomSend.appStatus.reactdom_status = 'loading'; let isResolved = false; const reactScript = document.createElement('script'); reactScript.async = false; reactScript.src = 'https://cdn.shopify.com/extensions/019ab39b-6f76-721d-9144-1a729619dbae/ecomsend-99/assets/react_react-dom.min.js'; reactScript.onload = () => { if (isResolved) return; isResolved = true; window.EcomSend.appStatus.react_status = 'loaded'; window.EcomSend.appStatus.reactdom_status = 'loaded'; // Save the newly loaded React to namespace window.EcomSend = window.EcomSend || {}; window.EcomSend.React = window.React; window.EcomSend.ReactDOM = window.ReactDOM; // If React existed before (might be added by other scripts during loading) // Save our loaded version, then restore the previous version if (existingReact && window.React !== existingReact) { window._EcomSendNamespace._loadedReact = window.React; window._EcomSendNamespace._loadedReactDOM = window.ReactDOM; // Use our loaded version as EcomSend's version window.EcomSend.React = window._EcomSendNamespace._loadedReact; window.EcomSend.ReactDOM = window._EcomSendNamespace._loadedReactDOM; // Restore global variables window.React = existingReact; window.ReactDOM = existingReactDOM; } resolve(); }; reactScript.onerror = () => { if (isResolved) return; isResolved = true; window.EcomSend.appStatus.react_status = 'failed'; window.EcomSend.appStatus.reactdom_status = 'failed'; reject(new Error('Failed to load React')); }; document.head.appendChild(reactScript); // Fallback check: if onload doesn't trigger but React is available setTimeout(() => { // If already resolved in 500ms, no need to start interval if
(isResolved) return; let checkCount = 0; const maxChecks = 10; // Check for 10 seconds const checkInterval = setInterval(() => { checkCount++; if (isResolved) { // Already resolved, stop checking clearInterval(checkInterval); return; } if (window.React && window.ReactDOM) { // React exists but onload didn't trigger isResolved = true; clearInterval(checkInterval); window.EcomSend = window.EcomSend || {}; window.EcomSend.React = window.React; window.EcomSend.ReactDOM = window.ReactDOM; window.EcomSend.appStatus.react_status = 'loaded'; window.EcomSend.appStatus.reactdom_status = 'loaded'; resolve(); return; } if (checkCount >= maxChecks) { // Stop checking after max attempts clearInterval( checkInterval); return; } }, 1000); }, 500); }); } function loadMobxDependencies() { return new Promise((resolve, reject) => { // Check if MobX is already loaded by other apps const existingMobx = window.mobx; window.EcomSend.appStatus.mobx_status = 'loading'; let isResolved = false; const mobxScript = document.createElement('script'); mobxScript.async = false; mobxScript.src = 'https://cdn.shopify.com/extensions/019ab39b-6f76-721d-9144-1a729619dbae/ecomsend-99/assets/mobx_react-custom-roulette.min.js'; mobxScript.onload = () => { if (isResolved) return; isResolved = true; window.EcomSend.appStatus.mobx_status = 'loaded'; // Save the newly loaded MobX (if exists) const loadedMobx = window.mobx; // Decide which MobX to use const mobxToUse = loadedMobx || existingMobx; // If MobX existed before, r
estore the original global variable (to avoid affecting other apps) if (existingMobx && loadedMobx && loadedMobx !== existingMobx) { window._EcomSendNamespace._loadedMobx = loadedMobx; window.mobx = existingMobx; } // Complete namespace initialization window.EcomSend = window.EcomSend || {}; window.EcomSend.mobx = mobxToUse; // Initialize namespace window.initializeEcomSendNamespace( window.EcomSend.React, window.EcomSend.ReactDOM, window.EcomSend.mobx ); resolve(); }; mobxScript.onerror = () => { if (isResolved) return; isResolved = true; window.EcomSend.appStatus.mobx_status = 'failed'; reject(new Error('Failed to load MobX')); }; document.head.appendChild(mobxScript); // Fallback check: if onload doesn't trigger but mobx is available setTimeout(() => { / / If already resolved in 500ms, no need to start interval if (isResolved) return; let checkCount = 0; const maxChecks = 10; // Check for 10 seconds const checkInterval = setInterval(() => { checkCount++; if (isResolved) { // Already resolved, stop checking clearInterval(checkInterval); return; } if (window.mobx) { // MobX exists but onload didn't trigger isResolved = true; clearInterval(checkInterval); const mobxToUse = window.mobx; window.EcomSend = window.EcomSend || {}; window.EcomSend.mobx = mobxToUse; window.EcomSend.appStatus.mobx_status = 'loaded'; // Initialize namespace window.initializeEcomSendNamespace( window.EcomSend.React, window.EcomSend.ReactDOM, window.EcomSen
d.mobx ); resolve(); return; } if (checkCount >= maxChecks) { // Stop checking after max attempts clearInterval(checkInterval); return; } }, 1000); }, 500); }); } async function initializeEcomSend() { try { window.EcomSend.appStatus.initialization_status = 'initializing'; await loadReactDependencies(); await loadMobxDependencies(); window.EcomSend.appStatus.initialization_status = 'ready'; setTimeout(() => { // Execute app initialization using EcomSend namespace window.withEcomSendContext(() => { if (window.EcomsendOnMobxLoaded) { window.EcomsendOnMobxLoaded(); } }); }, 200); } catch (error) { window.EcomSend.appStatus.initialization_status = 'failed'; setTimeout(EcomsendBackupCheck, 1000); } } if (document.readyState === 'l oading') { document.addEventListener('DOMContentLoaded', initializeEcomSend); } else { initializeEcomSend(); }