	    var spoPromoStacker = {
        init : function(){
			this.parentDomSelector = "#spoPromoStacker_wrapper";
			this.outerParent = jQuery(this.parentDomSelector).parent();
			this.loadingImage = jQuery('<img id="spoPromoStacker_loader" src="images/spoPromoStacker/loader.gif" alt="loading" />').insertBefore("#spoPromoStacker_content");
			this.loadingImage.hide();

			this.outerDomSelector = "#" + jQuery(this.parentDomSelector).parent().attr("id");
			this.orientation = this.getOrientation();
			this.rotatorExists = false;
			this.dateToday = dateToday = new Date().setHours(0,0,0,0);   
			this.defaultArray = [{type: 'static', url: 'ServiceApptForm', pxTag: 'gm_cic_spo_default', img:'CIC/Service/tiles/default.jpg', imgAlt:'Service'}];
			/* Determine which active GM franchises dealer carries. */
			this.spoFranchises = [];
			this.cmFranchises = ContextManager.getFranchises();
			for(var o=0; o < this.cmFranchises.length; o++) {
				switch (this.cmFranchises[o]) {
					case 'Chevrolet':
						this.spoFranchises.push('Chevrolet');
						break;
					case 'Buick':
						this.spoFranchises.push('Buick');
						break;
					case 'GMC':
						this.spoFranchises.push('GMC');
						break;
					case 'Cadillac':
						this.spoFranchises.push('Cadillac');
						break;
				}	
			}
			this.binarySearch(spoPromoStackerPricing);
        },
        binarySearch : function(arr){
			if(arr.length != 0) {
				this.price1 = arr[0].price.split('.');
				this.price2 = arr[0].price2.split('.');
				this.brake = arr[0].brake.split('.');				

				if(this.orientation == "horizontal") {
					this.expandCarousel();
				} else {
					this.loadingImage.fadeIn(250);
					this.trimArray();
				}
			} else {
				if(this.orientation == "horizontal") {
					return false;
				} else {
					this.promoArr = this.defaultArray;
					this.preLoad();
				}
			}
		},
		checkOEM : function(promoTileOEM) {
			if(promoTileOEM instanceof Array) {
				for (var o=0; o < promoTileOEM.length;o++) {
					for(var f=0; f < this.spoFranchises.length; f++) {
						if(promoTileOEM[o] == this.spoFranchises[f]) { return true; }
					}
				}
			}
			else {
				for(var f=0; f < this.spoFranchises.length; f++) {
					if(promoTileOEM == this.spoFranchises[f]) { return true; }
				}
			}
			return false;
		},
        trimArray : function(){
            this.promoArr = [];
			this.overrideArr = [];
            for(var i=0;i < spoPromoStackerConfig.length;i++){
                var showThisSlide = true;
                /* Logic to trim down promos array */
				if(!this.isEmpty(spoPromoStackerConfig[i].oem)) {
					if(!this.checkOEM(spoPromoStackerConfig[i].oem)) {
						showThisSlide = false;
					}
				}
				if(!this.isEmpty(spoPromoStackerConfig[i].standalone)){
					if(spoPromoStackerConfig[i].standalone && this.spoFranchises.length > 1) {
						showThisSlide = false;
					}
				}
                if((!this.checkDate(spoPromoStackerConfig[i].startDate,spoPromoStackerConfig[i].endDate))){
                    showThisSlide = false;
                }     
				if(!this.isEmpty(spoPromoStackerConfig[i].optIn)){
					if (!this.checkOptIn(spoPromoStackerConfig[i].optIn)){
						showThisSlide = false;
					}
				}					          
                if(!this.isEmpty(spoPromoStackerConfig[i].design)){
                    if(!this.checkDesign(spoPromoStackerConfig[i].design)){
                        showThisSlide = false;
                    }
                }
                if(!this.isEmpty(spoPromoStackerConfig[i].groupShow)){
                    if(!this.checkGroup(spoPromoStackerConfig[i].groupShow)){
                        showThisSlide = false;
                    }
                }
                if(!this.isEmpty(spoPromoStackerConfig[i].groupHide)){
                    if(this.checkGroup(spoPromoStackerConfig[i].groupHide)){
                        showThisSlide = false;
                    }
                }
                /* Logic to trim the rotator array */
                if(spoPromoStackerConfig[i].type == 'rotator'){
                    for(var r=0; r <spoPromoStackerConfig[i].rotatorGroup.length;r++){
                        var showThisRotatorSlide = true;
                        if(!this.isEmpty(spoPromoStackerConfig[i].rotatorGroup[r].groupShow)){
                            if(!this.checkGroup(spoPromoStackerConfig[i].rotatorGroup[r].groupShow)){
                                showThisRotatorSlide = false;
                            }
                        }
                        if(!this.isEmpty(spoPromoStackerConfig[i].rotatorGroup[r].groupHide)){
                            if(this.checkGroup(spoPromoStackerConfig[i].rotatorGroup[r].groupHide)){
                                showThisRotatorSlide = false;
                            }
                        }
                        if(!showThisRotatorSlide){
                            spoPromoStackerConfig[i].rotatorGroup.splice(r,1);
                            r--;
                        }
                    }
                }
                /* Logic to show single or double price tile */
                if((this.isEmpty(this.price2)) && (spoPromoStackerConfig[i].type == 'doublePrice')){
                    showThisSlide = false;
                }
                if((this.isEmpty(this.brake)) && (spoPromoStackerConfig[i].type == 'brakePrice')){
                    showThisSlide = false;
                }
                if((!this.isEmpty(this.price2)) && (spoPromoStackerConfig[i].type == 'singlePrice')){
                    showThisSlide = false;
                }       
  
				
				/* Override check needs to be the last. If you are adding more check functionality place above this comment */
				if(!this.isEmpty(spoPromoStackerConfig[i].override) && (showThisSlide == true)){
					if (spoPromoStackerConfig[i].override instanceof Array){
						for (var t=0; t< spoPromoStackerConfig[i].override.length; t++){
							this.overrideArr.push(spoPromoStackerConfig[i].override[t]);
						}
					}
					else{
						this.overrideArr.push(spoPromoStackerConfig[i].override);
					}
				}		
                if (showThisSlide){
					this.promoArr.push(spoPromoStackerConfig[i]);
                } 
            }
			
			/* Check for overrides */
			if (this.overrideArr.length>0){
				for(var i=0;i < this.promoArr.length;i++){
					for(var o=0;o < this.overrideArr.length;o++){
						if(this.promoArr[i].id == this.overrideArr[o]){
							this.promoArr.splice(i,1);
							i--;
							break;
						}		
					}
				}
			}

            if(this.promoArr.length == 0){
				if(this.orientation=="horizontal"){
					return false;
				}
				this.promoArr = this.defaultArray;
			} else if (this.promoArr.length < 3 && this.orientation=="horizontal"){
				while(this.promoArr.length < 3 ){
					this.promoArr.push(this.promoArr[0]);
				}
			}
            this.preLoad();
        },
		expandCarousel : function() {
			var evpObj = this;
			var placeholder = jQuery('<div id="evp-ribbon-placeholder"></div>');
			placeholder.insertAfter(this.outerParent);
			
			jQuery(placeholder).animate({
				height: "250px",
				marginBottom: "20px"
			},600,'',function() {
				evpObj.loadingImage.fadeIn(250);
				jQuery(spoPromoStacker.parentDomSelector).css({
					height: "250px"
				});
				spoPromoStacker.trimArray();
			});

		},
		getOrientation : function() {
			if(window.EVPStyle == "ribbon") {
				return "horizontal";
			} else {
				return "vertical";
			}
		},
        checkDate : function(sd,ed){
            if(this.isEmpty(sd)){
                sd = this.dateToday;
            }
            else{
                sd = this.scrubDate(sd);
            }
            if(this.isEmpty(ed)){
                ed = this.dateToday;
            }
            else{
                ed = this.scrubDate(ed);
            }
            if ((this.dateToday<sd) || (this.dateToday>ed)){
                return false;
            }
            return true;    
        },
        scrubDate : function(d){
            var year=d.split("/");
            if (year[2].length<4){
                year[2]="20"+year[2];
            }
            var date=new Date(Number(year[2]), Number(year[0])-1, Number(year[1]));
            return (date);  
        },
		makeCarousel : function() {
			EVPCarousel = function() {}

			EVPCarousel.prototype.createCarousel = function() {
				var carouselObj = this;
				var EVPs = jQuery(carouselObj.EVPContainerSelector).find(carouselObj.EVPSelector);

				jQuery('<ul id="evp_ribbon_widget"></ul>').appendTo(carouselObj.EVPContainerSelector);
				jQuery(this.parentDomSelector).addClass("evp-ribbon");
				jQuery(spoPromoStacker.outerDomSelector).css({
					height: "250px"
				});

				EVPs.each(function() {
				   var liWrapper = jQuery('<li style="float:left;clear:none;"></li>');
				   jQuery(this).clone().appendTo(liWrapper);
				   jQuery(liWrapper).appendTo("#evp_ribbon_widget");
				   jQuery(this).remove();
				});

				if(EVPs.length>3) {
					jQuery('<a class="prev button disabled">Prev</a>').insertBefore(this.parentDomSelector).hover(function() {
						jQuery(this).addClass("hover");
					}, function() {
						jQuery(this).removeClass("hover");
					});
					jQuery('<a class="next button">Next</a>').insertAfter(this.parentDomSelector).hover(function() {
						jQuery(this).addClass("hover");
					}, function() {
						jQuery(this).removeClass("hover");
					});
					jQuery("#spoPromoStacker_content").jCarouselLite({
						btnNext: spoPromoStacker.outerDomSelector + " .button.next",
						btnPrev: spoPromoStacker.outerDomSelector + " .button.prev",
						circular: false,
						start:0,
						scroll: 1,
						speed:600
					});
				} else {
					jQuery("#spoPromoStacker_content").jCarouselLite({
						circular: false,
						start:0,
						scroll: 1,
						speed:600
					});
				}
			}

			EVPCarousel.prototype.init = function() {
				this.EVPContainerSelector = "#spoPromoStacker_content";
				this.parentDomSelector = jQuery(spoPromoStacker.parentDomSelector);
				this.EVPSelector = ".spoPromoStacker_container";

				this.createCarousel();
			}
			
			var EVPRibbon = new EVPCarousel();
			EVPRibbon.init();
		},
        checkDesign : function(d){
            if(ContextManager.getDesign().toLowerCase() == d.toLowerCase()){
                return true;
            }
            return false;   
        },
        checkOptIn : function(opt){
			var promotions = ContextManager.getPromotions() || [];
			if(opt instanceof Array){
				var counter = 0;
				for(var p=0;p<promotions.length;p++){
					for(var o=0;o<opt.length;o++){
						if(opt[o].toLowerCase() ==  promotions[p].title.toLowerCase()){
							counter++;
						}
					}
				}
				if(counter == opt.length){
					return true;
				}
			}
			else{
				for(var g=0;g<promotions.length;g++){
					if(opt.toLowerCase() == promotions[g].title.toLowerCase()){
						return true;
					}
				}
			}
			return false;
        },		
        checkGroup : function(g){
            var siteGroups = ContextManager.getSiteGroups();
            if (g instanceof Array){
                for(var s=0;s<siteGroups.length;s++){
                    for(var q=0;q<g.length;q++){
                        if(g[q].toLowerCase() == siteGroups[s].toLowerCase()){
                            return true;
                        }
                    }
                }
                return false;
            }
            else{
                for(var s=0;s<siteGroups.length;s++){
                    
                    if(g.toLowerCase() == siteGroups[s].toLowerCase()){
                        return true;
                    }
                }
                return false;
            }
        },
        preLoad : function(){
            var imgs = []
            for(var a = 0; a<this.promoArr.length;a++){
                if(this.promoArr[a].type == 'rotator'){
                    for(var r = 0; r<this.promoArr[a].rotatorGroup.length;r++){
                        imgs.push(this.promoArr[a].rotatorGroup[r].img);
                    }
                }
                else{
                    imgs.push(this.promoArr[a].img);
                }
            }
            var pic = [], i, total = imgs.length, loaded = 0;
            for (i=0;i<total;i++) {
                pic[i] = new Image();
                jQuery(pic[i]).load(function() {
                    loaded++; 
                    if (loaded == total){
                        spoPromoStacker.loadHtml();
						window.EVPLoaded = true;
                    }
                });
				pic[i].src = imgs[i];
            }
        },
        loadHtml : function(){
            var htmlString = '';
            for(var i=0;i<this.promoArr.length;i++){
                var linkoutArr = ['',''];   
                if(!this.isEmpty(this.promoArr[i].url)){
                    if(this.promoArr[i].tagNgo){
                        linkoutArr = ["<a href='"+this.promoArr[i].url+"' target='_blank' onclick='this.tag(\""+this.promoArr[i].pxTag+"\")'>","</a>"];
                    }
                    else{
                        linkoutArr = ["<a href='"+this.buildCleanUrl(this.promoArr[i].url,this.promoArr[i].pxTag,this.promoArr[i].descriptionText)+"'>","</a>"];                    
                    }
                }
                if(this.promoArr[i].type == 'singlePrice' || this.promoArr[i].type == 'brakePrice'){
                    var priceType = this.price1;
                    if(this.promoArr[i].type == 'brakePrice'){
                        priceType = this.brake;
                    }
                    htmlString += "<div class='spoPromoStacker_container'>";
                    htmlString += linkoutArr[0];
					htmlString += "<img src='"+this.promoArr[i].img+"' alt='"+this.promoArr[i].imgAlt+"' />";
					htmlString += "<p class='spoPromoStackerPrice' style='left: "+this.promoArr[i].priceProps.x+"px; top: "+this.promoArr[i].priceProps.y+"px; font-size: "+this.promoArr[i].priceProps.size+"px; color: "+this.promoArr[i].priceProps.color+"; "+this.promoArr[i].pricePropsOptionalStyle+"'>";
					htmlString += "$"+priceType[0]+"<span style='font-size:"+this.promoArr[i].priceProps.centSize+"px; top:"+this.promoArr[i].priceProps.centOffset+"px;'>"+priceType[1]+"</span>";
					htmlString += "</p>"+linkoutArr[1]+"</div>";
                }
                else if(this.promoArr[i].type == 'doublePrice'){
                    htmlString += "<div class='spoPromoStacker_container'>";
					htmlString += linkoutArr[0];
					htmlString += "<img src='"+this.promoArr[i].img+"' alt='"+this.promoArr[i].imgAlt+"' />";
					htmlString += "<p class='spoPromoStackerPrice' style='left: "+this.promoArr[i].priceProps.x1+"px; top: "+this.promoArr[i].priceProps.y1+"px; font-size: "+this.promoArr[i].priceProps.size+"px; color: "+this.promoArr[i].priceProps.color+"; "+this.promoArr[i].pricePropsOptionalStyle+"'>";
					htmlString += "$"+this.price1[0]+"<span style='font-size:"+this.promoArr[i].priceProps.centSize+"px; top:"+this.promoArr[i].priceProps.centOffset+"px'>"+this.price1[1]+"</span>";
					htmlString += "</p><p class='spoPromoStackerPrice' style='left: "+this.promoArr[i].priceProps.x2+"px; top: "+this.promoArr[i].priceProps.y2+"px; font-size: "+this.promoArr[i].priceProps.size+"px; color: "+this.promoArr[i].priceProps.color+"; "+this.promoArr[i].pricePropsOptionalStyle+"'>";
					htmlString += "$"+this.price2[0]+"<span style='font-size:"+this.promoArr[i].priceProps.centSize+"px; top:"+this.promoArr[i].priceProps.centOffset+"px'>"+this.price2[1]+"</span>";
					htmlString += "</p>"+linkoutArr[1]+"</div>";
                }
                else if(this.promoArr[i].type == 'rotator'){
                    this.rotatorExists = true;
                    htmlString += "<div class='spoPromoStacker_container spoPromoStacker_rotator' id='spoPromoStacker_rotator_"+i+"' style='height:"+this.promoArr[i].rotatorHeight+"px; width:"+this.promoArr[i].rotatorWidth+"px; position:relative; overflow:hidden;'>";
                    for(var r = 0; r<this.promoArr[i].rotatorGroup.length;r++){
                        var firstSlide = ["","style='display:none'"];
                        if(r == 0){firstSlide = [" active","style='display:block'"];}
                        var htmlRotString = ['',''];
                        if(!this.isEmpty(this.promoArr[i].rotatorGroup[r].url)){
                            if(this.promoArr[i].rotatorGroup[r].tagNgo){
                                htmlRotString = ["<a href='"+this.promoArr[i].rotatorGroup[r].url+"' target='_blank' onclick='this.tag(\""+this.promoArr[i].rotatorGroup[r].pxTag+"\")'>","</a>"];
                            }
                            else{
                                htmlRotString = ["<a href='"+this.buildCleanUrl(this.promoArr[i].rotatorGroup[r].url,this.promoArr[i].rotatorGroup[r].pxTag,this.promoArr[i].rotatorGroup[r].descriptionText)+"'>","</a>"];         
                            }
                        }                       
                        htmlString += "<div class='spoPromoStacker_rotator_container"+firstSlide[0]+"' "+firstSlide[1]+" rel='"+this.promoArr[i].rotatorGroup[r].duration+","+(r+1)+","+this.promoArr[i].rotatorGroup.length+"'>"+htmlRotString[0]+"<img src='"+this.promoArr[i].rotatorGroup[r].img+"' alt='"+this.promoArr[i].rotatorGroup[r].imgAlt+"' />"+htmlRotString[1]+"</div>";    
                    }   
                    htmlString += "</div>";
                }
                else if(this.promoArr[i].type == 'static'){                              
                    htmlString += "<div class='spoPromoStacker_container'>"+linkoutArr[0]+"<img src='"+this.promoArr[i].img+"' alt='"+this.promoArr[i].imgAlt+"' />"+linkoutArr[1]+"</div>";
                }
            }
            
            jQuery('#spoPromoStacker_content').html(htmlString);
            this.displayStacker();
        },
        displayStacker : function(){
            jQuery('#spoPromoStacker_loader').fadeOut(250);
            jQuery('#spoPromoStacker_content').fadeIn(1000);
            if(this.rotatorExists){
                this.initSlideShow();
            }
            if(this.orientation == "horizontal") {
				this.makeCarousel();
            } else {
                var defaultEVPCSSString = "div.spoPromoStacker_container{margin-bottom: 15px; position:relative; width:300px; height:250px; }\n";
            }
        },
        initSlideShow : function(){
            jQuery("div.spoPromoStacker_rotator").each(function(){
                spoPromoStacker.slideShow(jQuery(this).attr("id"),true);
            });
        },
        slideShow : function(id,f){     
            var tmp = jQuery("#"+id).find("div.active");
            var slideProps = (tmp.attr('rel')).split(',');      
            if(!f){     
                tmp.removeClass('active').fadeOut(750); 
                if(slideProps[1] == slideProps[2]){
                    tmp.parent().find("div.spoPromoStacker_rotator_container:eq(0)").addClass('active').fadeIn(750);
                }
                else{
                    tmp.parent().find("div.spoPromoStacker_rotator_container:eq("+Number(slideProps[1])+")").addClass('active').fadeIn(750);
                }
            }
            tmp.parent().animate({'opacity':'100'},Number(slideProps[0]),function(){
                spoPromoStacker.slideShow(id,false);
            })              
        },
        tag : function(pixelTagId){
            var promoPixelTag = {
                pageLayout : 'linkout_' + pixelTagId,
                pageName : pixelTagId,
                pageLabel : 'linkout_' + pixelTagId + "_"+ContextManager.getPageName()+"&cs:lo=" + pixelTagId 
            };  
            EventManager.publish({
                eventName:'com.cobaltgroup.ws.action.click.SPO',
                publisherData:promoPixelTag
            });
        },
        buildCleanUrl : function(u,t,d){    
			if(!spoPromoStacker.isEmpty(d) && !spoPromoStacker.isEmpty(t) ){
				d = d.replace(/<<p1>>/i, "$"+spoPromoStacker.price1[0]+"."+spoPromoStacker.price1[1]).replace(/<<p2>>/i, "$"+spoPromoStacker.price2[0]+"."+spoPromoStacker.price2[1]).replace(/<<b>>/i, "$"+spoPromoStacker.brake[0]+"."+spoPromoStacker.brake[1]);
				t = t+"&"+d;
			}
            if(this.isEmpty(t)){
                return u;
            }
            else if (u.search("\\?") == -1){
                return u+"?cs:a:i="+t;
            }
            else{
                return u+"&cs:a:i="+t;
            }
        },      
        isEmpty : function(testVar){
            if ((testVar==undefined)||(testVar==null)||(testVar=="null")||(testVar=="")||(testVar=="undefined")){
                return true;
            }
            return false;
        }       
    };
