mmRequestCallbacks[1]({"Scripts":[{"Name":"IntegrationsModule","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*!\n *\tintegrations-module 0.9.7\n *\t-- Maxymiser Integrations Module provides a standardized approach to develop and deploy 3rd party integrations.\n *\t-- Built on 2017-02-02\n */\n!function(){function a(){function a(a,b){function i(b){return a=a||\"\",g(\"Integrations.register(\"+a+\"): \"+(b||\"\").toString())}var j,k;return b=e(b)?b:{},(a=(\"string\"==typeof a?a:\"\").toLowerCase().replace(/^\\s+|\\s+$/g,\"\"))?l[a]?(i(m.errors.alreadyRegistered),null):(b.name=a,j=h(b,{}),k={validate:c(j.validate)?j.validate:f,check:c(j.check)?j.check:f,interval:d(j.interval)?j.interval:50,timeout:d(j.timeout)?j.timeout:2e3,exec:c(j.exec)?j.exec:f,options:j},j=h(k,j),l[a]=j):(i(m.errors.missingRegisterName),null)}function i(a,b){b=e(b)?b:{};var c,d,f,g,i=new Deferred;if(a=(a||\"\").toLowerCase(),i.integrationName=a,!l[a])return m.reject(i,m.errors.unregisteredIntegration);if(c=h(l[a],{}),c=h(b,c),(f=c.validate(c))!==!0)return m.reject(i,f);if(d=c.campaign,(g=m.validateCampaignRequired(c,i))!==!0)return m.reject(i,g);if(c.isProduction=m.isProduction(),c.attributeMapRequired){var j=m.isValidAttributeMap(c.attributeMap);if(j!==!0)return m.reject(i,j)}return\"pending\"!==i.state()?i.promise():(\"never\"!==c.timeout&&m.setFailTimeout(c,i),m.check(c).then(function(a){return m.exec(c)}).then(function(a){return c.result=a,m.resolve(i,c)}).fail(function(a){return m.reject(i,a)}),i.promise())}function j(a,b){a=(a||\"\").toLowerCase();var c=l[a];return!!c&&(b=e(b)?b:{},l[a]=h(b,c),this)}function k(a){if(!a)return l;var b=(a||\"\").toLowerCase();return l[b]}var l={},m={errors:{missingRegisterName:\"Invalid integration reigstration. Name argument is required.\",missingRegisterExec:\"Missing `exec` for integration registration\",alreadyRegistered:\"Integration has already been registered\",missingRunName:\"Missing `name` for `integration.run`\",unregisteredIntegration:\"Unknown integration name\",noCampaignExperience:\"Integration was run before the campaign has generated\",noRedirectCampaign:\"Redirect Integration is not in a valid campaign scope\",noRedirectCampaignData:\"Redirect Integration is not on a generation page\",campaignRequired:\"Integration must be deployed within a campaign script\",failedToSaveRedirectData:\"Failed to save redirect data\"},HALFHOUR:1/48,isProduction:function(){function a(a){for(var c,d={},e=\"\",f=0;c=b(a+f++);)e+=c;e=decodeURIComponent(e);try{d=JSON.parse(e)}catch(g){}return d}function b(a){var b=new RegExp(\"(?:^|; )\"+encodeURIComponent(a).replace(/([.$?*|{}()\\[\\]\\\\\\/+^])/g,\"\\\\$1\")+\"=([^;]+)\"),c=(document.cookie.match(b)||[\"\",\"\"])[1];return c}var c=mmsystem.getConfig().storageType;if(\"cookie-key-value\"===c||\"cookie-key-value-secure\"===c)return!/mmapi.p.cfgid/i.test(document.cookie)&&!/mmapi.p.un/i.test(document.cookie);for(var d=a(\"mmcore.store.p.\")||{},e=a(\"mmcore.store.s.\")||{},f=a(\"mmapi.store.p.\")||{},g=a(\"mmapi.store.s.\")||{},h=[d,e,f,g],i={\"mmparams.p\":1,\"mmparams.d\":1},j={un:1,cfgID:1,pruh:1},k=h.length;k--;){var l=h[k];for(var m in i||{})for(var n in j||{})if((l[m]||{})[n])return!1}return!0},isValidIntegrationName:function(a){return\"string\"==typeof a&&/^\\w+/.test(a)},isCampaignScope:function(a){return!!(e(a)&&a.getName&&a.getExperience)},getCampaignExperience:function(a){var b={};return m.isCampaignScope(a)&&(b=a.getExperience&&a.getExperience()||{}),!!Object.keys(b)&&m.formatCampaignExperience(b)},formatCampaignExperience:function(a){a=e(a)?a:{};var b=[];for(var c in a)b.push(c+\":\"+a[c]);return b.join(\"|\")},getData:function(a){a=(a||\"\").toLowerCase();var b=visitor.getData(\"Integrations\");return b=e(b)?b:{},a&&(b[a]=b[a]||{}),b},setRedirectData:function(a,b){if(a=(a||\"\").toLowerCase(),!m.isCampaignScope(b))return!1;var c=m.getData(a),d=b.getName();return c[a][d]=c[a][d]||{},c[a][d].redirectData=b.getExperience(),visitor.setData(\"Integrations\",c,m.HALFHOUR),!0},removeRedirectData:function(a,b){if(a=(a||\"\").toLowerCase(),!m.isCampaignScope(b))return!1;var c=m.getData(a),d=b.getName();return c[a][d]=c[a][d]||{},c[a][d].redirectData=null,visitor.setData(\"Integrations\",c,m.HALFHOUR),!0},getRedirectData:function(a,b){if(a=(a||\"\").toLowerCase(),!m.isCampaignScope(b))return!1;var c=m.getData(a),d=b.getName();if(c[a][d]=c[a][d]||{},!c[a]||!c[a][d])return c[a]=c[a]||{},c[a][d]=c[a][d]||{},c[a][d].redirectData=null,visitor.setData(\"Integrations\",c,m.HALFHOUR),!1;for(var e in c[a])if(e===d)return c[a][e].redirectData;return!1},getSessionDate:function(a,b){var c=m.getData(a),d=c[a][b.getName()]||{},e=d.sessionDate;return e},setSessionDate:function(a,b){var c=m.getData(a),d=b.getName();c[a][d]=c[a][d]||{},c[a][d].sessionDate=(new Date).getTime(),visitor.setData(\"Integrations\",c,m.HALFHOUR)},resolve:function(a,b){return a.resolve(b),a.promise()},reject:function(a,b){var c=a.integrationName||\"unknown name\";return b=b||\"unknown reason\",g(\"Integration [\"+c+\"]: \"+b.toString()),a.reject(b),a.promise()},validateCampaignRequired:function(a,b){if(!a.campaignRequired)return a.oncePerSession?\"campaign option is required when using the oncePerSession option\":!a.redirect||\"campaign option is required when using the redirect option\";var c=a.campaign,d=\"\",e=m.isCampaignScope(c);if(e!==!0)return m.errors.campaignRequired;if(a.campaignExperience=m.getCampaignExperience(c),a.campaignExperience===!1&&!a.redirect)return m.errors.noCampaignExperience(a.name);if(a.oncePerSession&&!a.redirect&&a.oncePerSession&&(d=m.getSessionDate(a.name,c),m.setSessionDate(a.name,c),(new Date).getTime()-m.HALFHOUR>d))return g(\"Integration [\"+a.name+\"]: data has already been sent this session\"),m.resolve(b,a),!0;if(a.redirect){var f=function(){var a=c.getElements();for(var b in a)return!0;return!1}();return f?c.isDefault()?!(a.oncePerSession&&(d=m.getSessionDate(a.name,c),m.setSessionDate(a.name,c),(new Date).getTime()-m.HALFHOUR>d))||(g(\"Integration [\"+a.name+\"]: data has already been sent this session\"),m.resolve(b,a),!0):m.setRedirectData(a.name,c)?(m.resolve(b,a),!0):m.errors.failedToSaveRedirectData:a.oncePerSession&&(d=m.getSessionDate(a.name,c),m.setSessionDate(a.name,c),(new Date).getTime()-m.HALFHOUR>d)?(g(\"Integration [\"+a.name+\"]: data has already been sent this session\"),m.resolve(b,a),!0):(a.campaignExperience=m.getRedirectData(a.name,c),a.campaignExperience=m.formatCampaignExperience(a.campaignExperience),m.removeRedirectData(a.name,c),!!a.campaignExperience||m.errors.noRedirectCampaignData)}return!0},setFailTimeout:function(a,b){!function(b){setTimeout(function(){setTimeout(function(){if(\"pending\"===b.state())return m.reject(b,\"Integration timed out after \"+a.timeout+\"ms\")},0)},a.timeout+1)}(b)},isValidAttributeMap:function(a){if(!a)return\"Missing required attributeMap parameter\";if(!e(a)||!Object.keys(a).length)return\"The attributeMap parameter is empty or not an object\";for(var b in a){var c=a[b];if(\"string\"!=typeof b||!/^[a-zA-Z]+/.test(b))return\"Invalid attribute name in the attributeMap\";if(!e(c))return\"attributeMap values must be stored in an object\";if(!Object.keys(c).length)return\"attributeMap attribute object is empty\";for(var d in c)if(!/^\\w+$/.test(d)&&\"default\"!==d)return\"Invalid attribute ID in attributeMap\"}return!0},check:function(a){var c=new Deferred,d=!1;return function e(){var f=a.check.call(this,a);return b(f)?void setTimeout(function(){f.done(function(){return c.resolve()}).fail(function(a){return c.reject(a)})},0):f?void setTimeout(function(){c.resolve()},0):void(d||setTimeout(e,a.interval))}(),setTimeout(function(){d=!0},a.timeout),c.promise()},exec:function(a){var c=new Deferred,d=a.exec.call(this,a);return b(d)?(setTimeout(function(){d.done(function(a){return c.resolve(a)}).fail(function(a){return c.reject(a)})},0),c.promise()):(d===!0?m.resolve(c,a.result):m.reject(c,d),c.promise())}};return{register:a,run:i,setDefaults:j,get:k}}function b(a){return e(a)&&c(a.then)}function c(a){return\"function\"==typeof a}function d(a){return\"number\"==typeof a&&a>0}function e(a){return\"object\"==typeof a&&!!a}function f(){return!0}function g(a){window.mm_error=window.mm_error||\"\",window.mm_error+=a+\"\\n\"}function h(a,b){a=e(a)?a:{},b=e(b)?b:{};var c={};for(var d in b)c[d]=b[d];for(var f in a)c[f]=a[f];return c}if(\"object\"==typeof modules&&\"function\"==typeof modules.define){var i={autoDefine:!0,singleton:!0};modules.define(\"Integrations\",i,a)}else modules={require:function(){return new a}}}();","Order":-100,"HighLevelApiVersion":"1.24"},{"Name":"IntegrationIBM","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*!\n *\tIBMAnalytics 1.2.0\n *\t-- Maxymiser IBM Analytics integration\n *\t-- Built on 2016-05-09\n */\n!function(){var a={version:\"1.2.0\",oncePerSession:!0,campaignRequired:!0,check:function(a){return window.cmCreateElementTag&&!0},timeout:7e3,exec:function(a){var b=a.campaign.getName()+(a.isProduction?\"\":\" QA\");return window.cmCreateElementTag(a.campaignExperience,b),!0}};\"object\"==typeof modules&&\"function\"==typeof modules.define&&modules.require(\"Integrations\").register(\"IBM Analytics\",a)}();","Order":-90,"HighLevelApiVersion":"1.24"},{"Name":"HelperModule","Type":"script","Attrs":{"type":"text/javascript"},"Data":"modules.define('Helper', function () {\n\tthis.whenJQuery = function () {\n\t\treturn when(function (){\n\t\t\treturn typeof window.jQuery === 'function';\n\t\t});\n\t};\n});","Order":-55,"HighLevelApiVersion":"1.24"},{"Name":"PageTypeDetect_CDAPI","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*\n sitePages - object description\n\n sitePages - this is a list of pages on whebsite (which maxymiser trying identify).\n sitePages.item - contains 3 attributes\n - rules {string|function} -> what should be on the page\n - masks {array} -> list of masks where rules should be applied\n each mask {object} specify which part of url we need to check\n key -> part of location (pathname, hostname, search)\n value {string|regexp} -> rules\n optional: strict {bool} -> when rules should be equal\n examples:\n {'pathname' : '/shop.aspx'}\n -> key said which part of location we should check (location.pathname)\n -> value said location.pathname (from key) should contains \"/shop.aspx\"\n {'pathname':'/', strict: true}\n -> additional param strict need if we value should be equal.\n {'pathname': /(.*)/ig}\n -> you can put Reg Exp to check, in this case will be used match method.\n - domains -> list of domains where this rules and masks should be applied\n */\n\n/*\n NOTE - For desktop only\n\n important things for Payment and Delivery trigger\n\n for FIRST time it will be triggered as mmcore.success.Payment (and mmcore.success.Delivery) and send request\n all OTHER fimes it will be triggered as mmcore.end.Payment (and mmcore.end.Delivery) and will not send request\n\n SO subscribe on mmcore.end.Payment only after mmcore.success.Payment\n\n BECAUSE\n\n mmcore.end.Payment will be triggered on FAIL (when it's not PAYMENT PAGE)\n */\n\nvar desktopSitePages = {\n    'HomePage' : {\n        'rules' : 'body.template-home-template',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'BrandPages' : {\n        'rules' : 'body.page-custom.page-brands',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'Search' : {\n        'rules' : 'body.page-search, body.page-no-results',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'PLP' : {\n        'rules' : 'body.template-product-list-left-nav-template',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'PDP' : {\n        'rules' : 'section.o-layout__container',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'Basket' : {\n        'rules' : 'body#shopping-bag, body#sBag',\n        'masks' : [{'pathname':'/Basket'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'Login' : {\n        'rules' : 'body#signin, body#signIn',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'CheckoutAll' : {\n        'rules' : 'body#checkout',\n        'masks' : [{'pathname':'/Checkout'}],\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'Delivery' : {\n        'rules' : 'body#checkout #delivery.expanded',\n        'masks' : [{'pathname':'/Checkout'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'Confirmation' : {\n        'rules' : true,\n        'sendRequest' : true,\n        'masks' : [{'pathname':'/OrderOKView'}, {'pathname':'/OrderConfirmationView'}],\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    }\n};\n\nvar  mobileSitePages = {\n    'MobHomePage' : {\n        'rules' : 'body.template-home-template',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobBrandPages' : {\n        'rules' : 'body.page-custom.page-brands',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobSearch' : {\n        'rules' : 'body.page-search',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },'MobPLP' : {\n        'rules' : 'body.template-product-list-left-nav-template',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobPDP' : {\n        'rules' : 'body.layout-pdp-layout',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobBasket' : {\n        'rules' : 'body#sBag, body#shopping-bag',\n        'masks' : [{'pathname':'/Basket'}, {'pathname':'/OrderItemUpdate'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobLogin' : {\n        'rules' : 'body#signin, body#signIn',\n        'masks' : [{'pathname':'/'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobCheckoutAll' : {\n        // 'rules' : 'body#checkoutYourDetails, body#checkoutDeliveryOptions\n        // updated 17.06.2015 by Taras Turchyn - include all checkout steps\n        // 'rules' : function(){\n        // \treturn document.querySelector('body[id^=\"checkout\"]');\n        // },\n        'rules': 'body[id^=\"checkout\"]',\n        'masks' : [{'pathname':'/Checkout'}, {'pathname':'/SubmitOrder'}, {'pathname': '/SaveGuestUserDetails'}],\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobDelivery' : {\n        'rules' : 'body#checkoutYourDetails #deliverySection>*, body#checkoutDeliveryOptions #deliverySection>*, body#checkoutClickCollect #deliverySection>*, body#checkoutDeliveryAddresses #deliverySection>*',\n        'masks' : [{'pathname':'/Checkout'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobPayment' : {\n        'rules' : 'body#checkoutPayment',\n        'masks' : [{'pathname':'/Checkout'}, {'pathname':'/SubmitOrder'}, {'pathname' : '/ThreeDEndPoint'}],\n        'sendRequest' : true,\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    },\n    'MobConfirmation' : {\n        'rules' : true,\n        'sendRequest' : true,\n        'masks' : [{'pathname':'/OrderOKView'}, {'pathname':'/OrderConfirmationView'}],\n        'domains' : ['www.selfridges.com', 'test.selfridges.com', 'www.test1.selfridges.com', 'cm.selfridges.com', 'cm.test1.selfridges.com', 'cm.test2.selfridges.com', 'ibm1www.selfridges.com']\n    }\n};\n\nfunction checkoutChecker() {\n\n    // plugin for Payment and Delivery Pages detection as second(third) steps on CheckoutAll Page\n    var firstTimePaymnt = true,\n        firstTimeDeliv = true,\n        isGuest = $('#register').length ? true: false;\n\n    function deliveryGuestCase(ajaxUrl) { // if we have Guest case Delivery page will detect after user will fill Register page\n        var dlvEventType = firstTimeDeliv ? 'success.Delivery': 'end.Delivery';\n\n        if (isGuest && /SaveGuestUserDetailsSPDC/.test(ajaxUrl)) {\n            console.warn('trigger', dlvEventType);\n            if (firstTimeDeliv) visitor.requestPage('Delivery');\n            events.trigger(dlvEventType, {domain : location.hostname});\n            firstTimeDeliv = false;\n        }\n    }\n\n\n    window.$(document).ajaxComplete(function (e, obj, urlObj) {\n        var payEventType = firstTimePaymnt ? 'successPayment': 'endPayment';\n        // Payment state detection\n        if (/GiftingUpdateProcess/.test(urlObj.url)) {\n            console.warn('trigger', 'start.Payment');\n            events.trigger('startPayment', {domain : location.hostname});\n        } else if (/GetPaymentOptionsView/.test(urlObj.url)) {\n            console.warn('trigger', payEventType);\n            if (firstTimePaymnt) visitor.requestPage('Payment');\n            events.trigger(payEventType, {domain : location.hostname});\n            firstTimePaymnt = false;\n        }\n        deliveryGuestCase(urlObj.url);\n    });\n\n    if (isGuest) {\n        if ($('body#checkout #delivery.expanded').length) {\n            firstTimeDeliv = false;\n        }\n        $(document).on('click', '#register #checkoutSubmit1.btnN2L', function() {\n            console.warn('trigger', 'start.Delivery');\n            events.trigger('startDelivery', {domain : location.hostname});\n        });\n    }\n}\n\nmodules.define('pageType', function () {\n    // list of pages\n    var thisModule = this;\n    var type;\n    // thisModule.type = undefined;\n    var sitePages;\n    var page, PagesClass;\n\n    PagesClass = function() {};\n    PagesClass.prototype.getDomain = function() {\n        return location.hostname;\n    };\n    PagesClass.prototype.checkMask = function(masks) {\n        var result = false,\n            mask,\n            strict = false;\n\n        for (var i in masks) {\n            mask = masks[i];\n            strict = !!mask['strict'];\n            delete mask['strict'];\n            for (var j in mask) {\n                if (typeof mask[j] === 'string') {\n                    if (strict) {\n                        result = location[j] === mask[j];\n                    } else {\n                        result = location[j].indexOf(mask[j]) !== -1;\n                    }\n                } else if (mask[j] instanceof RegExp) {\n                    result = !!location[j].match(mask[j]);\n                }\n            }\n            if (result === true) break;\n        }\n        return result;\n    };\n    PagesClass.prototype.check = function(name, options) {\n        var self = this,\n            copyRules,\n            rules = options.rules,\n            domLoaded = false,\n            rulesCheckerDeferred, rulesCheckerPromice, stopCondition = function() {\n                return false;\n            },\n            stopOnDomReainess = true;\n\n        stopOnDomReainess = typeof options.stopOnDomReainess !== 'undefined' ? options.stopOnDomReainess : true;\n        copyRules = rules;\n\n        if (!name || !rules || !this.checkMask(options.masks) || options.domains.indexOf(this.getDomain()) === -1) {\n            return;\n        }\n\n        // trigger only if we check by some element on the page\n        self.onStart(name);\n        if (typeof rules === 'string') {\n            rules = function() {\n                return document.querySelectorAll(copyRules).length;\n\n            };\n        } else if (typeof rules === 'boolean' && rules) {\n            self.onSuccess(name, options.sendRequest, true);\n            return false;\n        }\n\n        if (stopOnDomReainess) {\n            stopCondition = function() {\n                return domLoaded;\n            };\n            events.domReady(function() {\n                domLoaded = true;\n            });\n        }\n\n        when(rules, stopCondition)\n            .done(function() {\n                self.onSuccess(name, options.sendRequest);\n            })\n            .fail(function() {\n                self.onEnd(name);\n            });\n    };\n    PagesClass.prototype.onSuccess = function(triggerName, sendRequest) {\n        var sendRequest = sendRequest || false;\n        var _this = this;\n\n        this.debugLog('trigger', 'success', triggerName);\n\n        // site.scope['pageType'].push(triggerName);\n        site.scope['pageType'] = triggerName;\n        type = triggerName;\n        function resolveCallback () {\n            site.scope['pageTriggers'][triggerName].resolve({\n                'domain': _this.getDomain()\n            });\n        };\n        if (sendRequest) {\n            visitor.requestPage(triggerName).done(resolveCallback);\n        } else {\n            resolveCallback();\n        }\n    };\n    PagesClass.prototype.onStart = function(triggerName) {\n        this.debugLog('trigger', 'start', triggerName);\n\n        site.scope['pageTriggers'] = site.scope['pageTriggers'] || {};\n        site.scope['pageTriggers'][triggerName] = Deferred();\n    };\n    PagesClass.prototype.onEnd = function(triggerName) {\n        this.debugLog('trigger', 'end', triggerName);\n        site.scope['pageTriggers'][triggerName].reject();\n    };\n    PagesClass.prototype.checkSandboxMode = function() {\n\n        var cookieCheck = false;\n\n        try {\n            // cookieCheck = /\"cfgid\":\"0\\|\\\\\"1\\\\\"/i.test(decodeURIComponent(document.cookie));\n            cookieCheck = /cfgid\":\"0\\|\\\\\"1\\\\\"/i.test(decodeURIComponent(document.cookie.match(/cfgid.*;?/i)[0]||''));\n        } catch(e) {};\n\n        this.debugOutputEnabled = cookieCheck;\n\n        return this;\n    };\n    PagesClass.prototype.debugLog = function() {\n        if (!this.debugOutputEnabled) {\n            return;\n        }\n        var message = Array.prototype.slice.call(arguments).join(' ');\n        window.console && window.console.info && window.console.info('%c' + message, 'color:#800000;font-weight:bold;font-size:13px;margin-left:40px;');\n    };\n    PagesClass.prototype.init = function(sitePages) {\n\n        this.checkSandboxMode();\n\n        site.scope['pageType'] = site.scope['pageType'] || [];\n\n        this.debugOutputEnabled && (window.debugpages = site.scope['pageType']);\n        for (var i in sitePages) {\n            this.check(i, sitePages[i]);\n        }\n    };\n\n    sitePages = document.querySelectorAll('meta[content*=\"chrome=1\"]').length ? mobileSitePages : desktopSitePages;\n\n    page = new PagesClass();\n    page.init(sitePages);\n\n\t/* sets  the calbacks   that  should execute  on  dhe resolving of page\n\t params @object\n\n\t @keys  -  trigger  names  specified  in  sitePages object\n\n\t @values - functions  that will  be executed  when  corresponding page-related defferd  will  be resolved\n\n\t @example\n\t site.scope.setPageLoadHandlers({\n\t 'Merkzettel': function() { console.warn('Merkzettel') },\n\t 'SearchresultPagePage': function() { console.warn('SearchresultPagePage') },\n\t 'ProductOvervewPage': function() { console.warn('ProductOvervewPage') }\n\t });\n\t */\n\n    var setPageLoadHandlers = function(handlersObject) {\n        var pageTriggers = site.scope['pageTriggers'] || {},\n            pageDeffereds = Object.keys(pageTriggers);\n        if (!handlersObject) {\n            return;\n        }\n\n        pageDeffereds.forEach(function(triggerName) {\n            var handler = handlersObject[triggerName];\n            if (handler && typeof handler === 'function') {\n                pageTriggers[triggerName].done(handler);\n            }\n        });\n    };\n    var whenPageType = function () {\n        var args = [].slice.call(arguments);\n        var deferred = new Deferred();\n        var numOfPages = args.length;\n\n        if( !numOfPages ) {\n            return deferred.reject();\n        }\n\n        args.every(function (name) {\n            var currentPromise = (site.scope['pageTriggers'] && site.scope['pageTriggers'][name]) ? site.scope['pageTriggers'][name] : null;\n            if( currentPromise ) {\n                currentPromise\n                    .done(deferred.resolve)\n                    .fail(function(){\n                        numOfPages -= 1;\n                        if( numOfPages == 0) {\n                            deferred.reject();\n                        }\n                    });\n            } else {\n                deferred.reject();\n            }\n            return true;\n        });\n\n        return deferred.promise();\n    };\n\n    whenPageType('CheckoutAll')\n        .then(Helper.whenJQuery)\n        .done(checkoutChecker);\n\n\n    this.when = whenPageType;\n    this.setPageLoadHandlers = setPageLoadHandlers;\n    this.getType = function () {\n        return type;\n    }\n});\n","Order":-50,"HighLevelApiVersion":"1.24"},{"Name":"ActAddToBasket","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*jslint indent: 2 */\n/*global mmcore, $, window, document */\n/*\n  Event\n    mmcore.action.mobAddToBasket - mobile site version add to basket action\n*/\nfunction addToBasket(attr){\n\n$('section.o-layout__container button.c-filter__atb').on('click', function () {\n\n        var interval = setInterval(checkelement);\n        function checkelement() {\n          var exists = $('.c-notifications .c-notifications__item.--info').length > 0 || $('.c-notifications .c-notifications__item.wishlistNotification').length > 0;\n          if (exists) {\n            var yes = $('.c-notifications .c-notifications__item.--info').length > 0;\n            var no = $('.c-notifications .c-notifications__item.wishlistNotification').length > 0;\n            if (yes) {\n                console.log('added to the basket success');\n\t\tactions.set('M_AddToBasket', 1, attr);\n    \t\tevents.trigger('AddToBasket');\n    \t\tactions.send();\n            } else if (no) {\n           \t// do nothing;\n            }\n            clearInterval(interval);\n          }\n        };\n\n});\n  $(document).ajaxComplete(function(event, xhr, settings) {\n    if (settings.url.indexOf('cart') > -1){\n      console.log('added to the basket');\n      actions.set('M_AddToBasket', 1, attr);\n      events.trigger('AddToBasket');\n      actions.send();\n    }\n    if (settings.url.indexOf('cart') > -1 && $('.quick-view-overlay-container .pdp-top-container').length > 0) {\n      console.log('added to the quickview basket');\n      actions.set('M_QuickViewAddBasket', 1, attr);\n      events.trigger('AddToBasket');\n      actions.send();\n    }\n  });\n}\npageType.when('PLP', 'PDP', 'Search')\n  .then(Helper.whenJQuery)\n    .done(function () {\n      addToBasket( pageType.getType() );\n    });\n","Order":0,"HighLevelApiVersion":"1.24"},{"Name":"ActMobAddToBasket","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*jslint indent: 2 */\n/*global mmcore, $, window, document */\n/*\n  Event\n    mmcore.action.mobAddToBasket - mobile site version add to basket action\n*/\nvar ACTION_NAME = 'M_MobAddToBasket';\nvar TRIGGER_NAME = 'mobAddToBasket';\nvar attr = '';\n//decorate ajax\nfunction addXMLRequestCallback(callback){\n  var oldSend, i;\n  if( XMLHttpRequest.callbacks ) {\n    // we've already overridden send() so just add the callback\n    XMLHttpRequest.callbacks.push( callback );\n  } else {\n    // create a callback queue\n    XMLHttpRequest.callbacks = [callback];\n    // store the native send()\n    oldSend = XMLHttpRequest.prototype.send;\n    // override the native send()\n    XMLHttpRequest.prototype.send = function(){\n      // process the callback queue\n      // the xhr instance is passed into each callback but seems pretty useless\n      // you can't tell what its destination is or call abort() without an error\n      // so only really good for logging that a request has happened\n      // I could be wrong, I hope so...\n      // EDIT: I suppose you could override the onreadystatechange handler though\n      for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {\n        XMLHttpRequest.callbacks[i].apply( this, arguments );\n      }\n      // call the native send()\n      oldSend.apply(this, arguments);\n    }\n  }\n};\nfunction init () {\n  addXMLRequestCallback( function(  ) {\n    //decorate onreadystatechange clients function\n    var xhr = this;\n    this.onreadystatechange = this.onreadystatechange || function(){};\n\n    this.onreadystatechange = (function(origin){\n      return function(){\n        //call onreadystatechange clients function\n        origin();\n        //on ajax complete call our code\n        if (xhr.readyState === 4) {\n          var response;\n          if( xhr.responseText ) {\n            if (/Item added to your Shopping Bag/im.test(xhr.responseText)) {\n              actions.set(ACTION_NAME, 1);\n              events.trigger(TRIGGER_NAME);\n              actions.send();\n            }\n          }\n        }\n      }\n    }(this.onreadystatechange));\n  });\n};\n//native ajaxComplete [end]\npageType\n  .when('MobPLP', 'MobPDP')\n   .then(Helper.whenJQuery)\n    .done(function () {\n      attr = pageType.getType();\n      init();\n    });","Order":0,"HighLevelApiVersion":"1.24"},{"Name":"Gender Attribute Capture Script","Type":"script","Attrs":{"type":"text/javascript"},"Data":"// Below is the code that has been generated automatically from the attribute's rules.\n\nvar attrName = \"Gender\";\n\n// start config\nvar config = {\n    \"datalayer\": {\n        \"variable\": \"utag.data.visitor_title\",\n        \"rules\": [\n            {\n                \"condition\": \"equals\",\n                \"text\": \"miss\",\n                \"value\": \"Female\"\n            },\n            {\n                \"condition\": \"equals\",\n                \"text\": \"mr\",\n                \"value\": \"Male\"\n            },\n            {\n                \"condition\": \"equals\",\n                \"text\": \"mrs\",\n                \"value\": \"Female\"\n            },\n            {\n                \"condition\": \"equals\",\n                \"text\": \"ms\",\n                \"value\": \"Female\"\n            },\n            {\n                \"condition\": \"equals\",\n                \"text\": \"dr\",\n                \"value\": \"Unknown\"\n            }\n        ],\n        \"defaultValue\": \"Male\"\n    }\n};\n// end config\n\nvar getVariable = function (variablePath) {\n    var i, result = window, variables;\n\n    if (typeof variablePath.split !== 'function') {\n        return null;\n    }\n\n    variables = variablePath.split('.');\n\n    for(i = 0; i < variables.length; i++) {\n        if (typeof result === 'object') {\n            result = result[variables[i]];\n        } else {\n            result = null;\n            break;\n        }\n    }\n\n    return result;\n};\n\n\nvar toDecimal = function (value) {\n    var result = null;\n    var parse = /[0-9]+(\\.[0-9]{1,2})?/.exec(value);\n\n    if (parse !== null) {\n        result = parseFloat(parse[0]);\n    }\n\n    return result;\n};\n\nvar checkCondition = function (value, rule) {\n    var decimalValue;\n    var result = false;\n    switch (rule.condition) {\n    case 'equals':\n        if (value === rule.text) {\n            result = true;\n        }\n        break;\n    case 'does not equal':\n        if (value !== rule.text) {\n            result = true;\n        }\n        break;\n    case 'contains':\n        if (value && typeof value.indexOf === 'function' && value.indexOf(rule.text) !== -1) {\n            result = true;\n        }\n        break;\n    case 'does not contain':\n        if (value && typeof value.indexOf === 'function' && value.indexOf(rule.text) === -1) {\n            result = true;\n        }\n        break;\n    case 'has value less than':\n        decimalValue = toDecimal(value);\n        if (decimalValue !== null && decimalValue < parseFloat(rule.text)) {\n            result = true;\n        }\n        break;\n    case 'has value greater than':\n        decimalValue = toDecimal(value);\n        if (decimalValue !== null && decimalValue > parseFloat(rule.text)) {\n            result = true;\n        }\n        break;\n    case 'is true':\n        if ('true' === (value + '').toLowerCase()) {\n            result = true;\n        }\n        break;\n    case 'is false':\n        if ('false' === (value + '').toLowerCase()) {\n            result = true;\n        }\n        break;\n    default:\n        result = false;\n    }\n\n    return result;\n};\n\nvar onReady = function () {\n    var rule, attributeValue;\n    var captureValue = getVariable(config.datalayer.variable);\n\n    for (var i = 0; i < config.datalayer.rules.length; i++) {\n        rule = config.datalayer.rules[i];\n\n        if (checkCondition(captureValue, rule)) {\n            attributeValue = rule.useDatalayerValue ? captureValue : rule.value;\n            visitor.storeAttr(attrName, attributeValue);\n            return;\n        }\n    }\n\n    attributeValue = config.datalayer.defaultUseDatalayerValue ? captureValue : config.datalayer.defaultValue;\n    visitor.storeAttr(attrName, attributeValue);\n};\n\n\nevents.domReady(onReady.bind(this));","Order":2000,"HighLevelApiVersion":"1.24"}],"Campaigns":[{"Name":"FIX-Checkout-Pre-select-Emails","Type":"ABnMVT","CSName":"","HighLevelApiVersion":"1.24","PagePrefix":"MDgzODM3","Scripts":[{"Name":"Google Universal","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*configuration block begin*/\nvar config = {\n    \"trackerName\": \"tealium\",\n    \"customDimensions\": \"44\"\n}\n\ntry { if (window.self !== window.top) { return; } }\ncatch (e) { return; }\n\nwindow.addEventListener('load', function(event) {\n  visitor.setData('GoogleIntegrationCounter', 0);\n  visitor.setData('GoogleIntegrationSevars', []);\n  visitor.setData('GoogleIntegrationData', {});\n});\n\nwindow.addEventListener('unload', function(event) {\n  visitor.setData('GoogleIntegrationCounter', 0);\n  visitor.setData('GoogleIntegrationSevars', []);\n  visitor.setData('GoogleIntegrationData', {});\n});\n\nvar pushIntegrationsEventInitTriggered = campaign.getData('pushIntegrationsInitEventTriggered');\ncampaign.events.on('pushIntegrationsInitEvent', ProcessInit);\nif (pushIntegrationsEventInitTriggered) { ProcessInit();}\n\nfunction ProcessInit() {\n  visitor.setData('GoogleIntegrationCounter', (visitor.getData('GoogleIntegrationCounter') || 0) + 1);\n  campaign.setData('pushIntegrationsInitEventTriggered', false);\n}\n\ncampaign.events.on('pushIntegrationsEvent', ProcessEvent);\n\nfunction ProcessEvent(processData) {\n    var experience = getExperienceData();\n    if (processData.isRedirect && processData.isFirst) {\n      campaign.setData('googleData', experience);\n      campaign.setData('pushIntegrationsEventReceivedByGoogle', true)\n      return;\n    } else if (processData.isRedirect && !processData.isFirst) {\n      experience = campaign.getData('googleData');\n      campaign.setData('googleData', null);\n    }\n    campaign.setData('pushIntegrationsEventReceivedByGoogle', true)\n    campaign.setData('pushIntegrationsEventProcessedByGoogle', true);\n    if (!isNewGeneration(experience)) { \n      visitor.setData('GoogleIntegrationCounter', (visitor.getData('GoogleIntegrationCounter') || 0) - 1);\n      return; \n    }\n    var sevars = visitor.getData('GoogleIntegrationSevars') || [];\n            var sevarsData = visitor.getData('GoogleIntegrationData') || {};\n            var data = campaign.getName() + (isProduction() ? '' : ' QA' ) + '=' + experience;\n            var sevarKey = config.trackerName + '&' + config.customDimensions;\n            if (sevars.indexOf(sevarKey) === -1) { sevars.push(sevarKey); }\n  \t\t\tif (sevarsData[sevarKey] && sevarsData[sevarKey].url !== window.location.href) { sevarsData[sevarKey] = null; }\n            sevarsData[sevarKey] = sevarsData[sevarKey] || {data: '', trackerName: '', customDimensions: '', url: ''};\n  \t\t\tvar newData = (sevarsData[sevarKey].data && sevarsData[sevarKey].data.indexOf(data) > -1) ? sevarsData[sevarKey].data : sevarsData[sevarKey].data + data + ',';\n            sevarsData[sevarKey] = { data: newData,\n                                    trackerName: config.trackerName,\n                                    customDimensions: config.customDimensions,\n                                    url: window.location.href,\n                                    campaign: (sevarsData[sevarKey].campaign || '') + campaign.getName() + ','};\n            visitor.setData('GoogleIntegrationCounter', (visitor.getData('GoogleIntegrationCounter') || 0) - 1);\n            if (visitor.getData('GoogleIntegrationCounter') === 0) {\n              waitForGA(function() {\n                for (var i = 0; i < sevars.length; i++) {\n                    var o = sevarsData[sevars[i]];\n                    var set = (o.trackerName ? o.trackerName + '.' : '') + 'set';\n\t\t\t\t\tvar name = o.campaign;\n                  \tvar send = (o.trackerName ? o.trackerName + '.' : '') + 'send';\n        \t\t\tvar category = 'Maxymiser' + (isProduction() ? '': ' QA');\n        \t\t\tvar action = name;\n                  \tif (o.customDimensions) {\n            \t\t\twindow[window['GoogleAnalyticsObject']](set, 'dimension' + o.customDimensions, o.data);\n        \t\t\t}\n        \t\t\tif (o.data) {\n        \t\t\t\twindow[window['GoogleAnalyticsObject']](send, 'event', category, action, o.data, {'nonInteraction': 1});\n    \t\t\t\t}\n                }\n                sevars = [];\n                sevarsData = {};\n                });\n            }\n          \tvisitor.setData('GoogleIntegrationSevars', sevars);\n            visitor.setData('GoogleIntegrationData', sevarsData);\n}\n\nfunction isNewGeneration(experienceData) {\n    if (campaign.getData('GoogleUniversalExperience') === experienceData) {\n        return false;\n    }\n    campaign.setData('GoogleUniversalExperience', experienceData);\n    return true;\n}\n\nfunction waitForGA(callback) {\n    var timeout = false;\n    when(function(){\n        return typeof window[window['GoogleAnalyticsObject']] === 'function';\n    }, function(){\n        return timeout;\n    }).done(function(){\n        callback();\n    });\n    setTimeout(function(){\n        timeout = true;\n    }, 10e3);\n}\nfunction setDimension(experience){\n    var set = (config.trackerName ? config.trackerName + '.' : '') + 'set';\n    var name = campaign.getName() + (isProduction() ? '' : ' QA');\n    window[window['GoogleAnalyticsObject']](set, 'dimension' + config.customDimensions, name + '=' + experience);\n}\nfunction sendEvent(expData){\n    if (expData) {\n        var send = (config.trackerName ? config.trackerName + '.' : '') + 'send';\n        var category = 'Maxymiser' + (isProduction() ? '': ' QA');\n        var action = campaign.getName();\n        window[window['GoogleAnalyticsObject']](send, 'event', category, action, expData, {'nonInteraction': 1});\n    }\n}\nfunction getExperienceData(){\n    var experience = campaign.getExperience();\n    var variants = [];\n    for(var element in experience) {\n        variants.push(element + ':' + experience[element]);\n    }\n    return variants.join('|');\n}\nfunction isProduction(){\n    if (location.search.toLowerCase().indexOf('mmcore.') > -1) {\n        return false;\n    }\n    function removeExpiration(v) {\n        return v ? v.replace(/^\\d\\|/, '') : '';\n    }\n    var storage = mmsystem.getConfig().storageType;\n    if (storage === 'cookie-key-value' || storage === 'cookie-key-value-secure') {\n        if (/mmapi.p.cfgid/i.test(document.cookie) || /mmapi.p.un/i.test(document.cookie)) {\n            return false;\n        } else {\n            return true;\n        }\n    }\n    var mmcoreP = readCookieStorage('mmcore.store.p.') || {};\n    var mmcoreS = readCookieStorage('mmcore.store.s.') || {};\n    var mmapiP = readCookieStorage('mmapi.store.p.') || {};\n    var mmapiS = readCookieStorage('mmapi.store.s.') || {};\n    var storageTypes = [mmcoreP, mmcoreS, mmapiP, mmapiS];\n    var storageKeys = {\n        'mmparams.p': 1,\n        'mmparams.d': 1\n    };\n    var utils = {\n        'un': 1,\n        'cfgID': 1,\n        'pruh': 1\n    };\n    for (var l = storageTypes.length; l--;) {\n        var storageType = storageTypes[l];\n        for (var storageKey in (storageKeys || {})) {\n            for (var util in (utils || {})) {\n                if ((storageType[storageKey] || {})[util]) {\n                    return false;\n                }\n            }\n        }\n    }\n    function readCookieStorage(name) {\n        var res = {},\n            whole = '',\n            i = 0,\n            chunk;\n        while ((chunk = getCookie(name + i++))) {\n            whole += chunk;\n        }\n        whole = decodeURIComponent(whole);\n        try {\n            res = JSON.parse(whole);\n        } catch (e) {}\n        return res;\n    }\n    function getCookie(name) {\n        var r = new RegExp('(?:^|; )' + encodeURIComponent(name).replace(/([.$?*|{}()\\[\\]\\\\\\/+^])/g, '\\\\$1') + '=([^;]+)'),\n            value = (document.cookie.match(r) || ['', ''])[1];\n        return value;\n    }\n    return true;\n}","Order":5000,"HighLevelApiVersion":"1.24"},{"Name":"Integrations Manager","Type":"script","Attrs":{"type":"text/javascript"},"Data":"var config = {\n    \"elementUrls\": [\n        {\n            \"name\": \"Element1\",\n            \"includedUrls\": [\n                \"http*://www.selfridges.com/*\",\n                \"http*://b02www.selfridges.com/*\"\n            ],\n            \"excludedUrls\": []\n        }\n    ],\n    \"redirectUrls\": []\n};\n\ncampaign.events.on('lastRequest', PushIntegrationsManager);\nvar isRedirect = campaign.getData('isRedirect');\nisRedirect = localStorage.getItem(campaign.getName() + '_isRedirect');\n\nvar currentUrl = window.location.href;\n  var matchOnRedirectUrls = Match(currentUrl, config['redirectUrls']);\n  var matchOnElementUrls = false;\n  var matchInclude = false;\n  var matchExclude = false;\n  for (var i = 0; i < config['elementUrls'].length; i++) {\n    matchInclude = Match(currentUrl, config['elementUrls'][i].includedUrls);\n    matchExclude = Match(currentUrl, config['elementUrls'][i].excludedUrls);\n    if (matchInclude && !matchExclude) {\n      matchOnElementUrls = true;\n      break;\n    }\n  }\n\nif (matchOnElementUrls || (matchOnRedirectUrls && isRedirect)) {\n  campaign.setData('pushIntegrationsInitEventTriggered', true);\n  campaign.events.trigger('pushIntegrationsInitEvent', true);\n}\n\nif (isRedirect) {\n  PushIntegrationsManager();\n}\n                   \nfunction PushIntegrationsManager() {\n  isRedirect = campaign.getData('isRedirect');\n  var currentUrl = window.location.href;\n  var matchOnRedirectUrls = Match(currentUrl, config['redirectUrls']);\n  var matchOnElementUrls = false;\n  var matchInclude = false;\n  var matchExclude = false;\n  for (var i = 0; i < config['elementUrls'].length; i++) {\n    matchInclude = Match(currentUrl, config['elementUrls'][i].includedUrls);\n    matchExclude = Match(currentUrl, config['elementUrls'][i].excludedUrls);\n    if (matchInclude && !matchExclude) {\n      matchOnElementUrls = true;\n      break;\n    }\n  }\n  if (matchOnElementUrls) {\n    var data = {'isFirst': true, 'isRedirect': isRedirect};\n    campaign.setData('pushIntegrationsEventTriggered', data);\n    campaign.events.trigger('pushIntegrationsEvent', data);\n  } else if (matchOnRedirectUrls && isRedirect) {\n    campaign.setData('isRedirect', null);\n    var data = {'isFirst': false, 'isRedirect': true};\n    campaign.setData('pushIntegrationsEventTriggered', data);\n    campaign.events.trigger('pushIntegrationsEvent', data);\n  }\n}\n\nfunction MatchMask (url, originalMask) {\n  var mask = '^';\n  var pos = 0;\n  while (originalMask.length > pos) {\n    var char = originalMask[pos];\n    if (char == '*') {\n\t  mask = mask + '.*';\n\t  pos = pos + 1;\n\t} else if (char == '(') {\n      var posClosing = originalMask.indexOf(')', pos + 1);\n      var posNextOpening = originalMask.indexOf('(', pos + 1);\n\t  if (posClosing > pos && (posNextOpening < 0 || posClosing < posNextOpening)) {\n        mask = mask + '.*';\n        pos = posClosing + 1;\n      } else {\n        return false;\n      }\n    } else {\n      mask = mask + char;\n      pos = pos + 1;\n    }\n  }\n  mask = mask + '$';\n  mask = mask.replace('?', \"\\\\?\");\n  var r = new RegExp(mask);\n  return r.test(url);\n}\n\nfunction Match(url, masks) {\n  if (!url || !masks) {\n    return false;\n  }\n  url = url.toLowerCase();\n  var matchedMasks = 0;\n  for (var i = 0; i < masks.length; i++) {\n    var mask = masks[i].toLowerCase();\n    if (MatchMask(url, mask)) {\n      matchedMasks = matchedMasks + 1;\n    }\n  }\n  return matchedMasks > 0;\n}","Order":5000,"HighLevelApiVersion":"1.24"}],"Elements":[],"Recommendations":[]},{"Name":"HACK-SelfPlus banner on PDP","Type":"ABnMVT","CSName":"","HighLevelApiVersion":"1.24","PagePrefix":"MDg5MDI5","Scripts":[{"Name":"C1798647990","Type":"script","Attrs":{"type":"text/javascript"},"Data":"document.addEventListener(\"DOMContentLoaded\", function(){\n  /*configuration block begin*/\nvar config = {\n\t\"actionName\": \"SelfPlus-bannerClick\",\n\t\"value\": 1,\n\t\"attr\": \"\"\n};\n/*configuration block end*/\n\n  when(function() {\n    return window.$ && typeof window.$ === 'function' && $('body.layout-pdp-layout, .o-layout__container .c-product-hero').length > 0;\n  }).done(function() {\n    $(document).on(\"click\", \"#maxy-selfplus-wrapper a\", function() {\n    \tactions.postpone(config.actionName, config.value, config.attr);\n    });\n  });\n});","Order":4000,"HighLevelApiVersion":"1.24"}],"Elements":[],"Recommendations":[]},{"Name":"HACK - Stylitics Tracking Pixel","Type":"ABnMVT","CSName":"","HighLevelApiVersion":"1.24","PagePrefix":"MDg5NjEx","Scripts":[{"Name":"C1987039040","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*configuration block begin*/\nvar config = {\n\t\"actionName\": \"SUB-LEVEL-CLICK 3\",\n\t\"value\": 1,\n\t\"attr\": \"\"\n};\n/*configuration block end*/\n\nevents.domReady(function(){ \n  $(document).one('click', '.col-wrapper .maxy-new-cat h3, body:not(\"AB_maxy-MegaMenu-Redesign\") .menuCol:not(\".menuColFirst\"):not(\".menuFH\"):not(\".maxy-edits\") .itemGroup h3, .menuCol .c-brands-atoz__label', function(){\n   \tactions.send(config.actionName, config.value, 'SUB-LEVEL-CLICK');\n  });\n\n  $(document).on('click', '.lvl1 ul li a.arrow', function() {\n      $(document).one('click touch', '.lvl2 ul li > a.arrow', function() {\n        actions.send(config.actionName, config.value, 'SUB-LEVEL-CLICK');\n      });\n  });\n});\n","Order":4000,"HighLevelApiVersion":"1.24"},{"Name":"C1794369184","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*configuration block begin*/\nvar config = {\n\t\"actionName\": \"EXPANDED-SUB-LEVEL 4\",\n\t\"value\": 1,\n\t\"attr\": \"\"\n};\n/*configuration block end*/\n\nevents.domReady(function(){ \n  $(document).on('click', '.lvl3 ul li a, .subcol-wrapper .menuCol dd > a, body:not(\"AB_maxy-MegaMenu-Redesign\") .menuBlock dl.itemGroup dd > a, .menuCol .c-brands-atoz__link', function(){\n   actions.postpone(config.actionName, config.value, 'clicked expanded sub-link');\n  });\n});\n\n","Order":4000,"HighLevelApiVersion":"1.24"},{"Name":"C504692340","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*configuration block begin*/\nvar config = {\n\t\"actionName\": \"MEGA-MENU-CLICK 3\",\n\t\"value\": 1,\n\t\"attr\": \"\"\n};\n/*configuration block end*/\n\nevents.domReady(function(){ \n  $(document).one('click', '.lvl2 ul li a:not(\".arrow\"), .megamenu ul li a, .selfsays-wrapper a, .col-wrapper .maxy-edits a, .menuBlock.whats_on a, .subcol-wrapper a', function(){\n   actions.send(config.actionName, config.value, 'MEGA-MENU-CLICK');\n  });\n $(document).on('click', '.lvl1 ul li a.arrow', function() {\n   $(document).on('click touch', '.lvl2 ul li > a.arrow', function() {\n     $(document).one('click touch', '.lvl3 ul li a', function() {\n        actions.postpone(config.actionName, config.value, 'MEGA-MENU-CLICK');\n     });\n   });\n });\n});\n\n","Order":4000,"HighLevelApiVersion":"1.24"},{"Name":"C1760471626","Type":"script","Attrs":{"type":"text/javascript"},"Data":"/*configuration block begin*/\nvar config = {\n\t\"actionName\": \"HOVER-BURGER-CLICK 3\",\n\t\"value\": 1,\n\t\"attr\": \"\"\n};\n/*configuration block end*/\n\nevents.domReady(function(){ \n  $(document).one('mouseenter', '#mm-topNav div.mmBook', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - book');\n  });\n  $(document).one('mouseenter', '#mm-topNav div.mmShop', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - shop');\n  });\n  $(document).one('mouseenter', '#mm-topNav div.mmVisit', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - visit');\n  });\n    $(document).one('mouseenter', '.megamenu li a', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - shop_expanded');\n  });\n  $(document).one('touch click', 'li.sign-in, li.wishlist, li.bag, li.account', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - icon_click');\n  });\n  $(document).one('touch click', '.js-mobile-menu-trigger', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - hamburger_click');\n  });\n  $(document).one('touch click', '#topNav .nav-wrapper .shop', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - shop_click');\n  });\n  $(document).one('touch click', '#topNav .nav-wrapper .book', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - book_click');\n  });\n  $(document).one('touch click', '#topNav .nav-wrapper .visit', function(){\n   actions.send(config.actionName, config.value, 'HOVER-BURGER-CLICK - visit_click');\n  });\n});\n","Order":4000,"HighLevelApiVersion":"1.24"}],"Elements":[],"Recommendations":[]}],"MRRules":[],"PersistData":[{"Name":"srv","IsGlobal":false,"Value":"prodiadcgeu04","Expiration":365},{"Name":"bid","IsGlobal":false,"Value":"prodiadcgeu04","Expiration":0.00694},{"Name":"pd","IsGlobal":false,"Value":"dS-alJAetEPZdb4q8ghui3XQ9Zg92aHEAaX-YAd0Wxg=|AQAAAApDH4sIAAAAAAAEAGNhWPxyhfF5kbedDMyZiSmMQgyMTgzpTxU-MTLs_95jtCH0pgeMZgCC_1DAwOaSWZSaXMJ4XoQRJA4GPzcxIRQwMDPUujMyxB2NZmTYwR3HyBAEVMPoCgB8npNRcAAAAA==","Expiration":365}],"SiteInfo":[{"Url":"selfridges.com","ID":841}],"SystemData":[{"Version":"1.0","RequestId":1,"ResponseId":1}],"GenInfo":{},"ServerAttributes":{"GeoCountry":"US","EMPTY-00":"","MensContent":"","WomensContent":""},"Iteration":"tloHsRxJZlwWItZVKvh9x397oE8","Packages":["mmpackage-1.24.js"]});