if (document.getElementById){try{if (typeof(_dt) == 'undefined') { var _dt = { debug: false, data: null, frames: [], handlers: {}, trace : function(msg, data) { }, loadScript : function(url, callback) { var scr = document.createElement('SCRIPT'); scr.type = 'text/javascript'; scr.setAttribute('defer','true'); scr.setAttribute('async','true'); if (callback) { if (scr.readyState) { scr.onreadystatechange = function() { if (scr.readyState == 'loaded' || scr.readyState == 'complete') { scr.onreadystatechange = null; callback(); } }; } else { scr.onload = function() { callback(); }; } } scr.src = url; var s0 = document.getElementsByTagName('script')[0]; s0.parentNode.insertBefore(scr, s0); if (this.debug) console.log('Invoking Script: '+url); }, onPageReady : function(handler) { if (document.readyState === 'complete') setTimeout(handler, 1); else if (document.addEventListener) { document.addEventListener('DOMContentLoaded', handler, false); window.addEventListener('load', handler, false); } else if (document.attachEvent) { document.attachEvent('onreadystatechange', handler); window.attachEvent('onload', handler); } }, detachHandler : function(handler) { if (document.addEventListener) { document.removeEventListener('DOMContentLoaded', handler, false); window.removeEventListener('load', handler, false); } else { document.detachEvent('onreadystatechange', handler); window.detachEvent('onload', handler); } }, attachUnloadHandler : function(handler) { this.bindEvent(window, "beforeunload", handler); if (!window.addEventListener) window.attachEvent("onunload", handler); }, parmVal : function(parm){ try { var hashes = [this.data, this.parentData]; for (var i=0; i < hashes.length; i++){ var hash = hashes[i]; if (hash){ if (typeof(hash.parms) != "undefined" && typeof(hash.parms[parm]) != "undefined") return hash.parms[parm]; else if (typeof(hash.event) != "undefined" && typeof(hash.event.parms) != "undefined" && typeof(hash.event.parms[parm]) != "undefined") return hash.event.parms[parm]; } } if (top != window.self && typeof(top._dt) != "undefined" && top._dt.data && typeof(top._dt.data.parms) != "undefined" && typeof(top._dt.data.parms[parm]) != "undefined") return top._dt.data.parms[parm]; }catch(e){this.trace("Exception:_dt.parmVal "+parm);} return null; }, propVal : function(prop){ try { if (this.data && typeof(this.data[prop]) != "undefined") return this.data[prop]; else if (typeof(top._dt) != "undefined" && top._dt.data && typeof(top._dt.data[prop]) != "undefined") return top._dt.data[prop]; }catch(e){this.trace("Exception:_dt.propVal "+prop);} return this.parmVal(prop); }, onDTLoaded : function(callback){ this.trace("Base onDTLoaded"); this.notifyFrames(); if (callback) callback(this.data); }, notifyFrames : function(){ if (this.data && window.postMessage){ if (this.frames.length){ var payload = JSON.stringify({action:"handleParentData", dtData: this.data}); for (var i=0; i < this.frames.length; i++) this.frames[i].postMessage(payload, "*"); } else{ var payload = JSON.stringify({action:"register"}); for (var i=0; i < window.frames.length; i++) window.frames[i].postMessage(payload, "*"); } } }, firePixel : function(url, callback){ if (url){ this.trace("_dt.firePixel "+url); var img = new Image(); if (callback){ img.onload = function(){callback(null);}; img.onerror = function(){callback("Failed to fire "+this.src);}; } img.src = url; } else if (callback) callback('firePixel: No URL specified.'); }, swapQSParm: function(url, parm, val){ var re = new RegExp("([?|&])" + parm + "=.*?(&|$)","i"); if (typeof(val) == "undefined") val = ""; if (url.match(re)) return url.replace(re,'$1' + parm + "=" + encodeURIComponent(val) + '$2'); else return url + '&' + parm + "=" + encodeURIComponent(val); }, parseQueryString: function(url){ var qsParms = {}; url.replace(new RegExp("([^?=&]+)(=([^&]*))", "g"), function($0, $1, $2, $3) { qsParms[$1] = $3; } ); return qsParms; }, toQueryString: function(obj){ var qp = []; if (obj){ for (var key in obj){ if (typeof(obj[key]) != "undefined") qp.push(key+"="+encodeURIComponent(obj[key])); } } return qp.join('&'); }, setCookie: function(name, value, expires){ if (name){ var when = new Date(); when.setTime(when.getTime() + 1000 * (parseInt(expires) || 0)); var domain = location.hostname.split('.').reverse().splice(0,2).reverse().join('.'); document.cookie = name + '=' + value + '; expires=' + when.toGMTString() + '; path=/; domain=.' + domain; } }, dtvisVal: function (){ var result = document.cookie.match('(^|;)\\s*dtvis\\s*=\\s*([^;]+)'); return result ? result.pop() : ''; }, bindEvent : function(element, eventName, handler){ if (element.addEventListener) element.addEventListener(eventName, handler, false); else if (element.attachEvent) window.attachEvent('on'+eventName, handler); }, handleMessage: function(e){ _dt.trace("_dt.handleMessage", e.data); try{ if (e.data && typeof(e.data) == 'string'){ var data = JSON.parse(e.data); var action = data.action; if (action && this.handlers[action]){ for (var i=0; i < this.handlers[action].length; i++){ var handler = this.handlers[action][i]; if (handler && handler._once) this.handlers[action].splice(i--, 1); handler(e, data); } } } }catch(e){this.trace("Exception:_dt.handleMessage ",e);} }, on: function(msg, handler){ if (msg && handler){ if (!this.handlers[msg]) this.handlers[msg] = []; this.handlers[msg].push(handler); } }, once: function(msg, handler){ if (msg && handler){ handler._once = 1; this.on(msg, handler); } }, onRegisterFrame: function(e, msgData){ if (this.frames.indexOf(e.source) === -1) this.frames.push(e.source); if (this.data){ e.source.postMessage(JSON.stringify({action:"handleParentData", dtData: this.data}), "*"); } }, preflightComplete: function(finalURL){ this.loadScript(finalURL); }, getUserData: function(callback){ let userData = this.propVal('profile'); if (callback) callback(_dt.error || null, userData); _dt.trace("getUserData",userData); }, deleteUserData: function(callback){ let url = this.userPixel('deletedata'); this.firePixel(url, function(response){ _dt.trace("deleteUserData complete",response); if (response == null && _dt.data) _dt.data.profile = null; if (callback) callback(response?'deleteUserData request failed':null, null); }); }, doNotSell: function(callback){ let url = this.userPixel('donotsell'); this.firePixel(url, function(err){ _dt.trace("doNotSell complete",err); if (!err){ try{ let dnspixels = _dt.propVal('dnspixels'); if (dnspixels && dnspixels.length){ for (let i=0; i < dnspixels.length; i++) (new Image()).src = dnspixels[i]; } } catch(e){} } if (callback) callback(err?'doNotSell request failed':null, null); }); }, userPixel: function(endPoint){ let sitetype = this.parmVal('sitetype'); let webid = this.parmVal('webid'); let url = this.baseURL + '/dt/user/'+endPoint+'?cs:pa=dtuser'; if (sitetype) url += '&sitetype='+sitetype; if (webid) url += '&webid='+webid; return url + "&_"+ Date.now(); }, getJSON: function(url, callback){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { try { var data = JSON.parse(xhr.responseText); } catch(err) { _dt.trace(err.message + " in " + xhr.responseText); return; } if (callback) callback(data); } }; xhr.open("GET", url, true); xhr.send(); } }; _dt.bindEvent(window, "message", _dt.handleMessage.bind(_dt)); _dt.on('registerFrame', _dt.onRegisterFrame.bind(_dt)); } _dt.vinDetector = { LABEL_RE : new RegExp(/\bvin\b[^=]/i), VIN_RE : new RegExp(/\b([A-Z0-9]{17})\b/), VIN_RE_CI : new RegExp(/\b([a-zA-Z0-9]{17})\b/), CHUNK_SIZE : 30, detect : function(container) { if (!container) container = document.body; var vin = ''; if (container.innerText) vin = this.scanForVin(container.innerText); if (!vin && container.textContent) vin = this.scanForVin(container.textContent); return vin; }, scanForVin : function(text) { var vin = ''; var vinPos = 0; var pageURL = this.getPageURL(); var ckURL = this.VIN_RE_CI.test(pageURL); var multiples = false; while ((vinPos = text.search(this.LABEL_RE)) != -1) { var result = this.VIN_RE.exec(text.substr(vinPos+3, this.CHUNK_SIZE)); if (result !== null && result[1] !== null) { /* If vin matches vin in URL, we have a definite match. */ if (ckURL && pageURL.match(RegExp(result[1], 'i'))) return result[1]; /* If more than one vin found, assume not a VDP and abort the search unless the same vin is passed on the URL. */ if (vin != '' && vin != result[1]) { multiples = true; if (!ckURL) return ''; } vin = result[1]; } text = text.substr(vinPos+20); } return multiples ? '' : vin; }, getPageURL : function(){ return document.location.href; } }; _dt.detectVIN = function(container) { return this.vinDetector.detect(container); }; _dt.preflight = function(){let url = "https://dt.cobaltgroup.com/dt/1.0/dt.js?sitetype=dealer&cblttags=1&detectleads=0&cs%3Apg=%2Fabout-us%2F&cs%3Avendor=dealerinspire&uidindex=ws&uid=&referrer=https%3A%2F%2Fwww.woodhousegm.com%2Fabout-us%2F&pfc=1";let vin = this.detectVIN(document.body);if (vin)url += "&vin=" + vin;url += "&pgreferrer=" + encodeURIComponent(document.referrer.substr(0,2000));this.preflightComplete(url);};function _dt_ready(e){_dt.preflight();if (e)_dt.detachHandler(_dt_ready);}_dt.debug = (false == 1);_dt.onPageReady(_dt_ready);}catch(e){}}