{"size": 39287, "ext": "js", "max_stars_repo_path": "app-quickstart-init.js", "max_stars_repo_name": "speedaddictcycles/speedaddictcycles", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "app-quickstart-init.js", "max_issues_repo_name": "speedaddictcycles/speedaddictcycles", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "app-quickstart-init.js", "max_forks_repo_name": "speedaddictcycles/speedaddictcycles", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 41.4857444562, "max_line_length": 335, "alphanum_fraction": 0.6905592181}
(function(_app){
var configURI = (document.location.protocol == 'file:') ? _app.vars.testURL+'jsonapi/config.js' : _app.vars.baseURL+'jsonapi/config.js';

//Load the config.js script asynchronously.  When it finishes loading, we can start up the app
_app.u.loadScript(configURI,function(){
	//in some cases, such as the zoovy UI, zglobals may not be defined. If that's the case, certain vars, such as jqurl, must be passed in via P in initialize:
	_app.vars.username = zGlobals.appSettings.username.toLowerCase(); //used w/ image URL's.
	//need to make sure the secureURL ends in a / always. doesn't seem to always come in that way via zGlobals
	_app.vars.secureURL = zGlobals.appSettings.https_app_url;
	_app.vars.domain = zGlobals.appSettings.sdomain; //passed in ajax requests.
	_app.vars.jqurl = (document.location.protocol === 'file:') ? _app.vars.testURL+'jsonapi/' : '/jsonapi/';
	
	var startupRequires = ['quickstart', 'store_sac', 'store_filter', 'gts.html'];
	
	_app.require(startupRequires, function(){
		setTimeout(function(){$('#appView').removeClass('initFooter');}, 1200);
		_app.ext.quickstart.callbacks.startMyProgram.onSuccess();
		
		if(window.location.pathname.indexOf('/invoice') == 0){
			
			}
		else {
			_app.ext.store_sac.u.applyGTS();
			}
		setTimeout(function(){
			_app.require('templates.html',function(){
				postscribe('#provideSupport', '<script type="text/javascript">'+_app.templates.provideSupportScript.html()+'</script>');
				}),
			1500});
		});
	}); //The config.js is dynamically generated.
	
_app.extend({
	"namespace" : "quickstart",
	"filename" : "app-quickstart.js"
	});

_app.couple('quickstart','addPageHandler',{
	"pageType" : "static",
	"require" : [],
	"handler" : function($container, infoObj){
		var deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(deferred);
		if(infoObj.deferred){
			infoObj.defPipeline.addDeferred(infoObj.deferred);
			}
		//We use infoObj.require here because the router handlers may have put something in there.
		//By nature, the static page handler requires nothing, but the templates it renders may require all kinds of stuff
		infoObj.require = infoObj.require || [];
		_app.require(infoObj.require,function(){
			infoObj.verb = 'translate';
			infoObj.templateid = infoObj.templateID;
			var $page = new tlc().runTLC(infoObj);
			//$page.tlc(infoObj);
			$page.data('templateid',infoObj.templateid);
			$page.data('pageid',infoObj.id);
			$container.append($page);
			infoObj.state = 'complete';
			//this method is synchronous so no extra deferred required
			_app.renderFunctions.handleTemplateEvents($page,infoObj);
			deferred.resolve();
			});
		}
	});

_app.extend({
	"namespace" : "order_create",
	"filename" : "extensions/checkout/extension.js"
	});

_app.couple('quickstart','addPageHandler',{
	"pageType" : "checkout",
	"require" : ['order_create','cco', 'extensions/checkout/active.html'],
	"handler" : function($container, infoObj, require){
		var deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(deferred);
		infoObj.templateID = 'checkoutTemplate';
		_app.require(require,function(){
			$container.attr('id', 'checkoutContainer');
			_app.ext.order_create.a.startCheckout($container,_app.model.fetchCartID());
			infoObj.state = 'complete'; //needed for handleTemplateEvents.
			_app.renderFunctions.handleTemplateEvents($container,infoObj);
			deferred.resolve();
			});
		}
	});
_app.u.bindTemplateEvent('checkoutTemplate','depart.destroy',function(event, $context, infoObj){
	var $page = $context.closest('[data-app-uri]');
	if($page){
		$page.empty().remove();
		}
	});
_app.couple('quickstart','addPageHandler',{
	"pageType" : "invoice",
	"require" : ['order_create', 'store_crm','extensions/checkout/active.html'],
	"handler" : function($container, infoObj, require){
		_app.require(require, function(){
			_app.ext.order_create.a.showInvoice($container, infoObj.cartid);
			});
		}
	});
	
_app.extend({
	"namespace" : "cco",
	"filename" : "extensions/cart_checkout_order.js"
	});

_app.couple('quickstart','addPageHandler',{
	"pageType" : "cart",
	"require" : ['cco','order_create','templates.html'],
	"handler" : function($container, infoObj, require){
		infoObj.deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(infoObj.deferred);
		infoObj.navcat = zGlobals.appSettings.rootcat;
		infoObj.cartid = _app.model.fetchCartID();
		infoObj.templateID = 'cartTemplate';
		infoObj.trigger = 'fetch';
		_app.require(require,function(){
			//var $cart = new tlc().getTemplateInstance('cartTemplate');
			//var $cart = $(_app.renderFunctions.createTemplateInstance('cartTemplate',infoObj));
			var $cart = _app.ext.cco.a.getCartAsJqObj(infoObj);
			$container.append($cart);
			
			$cart.on('complete',function(){
				$("[data-app-role='shipMethodsUL']",$(this)).find(":radio").each(function(){
					$(this).attr('data-app-change','quickstart|cartShipMethodSelect');
					});
				});

			$cart.trigger(infoObj.trigger,$.extend({'Q':'mutable'},infoObj));
				_app.model.dispatchThis('mutable');
			
			// _app.calls.cartDetail.init(_app.model.fetchCartID(),{
				// 'callback':'tlc',
				// 'onComplete' : function(){
					// infoObj.state = 'complete';
					// _app.renderFunctions.handleTemplateEvents($cart,$.extend(true,{},infoObj));
					// },
				// 'jqObj' : $cart,
				// 'verb' : 'translate'
				// },'mutable');
			// _app.model.dispatchThis('mutable');
			});
		}
	});
_app.u.bindTemplateEvent(function(templateID){ return (templateID == 'cartTemplate' || templateID == 'fieldcamTemplate')},'depart.destroy',function(event, $context, infoObj){
	var $page = $context.closest('[data-app-uri]');
	if($page){
		$page.empty().remove();
		}
	});

_app.extend({
	"namespace" : "store_routing",
	"filename" : "extensions/store_routing.js"
	});
	//formerly in startup callback of store_routing
_app.router.addAlias('product',		function(routeObj){_app.ext.quickstart.a.showContent(routeObj.value,	$.extend({'pageType':'product'}, routeObj.params));});
_app.router.appendHash({'type':'match','route':'/product/{{pid}}/{{name}}*','callback':'product'});
_app.router.appendHash({'type':'match','route':'/product/{{pid}}*','callback':'product'});


_app.router.addAlias('homepage',	function(routeObj){_app.ext.quickstart.a.showContent(routeObj.value,	$.extend({'pageType':'homepage'}, routeObj.params));});
_app.router.appendHash({'type':'exact','route':'/home','callback':'homepage'});
_app.router.appendHash({'type':'exact','route':'/home/','callback':'homepage'});
_app.router.appendHash({'type':'exact','route':'/','callback':'homepage'});

_app.router.addAlias('category',	function(routeObj){_app.ext.quickstart.a.showContent(routeObj.value,	$.extend({'pageType':'category'}, routeObj.params));});
_app.router.appendHash({'type':'match','route':'/category/{{navcat}}*','callback':'category'});

_app.router.addAlias('search',		function(routeObj){_app.ext.quickstart.a.showContent(routeObj.value,	$.extend({'pageType':'search'}, routeObj.params));});
_app.router.appendHash({'type':'match','route':'/search/tag/{{tag}}*','callback':'search'});
_app.router.appendHash({'type':'match','route':'/search/keywords/{{KEYWORDS}}*','callback':'search'});

_app.router.addAlias('checkout',	function(routeObj){_app.ext.quickstart.a.showContent(routeObj.value,	$.extend({'pageType':'checkout', 'requireSecure':true}, routeObj.params));});
_app.router.appendHash({'type':'exact','route':'/checkout','callback':'checkout'});
_app.router.appendHash({'type':'exact','route':'/checkout/','callback':'checkout'});

_app.router.addAlias('invoice',		function(routeObj){
	var infoObj = $.extend({'pageType' : 'invoice','requireSecure' : true}, routeObj.params, _app.u.getWhitelistedObject(routeObj.searchParams, ['cartid']));
	console.log(routeObj.searchParams);
	console.log(infoObj);
	_app.ext.quickstart.a.showContent(routeObj.value, infoObj);
	});
_app.router.appendHash({'type':'exact','route':'/invoice','callback':'invoice'});
_app.router.appendHash({'type':'exact','route':'/invoice/','callback':'invoice'});

_app.router.addAlias('cart',	function(routeObj){_app.ext.quickstart.a.showContent(routeObj.value,	$.extend({'pageType':'cart'}, routeObj.params));});
_app.router.appendHash({'type':'exact','route':'/cart','callback':'cart'});
_app.router.appendHash({'type':'exact','route':'/cart/','callback':'cart'});

_app.router.appendHash({'type':'exact','route':'/404','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'pageNotFoundTemplate',
		'require':'templates.html'
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});

_app.router.appendHash({'type':'exact','route':'/about_us/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'aboutUsTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.router.appendHash({'type':'exact','route':'/contact_us/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'contactUsTemplate',
		'require':['templates.html','store_crm']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.router.appendHash({'type':'exact','route':'/frequently_asked_questions/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'faqTemplate',
		'require':['templates.html','store_crm']
		});
	dump(routeObj.params);
	routeObj.params.deferred = $.Deferred();
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.u.bindTemplateEvent('faqTemplate','complete.faq',function(event, $context, infoObj){
	$context.off('complete.faq');
	dump('in faq complete event');
	_app.require(['store_crm','templates.html'],function(){
		_app.ext.store_crm.calls.appFAQsAll.init({'jqObj':$('.faqContent',$context),'deferred':infoObj.deferred,'callback':'showFAQTopics','extension':'store_crm','templateID':'faqTopicTemplate'});
		_app.model.dispatchThis();			
		});
	});
_app.router.appendHash({'type':'exact','route':'/payment_policy/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'paymentTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.router.appendHash({'type':'exact','route':'/privacy_policy/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'privacyTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.router.appendHash({'type':'exact','route':'/return_policy/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'returnTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.router.appendHash({'type':'exact','route':'/shipping_policy/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'templateID':'shippingTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
	
_app.router.appendHash({'type':'exact','route':'/my_account/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'login' : true,
		'templateID':'myAccountTemplate',
		'require':['cco','templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.u.bindTemplateEvent('myAccountTemplate','complete.customer',function(event, $context, infoObj){
	_app.ext.cco.calls.appCheckoutDestinations.init(_app.model.fetchCartID(),{},'mutable'); //needed for country list in address editor.
	_app.model.addDispatchToQ({"_cmd":"buyerAddressList","_tag":{'callback':'tlc','jqObj':$('.mainColumn',$context),'verb':'translate','datapointer':'buyerAddressList'}},'mutable');
	_app.model.dispatchThis();							
	});
_app.router.appendHash({'type':'exact','route':'/my_order_history/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'login' : true,
		'templateID':'orderHistoryTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.u.bindTemplateEvent('orderHistoryTemplate','complete.customer',function(event, $context, infoObj){
	_app.model.addDispatchToQ({"_cmd":"buyerPurchaseHistory","_tag":{'callback':'tlc','jqObj':$('.mainColumn',$context),'verb':'translate','datapointer':'buyerPurchaseHistory'}},'mutable');
	_app.model.dispatchThis();							
	});
_app.router.appendHash({'type':'exact','route':'/change_password/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'login' : true,
		'templateID':'changePasswordTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.u.bindTemplateEvent('changePasswordTemplate','complete.customer',function(event, $context, infoObj){
	_app.model.addDispatchToQ({"_cmd":"buyerPurchaseHistory","_tag":{
		"datapointer":"buyerPurchaseHistory",
		"callback":"tlc",
		"verb" : "translate",
		"jqObj" : $("[data-app-role='orderList']",$context).empty()
		}},"mutable");
	_app.model.dispatchThis();							
	});
_app.router.appendHash({'type':'exact','route':'/my_wishlist/','callback':function(routeObj){
	$.extend(routeObj.params,{
		'pageType':'static',
		'login' : true,
		'templateID':'customerListsTemplate',
		'require':['templates.html']
		});
	_app.ext.quickstart.a.showContent(routeObj.value,routeObj.params);
	}});
_app.u.bindTemplateEvent('customerListsTemplate','complete.customer',function(event, $context, infoObj){
	_app.model.addDispatchToQ({"_cmd":"buyerProductLists","_tag":{"datapointer":"buyerProductLists",'verb':'translate','jqObj': $('.mainColumn',$context),'callback':'tlc',onComplete : function(rd){
//data formatting on lists is unlike any other format for product, so a special handler is used.				
		function populateBuyerProdlist(listID,$context)	{
			//add the product list ul here because tlc statement has list ID for bind.
			$("[data-buyerlistid='"+listID+"']",$context).append("<ul data-tlc=\"bind $var '.@"+listID+"'; store_prodlist#productlist  --hideSummary='1' --withReviews='1' --withVariations='1' --withInventory='1' --templateid='productListTemplateBuyerList'  --legacy;\" class='listStyleNone fluidList clearfix noPadOrMargin productList'></ul>");
			_app.model.addDispatchToQ({"_cmd":"buyerProductListDetail","listid":listID,"_tag" : {'datapointer':'buyerProductListDetail|'+listID,"listid":listID,'callback':'buyerListAsProdlist','extension':'quickstart', "require":"store_prodlist",'jqObj':$("[data-buyerlistid='"+listID+"'] ul",$context)}},'mutable');
			}
		
		var data = _app.data[rd.datapointer]['@lists']; //shortcut
		var L = data.length;
		var numRequests = 0;
		for(var i = 0; i < L; i += 1)	{
			populateBuyerProdlist(data[i].id,rd.jqObj)
			}
		_app.model.dispatchThis('mutable');
		//no sense putting 1 list into an accordion.
		if(L > 1)	{
			$('.applyAccordion',rd.jqObj).accordion({heightStyle: "content"});
			}
		}}},"mutable");
	_app.model.dispatchThis();							
	});
		
_app.u.bindTemplateEvent(function(){return true;}, 'complete.routing', function(event, $context, infoObj){
	if(infoObj){
		var canonical = "";
		
		var $routeEle = $('[data-canonical]',$context);
		if($routeEle.length){ canonical = $routeEle.attr('data-canonical'); }
		else{
			canonical = $context.closest('[data-app-uri]').attr('data-app-uri');
			}
		
		var $canonical = $('link[rel=canonical]')
		if(!$canonical.length){
			dump('NO CANONICAL IN THE DOCUMENT');
			$canonical = $('<link rel="canonical" href="" />');
			$('head').append($canonical);
			}
		$canonical.attr('href', canonical);
		}
	});
	
_app.extend({
	"namespace" : "store_tracking",
	"filename" : "extensions/store_tracking.js"
	});
_app.couple('order_create','addOrderCompleteHandler',{
	'handler':function(P){
		_app.require('store_tracking',function(){
			if(P && P.datapointer && _app.data[P.datapointer] && _app.data[P.datapointer].order){
				var order = _app.data[P.datapointer].order;
				var plugins = zGlobals.plugins;
				// note: order is an object that references the raw (public) cart
				// order.our.xxxx  order[@ITEMS], etc.
				// data will appear in google analytics immediately after adding it (there is no delay)
				ga('require', 'ecommerce');
				//analytics tracking
				var r = {
					'id' : order.our.orderid,
					'revenue' : order.sum.items_total,
					'shipping' : order.sum.shp_total,
					'tax' : order.sum.tax_total
					};
				// _app.u.dump(r);
				ga('ecommerce:addTransaction',r);

				for(var i in order['@ITEMS']){
					var item = order['@ITEMS'][i];
					// _app.u.dump(item);
					ga('ecommerce:addItem', {
						'id' : order.our.orderid,
						'name' : item.prod_name,
						'sku' : item.sku,
						'price' : item.base_price,
						'quantity' : item.qty,
						})
					};

				ga('ecommerce:send');
				_app.u.dump('FINISHED store_tracking.onSuccess (google analytics)');
				
				for(var i in plugins){
					if(_app.ext.store_tracking.trackers[i] && _app.ext.store_tracking.trackers[i].enable){
						_app.ext.store_tracking.trackers[i](order, plugins[i]);
						}
					}
				}
			});
		}
	});

//Generate meta information
_app.u.bindTemplateEvent(function(){return true;}, 'complete.metainformation',function(event, $context, infoObj){
	var defaultTitle = "Motorcycle Helmets, Gear, and Parts";
	var titlePrefix = "";
	var titlePostfix = " - Speed Addict Cycles";
	
	var baseTitle = $('[data-seo-title]', $context).attr('data-seo-title') || defaultTitle;
	var desc = $('[data-seo-desc]', $context).attr('data-seo-desc') || '';
	
	document.title = titlePrefix + baseTitle + titlePostfix;
	$('meta[name=description]').attr('content', desc);
	});
	
//Scroll restore
_app.u.bindTemplateEvent(function(){return true;}, 'complete.scrollrestore',function(event, $context, infoObj){
	var scroll = $context.data('scroll-restore');
	if(scroll){
		$('html, body').animate({scrollTop : scroll}, 300);
		}
	else if((infoObj.performJumpToTop === false) ? false : true) {
		$('html, body').animate({scrollTop : 0}, 300);
		}
	else {
		//do nothing
		}
	});
	
_app.u.bindTemplateEvent(function(){return true;}, 'depart.scrollrestore', function(event, $context, infoObj){
	var scroll = $('html').scrollTop()
	$context.data('scroll-restore',scroll);
	});

// _app.u.bindTemplateEvent('productTemplate', 'complete.invcheck',function(event, $context, infoObj){
	// if(!$context.attr('data-invcheck')){
		// $context.attr('data-invcheck','true');
		// var data = _app.data['appProductGet|'+infoObj.pid];
		// var variations = data['@variations'];
		// if(variations.length == 1){
			// var id = variations[0].id;
			// $('select[name='+id+'] option', $context).each(function(){
				// var sku = infoObj.pid+":"+id+""+$(this).attr("value");
				// dump(sku);
				// dump(data["@inventory"][sku]);
				// if(data["@inventory"][sku] && data["@inventory"][sku].AVAILABLE <= 0){
					// //$(this).attr("disabled","disabled");
					// $(this).remove();
					// }
				// });
			// }
		// }
	// });
	
_app.extend({
	"namespace" : "store_prodlist",
	"filename" : "extensions/store_prodlist.js"
	});
	
_app.extend({
	"namespace" : "prodlist_infinite",
	"filename" : "extensions/prodlist_infinite.js"
	});
	
_app.extend({
	"namespace" : "store_navcats",
	"filename" : "extensions/store_navcats.js"
	});
	
_app.couple('quickstart','addPageHandler',{
	"pageType" : "homepage",
	"require" : ['store_navcats','templates.html','store_routing', 'store_prodlist'],
	"handler" : function($container, infoObj, require){
		infoObj.deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(infoObj.deferred);
		dump('homepage handler');
		infoObj.navcat = zGlobals.appSettings.rootcat;
		_app.require(require,function(){
			infoObj.templateID = 'homepageTemplate';
			_app.ext.store_navcats.u.showPage($container, infoObj);
			});
		}
	});
	
_app.couple('quickstart','addPageHandler',{
	"pageType" : "category",
	"require" : ['store_navcats','store_prodlist','prodlist_infinite','templates.html','store_routing'],
	"handler" : function($container, infoObj, require){
		infoObj.deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(infoObj.deferred);
		if(infoObj.navcat.charAt(0) != '.'){
			infoObj.navcat = '.'+infoObj.navcat
			}
		if(_app.ext.quickstart.vars.session.recentCategories[0] != infoObj.navcat)	{
			_app.ext.quickstart.vars.session.recentCategories.unshift(infoObj.navcat);
			}
		_app.require(require,function(){
			if(infoObj.templateID){}
			else{infoObj.templateID = 'categoryTemplate';}
			if(infoObj.templateID = 'categoryTemplate'){
				infoObj.prodRenderedDeferred = $.Deferred();
				infoObj.defPipeline.addDeferred(infoObj.prodRenderedDeferred);
				}
			_app.ext.store_navcats.u.showPage($container, infoObj);
			});
						
		}
	});
	
_app.extend({
	"namespace" : "store_search",
	"filename" : "extensions/store_search.js"
	});
	
_app.couple('store_search','addUniversalFilter',{
	'filter' : {"has_child":{"type":"sku","query":{"range":{"available":{"gte":1}}}}}
	});
_app.couple('store_search','addUniversalFilter',{
	'filter' : {"not":{"term":{"tags":"IS_DISCONTINUED"}}}
	});
				
_app.couple('quickstart','addPageHandler',{
	"pageType" : "search",
	"require" : ['store_search','templates.html','store_routing'],
	"handler" : function($container, infoObj, require){
		infoObj.deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(infoObj.deferred);
		_app.require(require,function(){
			_app.ext.store_search.u.showSearch($container, infoObj);
			});
						
		}
	});
	
_app.extend({
	"namespace" : "store_product",
	"filename" : "extensions/store_product.js"
	});


_app.couple('quickstart','addPageHandler',{
	"pageType" : "product",
	"require" : ['store_product','store_navcats', 'store_routing', 'store_search', 'store_crm', 'store_prodlist', 'templates.html'],
	"handler" : function($container, infoObj, require){
		infoObj.deferred = $.Deferred();
		infoObj.defPipeline.addDeferred(infoObj.deferred);
		if($.inArray(infoObj.pid,_app.ext.quickstart.vars.session.recentlyViewedItems) < 0)	{
			_app.ext.quickstart.vars.session.recentlyViewedItems.unshift(infoObj.pid);
			}
		else	{
			_app.ext.quickstart.vars.session.recentlyViewedItems.splice(0, 0, _app.ext.quickstart.vars.session.recentlyViewedItems.splice($.inArray(infoObj.pid, _app.ext.quickstart.vars.session.recentlyViewedItems), 1)[0]);
			}
		//IMPORTANT: requiring every extension needed in order to render the page, including TLC formats in the template
		_app.require(require, function(){
			infoObj.templateID = 'productTemplate';
			_app.ext.store_product.u.showProd($container, infoObj);
			});
		}
	});
	
// _app.extend({
	// "namespace" : "cart_message",
	// "filename" : "extensions/cart_message/extension.js"
	// });
	
_app.extend({
	"namespace" : "store_crm",
	"filename" : "extensions/store_crm.js"
	});
	
// _app.extend({
	// "namespace" : "partner_addthis",
	// "filename" : "extensions/partner_addthis.js"
	// });
// _app.u.bindTemplateEvent('productTemplate', 'complete.test', function(event, $context, infoObj){
	// var $toolbox = $('.socialLinks', $context);
	// if($toolbox.hasClass('addThisRendered')){
		// //Already rendered, don't do it again.
		// }
	// else {
		// $toolbox.addClass('addThisRendered').append(
				// '<div class="addthis_toolbox addthis_default_style addthis_32x32_style">'
			// +		'<a class="addthis_button_preferred_1"></a>'
			// +		'<a class="addthis_button_preferred_2"></a>'
			// +		'<a class="addthis_button_preferred_3"></a>'
			// +		'<a class="addthis_button_preferred_4"></a>'
			// +		'<a class="addthis_button_preferred_5"></a>'
			// +		'<a class="addthis_button_preferred_6"></a>'
			// +		'<a class="addthis_button_preferred_7"></a>'
			// +		'<a class="addthis_button_preferred_8add"></a>'
			// +		'<a class="addthis_button_compact"></a>'
			// +	'</div>');
		
		// _app.ext.partner_addthis.u.toolbox($toolbox, infoObj);
		// }
	// });

_app.extend({
	"namespace" : "store_sac",
	"filename" : "extensions/_store_sac.js"
	});
_app.couple('store_search','addUniversalFilter',{
	'filter' : {"term":{"showtime":"1"}}
	});
_app.u.bindTemplateEvent('homepageTemplate', 'complete.sac', function(event, $context, infoObj){
	_app.ext.store_sac.u.startHomepageSlideshow();
	var $carousel = $('[data-sac=carousel]',$context);
	if($carousel.hasClass('carouselRendered')){
		//already rendered
		}
	else {
		$carousel.addClass('carouselRendered')
		setTimeout(function(){
			$carousel.carouFredSel({
				"responsive":true,
				"width":200,
				"height":"auto",
				"auto" : { "play" : false },
				"items" : { "visible" : 3},
				"prev" : { "button" : $('.homepageFeaturesCarouselPrev', $context) },
				"next" : { "button" : $('.homepageFeaturesCarouselNext', $context) }
				},{"debug" : false});
			},1000);
		}
	});
	
_app.u.bindTemplateEvent('productTemplate', 'complete.childcheck', function(event, $context, infoObj){
	var data = _app.data["appProductGet|"+infoObj.pid];
	if(data["%attribs"]["zoovy:grp_parent"]){
		//setTimeout(function(){_app.router.handleURIString("/product/"+data["%attribs"]["zoovy:grp_parent"]+"/");}, 200);
		}
	});
_app.u.bindTemplateEvent('productTemplate', 'complete.recentlyviewed', function(event, $context, infoObj){
	$('.recentlyViewed',$context).empty().tlc({templateid:"recentlyViewedTemplate",dataset:{session:_app.ext.quickstart.vars.session,pid:infoObj.pid}});
	});
_app.extend({
	"namespace" : "store_filter",
	"filename" : "extensions/_store_filter.js"
	});
var filterComplete = function(event, $context, infoObj){
	var $fc = $('#filterContainer');
	var $fl = $('#filterList', $fc);
	$fl.removeData().empty();		
	var dataset = $context.data('fl-dataset');
	var templateid = $context.data('fl-templateid');
	$fl.data('dataset',dataset);
	$fl.tlc({'dataset':dataset, 'templateid':templateid});
	$('form',$fl).data('jqContext',$context);
	$('button', $fl).button();
	if($context.data('templateid') != 'filteredSearchTemplateBrand'){		
		$fc.addClass('active expand');
		var timer = setTimeout(function(){
			$fc.removeClass('expand');
			}, 4000);
		$fc.data('hidetimer', timer);
		$fc.on('mouseenter.sac', function(){
			clearTimeout($fc.data('hidetimer'));
			$fc.off('mouseenter.sac');
			});
		$('form', $fc).data('loadFullList', infoObj.loadFullList).trigger('submit');
		}
	};
var filterDepart = function(event, $context, infoObj){
	var $fc = $('#filterContainer');
	$fc.removeClass('expand').removeClass('active');
	$fc.off('mouseenter.sac');
	};
_app.u.bindTemplateEvent('filteredSearchTemplate', 'complete.sac', filterComplete);
_app.u.bindTemplateEvent('filteredSearchTemplate', 'depart.sac', filterDepart);
_app.u.bindTemplateEvent('filteredSearchTemplateBrand', 'complete.sac', filterComplete);
_app.u.bindTemplateEvent('filteredSearchTemplateBrand', 'depart.sac', filterDepart);

_app.router.appendHash({'type':'exact','route':'/motorcycle-helmets/', 'callback':function(routeObj){
	_app.ext.quickstart.a.showContent(routeObj.value,{
		'pageType' : 'static',
		'require' : ['templates.html'],
		'templateID':'helmetsTemplate'
		});
	}});
_app.router.appendHash({'type':'exact','route':'/parts/', 'callback':function(routeObj){
	_app.ext.quickstart.a.showContent(routeObj.value,{
		'pageType' : 'static',
		'require' : ['templates.html'],
		'templateID':'partsTemplate'
		});
	}});
_app.router.appendHash({'type':'exact','route':'/apparel/', 'callback':function(routeObj){
	_app.ext.quickstart.a.showContent(routeObj.value,{
		'pageType' : 'static',
		'require' : ['templates.html'],
		'templateID':'apparelTemplate'
		});
	}});
_app.router.appendHash({'type':'exact','route':'/brands/', 'callback':function(routeObj){
	_app.ext.quickstart.a.showContent(routeObj.value,{
		'pageType' : 'static',
		'require' : ['templates.html'],
		'templateID':'brandsTemplate'
		});
	}});

//Adds the listener for the url.  The route needs to match the page pushed into robots below
_app.router.appendHash({'type':'match','route':'/motorcycle-helmets/{{id}}/*','callback':'filter'});
//This is the list of helmet pages.  The ID is part of the URL- change this for SEO reasons- the jsonPath is the file where it loads the options from.  The jsonPath doesn't matter as long as it loads the file
var helmetPages = [
	{id:'dirt-bike',jsonPath:'filters/helmets/dirt-bike.json'},
	{id:'accessories',jsonPath:'filters/helmets/helmet-accessories.json'},
	{id:'dual-sport',jsonPath:'filters/helmets/dual-sport.json'},
	{id:'half-shell',jsonPath:'filters/helmets/half-shell.json'},
	{id:'modular',jsonPath:'filters/helmets/modular.json'},
	{id:'three-quarter',jsonPath:'filters/helmets/three-quarter.json'},
	{id:'full-face',jsonPath:'filters/helmets/full-face.json'}
	];
for(var i in helmetPages){	
	_app.couple('store_filter','addPage',helmetPages[i]);
	}

_app.router.appendHash({'type':'match','route':'/parts/{{id}}/*','callback':'filter'});
var partsPages = [
	{id:'chain-and-sprocket-kits',jsonPath:'filters/parts/chain-kits.json'},
	{id:'electrical',jsonPath:'filters/parts/electrical.json'},
	{id:'exhaust',jsonPath:'filters/parts/exhaust.json'},
	{id:'intake',jsonPath:'filters/parts/intake.json'},
	{id:'suspension',jsonPath:'filters/parts/suspension.json'},
	{id:'brakes',jsonPath:'filters/parts/brakes.json'},
	{id:'controls',jsonPath:'filters/parts/controls.json'},
	{id:'repair-manual',jsonPath:'filters/parts/repair-manual.json'},
	{id:'chain',jsonPath:'filters/parts/chain.json'},
	{id:'tires',jsonPath:'filters/parts/tires.json'},
	{id:'grip-pads',jsonPath:'filters/parts/grip-pads.json'}
	];
for(var i in partsPages){	
	_app.couple('store_filter','addPage',partsPages[i]);
	}

_app.router.appendHash({'type':'match','route':'/apparel/{{id}}/*','callback':'filter'});
var apparelPages = [
	{id:'motorcycle-jackets',jsonPath:'filters/apparel/motorcycle-jackets.json'},
	{id:'motorcycle-pants',jsonPath:'filters/apparel/motorcycle-pants.json'},
	{id:'motorcycle-race-suits',jsonPath:'filters/apparel/motorcycle-race-suits.json'},
	{id:'motorcycle-boots',jsonPath:'filters/apparel/motorcycle-boots.json'},
	{id:'gloves',jsonPath:'filters/apparel/gloves.json'},
	{id:'goggles',jsonPath:'filters/apparel/goggles.json'},
	{id:'grips',jsonPath:'filters/apparel/grips.json'},
	{id:'luggage',jsonPath:'filters/apparel/luggage.json'},
	{id:'tools',jsonPath:'filters/apparel/tools.json'},
	{id:'security',jsonPath:'filters/apparel/security.json'},
	{id:'tank-pads',jsonPath:'filters/apparel/tank-pads.json'},
	{id:'hitcase',jsonPath:'filters/apparel/hitcase.json'}
	];
for(var i in apparelPages){	
	_app.couple('store_filter','addPage',apparelPages[i]);
	}

_app.router.appendHash({'type':'match','route':'/brands/{{id}}/*','callback':'filter' /*use brandFilter later*/});
_app.router.appendHash({'type':'match','route':'/brand-feature-reviews/{{id}}/*','callback':'brandFilter'});
var brandsPages = [
	{id:'airoh-helmets',jsonPath:'filters/brands/airoh-helmets.json'},
	{id:'ancra-tie-downs',jsonPath:'filters/brands/ancra-tie-downs.json'},
	{id:'answer',jsonPath:'filters/brands/answer.json'},
	{id:'arai-helmets',jsonPath:'filters/brands/arai-helmets.json'},
	{id:'bmc-air-filters',jsonPath:'filters/brands/bmc-air-filters.json'},
	{id:'cortech-riding-gear',jsonPath:'filters/brands/cortech.json'},
	{id:'factory-racing',jsonPath:'filters/brands/factory-racing.json'},
	{id:'giant-loop-luggage',jsonPath:'filters/brands/giant-loop-luggage.json'},
	{id:'hjc-helmets',jsonPath:'filters/brands/hjc-helmets.json'},
	{id:'joe-rocket-riding-gear',jsonPath:'filters/brands/joe-rocket.json'},
	{id:'k-and-n',jsonPath:'filters/brands/k-and-n.json'},
	{id:'msr',jsonPath:'filters/brands/msr.json'},
	{id:'nolan-helmets',jsonPath:'filters/brands/nolan-helmets.json'},
	{id:'olympia-gloves',jsonPath:'filters/brands/olympia-gloves.json'},
	{id:'onguard-locks',jsonPath:'filters/brands/onguard-locks.json'},
	{id:'progressive-suspension',jsonPath:'filters/brands/progressive-suspension.json'},
	{id:'progrip-grips',jsonPath:'filters/brands/progrip-grips.json'},
	{id:'racepro',jsonPath:'filters/brands/racepro.json'},
	{id:'rk-motorcycle-chain',jsonPath:'filters/brands/rk-motorcycle-chain.json'},
	{id:'vortex-chain-and-sprocket-kits',jsonPath:'filters/brands/vortex-chain-and-sprocket-kits.json'},
	{id:'shoei-helmets',jsonPath:'filters/brands/shoei-helmets.json'},
	{id:'skidlid-helmets',jsonPath:'filters/brands/skidlid-helmets.json'},
	{id:'speed-and-strength',jsonPath:'filters/brands/speed-and-strength.json'},
	{id:'suomy-helmets',jsonPath:'filters/brands/suomy-helmets.json'},
	{id:'thh-helmets',jsonPath:'filters/brands/thh-helmets.json'},
	{id:'yuasa-batteries',jsonPath:'filters/brands/yuasa-batteries.json'}
	];
for(var i in brandsPages){	
	_app.couple('store_filter','addPage',brandsPages[i]);
	}


_app.rq.push(['script',0,'lightbox/js/lightbox-2.6.min.js']);

_app.model.getGrammar("pegjs");


//Any code that needs to be executed after the app init has occured can go here.
//will pass in the page info object. (pageType, templateID, pid/navcat/show and more)
_app.u.appInitComplete = function()	{
//	_app.u.dump("Executing _appIsLoaded code...");
	
	_app.ext.order_create.checkoutCompletes.push(function(vars,$checkout){
		dump(" -> begin checkoutCOmpletes code: "); dump(vars);
		
		var cartContentsAsLinks = encodeURIComponent(_app.ext.cco.u.cartContentsAsLinks(_app.data[vars.datapointer].order));
	
		
//append this to 
		$("[data-app-role='thirdPartyContainer']",$checkout).append("<h2>What next?</h2><div class='ocm ocmFacebookComment pointer zlink marginBottom checkoutSprite  '></div><div class='ocm ocmTwitterComment pointer zlink marginBottom checkoutSprit ' ></div><div class='ocm ocmContinue pointer zlink marginBottom checkoutSprite'></div>");
		$('.ocmTwitterComment',$checkout).click(function(){
			window.open('http://twitter.com/home?status='+cartContentsAsLinks,'twitter');
			window[_app.vars.analyticsPointer]('send', 'event','Checkout','User Event','Tweeted about order');
			window[_app.vars.analyticsPointer]('send', 'event','Checkout','User Event','Tweeted about order');
			});
		//the fb code only works if an appID is set, so don't show banner if not present.				
		if(_app.u.thisNestedExists("zGlobals.thirdParty.facebook.appId") && typeof FB == 'object')	{
			$('.ocmFacebookComment',$checkout).click(function(){
				_app.ext.quickstart.thirdParty.fb.postToWall(cartContentsAsLinks);
				ga('send','event','Checkout','User Event','FB message about order');
				window[_app.vars.analyticsPointer]('send', 'event','Checkout','User Event','FB message about order');
				});
			}
		else	{$('.ocmFacebookComment').hide()}
		});
	
	//Cart Messaging Responses.
	_app.cmr.push(['chat.join',function(message){
		if(message.FROM == 'ADMIN')	{
			var $ui = _app.ext.quickstart.a.showBuyerCMUI();
			$("[data-app-role='messageInput']",$ui).show();
			$("[data-app-role='messageHistory']",$ui).append("<p class='chat_join'>"+message.FROM+" has joined the chat.<\/p>");
			$('.show4ActiveChat',$ui).show();
			$('.hide4ActiveChat',$ui).hide();
			}
		}]);

	_app.cmr.push(['goto',function(message,$context){
		var $history = $("[data-app-role='messageHistory']",$context);
		$P = $("<P>")
			.addClass('chat_post')
			.append("<span class='from'>"+message.FROM+"<\/span> has sent over a "+(message.vars.pageType || "")+" link for you within this store. <span class='lookLikeLink'>Click here<\/span> to view.")
			.on('click',function(){
				showContent(_app.ext.quickstart.u.whatAmIFor(message.vars),message.vars);
				});
		$history.append($P);
		$history.parent().scrollTop($history.height());
		}]);

	}





//this will trigger the content to load on app init. so if you push refresh, you don't get a blank page.
//it'll also handle the old 'meta' uri params.
//this will trigger the content to load on app init. so if you push refresh, you don't get a blank page.
//it'll also handle the old 'meta' uri params.
_app.router.appendInit({
	'type':'function',
	'route': function(v){
		return {'init':true} //returning anything but false triggers a match.
		},
	'callback':function(f,g){
		$('#clickBlocker').remove();
		dump(" -> triggered callback for appendInit");
		g = g || {};
		var $existingPage = $('#mainContentArea [data-app-uri]');
		if($existingPage.length /*&& $existingPage.attr('data-app-uri') == document.location.pathname*/){
			//We are a transplanted document, let's load accordingly.
			//re-attach template handlers
			var $renderedTemplate = $('[data-templateid]', $existingPage);
			var templateid = $renderedTemplate.attr('data-templateid');
			for(var i in _app.templateEvents){
				var event = _app.templateEvents[i];
				if(event.filterFunc(templateid)){
					dump("Attaching event");
					dump(event);
					$renderedTemplate.on(event.event, event.handler);
					}
				}
			//handleURIChange here will not change the page, but it will execute appropriate events
			//that's why we pass false for the windowHistoryAction- no pushstate
			_app.router.handleURIString($existingPage.attr('data-app-uri'), false, {"retrigger" : true});
			}
		else if (document.location.hash.indexOf("#!") == 0){
			var pathStr = document.location.hash.substr(2);
			var search = false;
			if(pathStr.indexOf('?') >= 0){
				var arr = pathStr.split('?');
				pathStr = arr[0];
				search = '?'+arr[1];
				}
			_app.router.handleURIChange("/"+pathStr, search, false, 'replace');
			}
		else if(document.location.protocol == "file:"){
			_app.router.handleURIChange("/", document.location.search, document.location.hash, 'replace');
			}
		else if (g.uriParams.marketplace){
			_app.router.handleURIString('/product/'+g.uriParams.product+'/', 'replace');
			window[_app.vars.analyticsPointer]('send','event','Arrival','Syndication','product '+g.uriParams.product);
			}
		else if(document.location.pathname)	{	
			_app.u.dump('triggering handleHash');
			_app.router.handleURIChange(document.location.pathname, document.location.search, document.location.hash, 'replace');
			}
		else	{
			_app.router.handleURIChange("/", document.location.search, document.location.hash, 'replace');
			_app.u.throwMessage(_app.u.successMsgObject("We're sorry, the page you requested could not be found!"));
			window[_app.vars.analyticsPointer]('send', 'event','init','404 event',document.location.href);
			}
		if(g.uriParams && g.uriParams.meta)	{
			_app.require('cco', function(){
				_app.ext.cco.calls.cartSet.init({'want/refer':g.uriParams.meta,'cartID':_app.model.fetchCartID()},{},'passive');
				});
			}
		if(g.uriParams && g.uriParams.meta_src)	{
			_app.require('cco',function(){
				_app.ext.cco.calls.cartSet.init({'want/refer_src':g.uriParams.meta_src,'cartID':_app.model.fetchCartID()},{},'passive');
				});
			}
		}
	});

_app.u.bindTemplateEvent(function(){return true;},'complete.analyticssetup',function(event, $context, infoObj){
	if(!_app.vars.analyticsFirstPageSent){
		_app.vars.analyticsFirstPageSent = true;
		}
	else{
		var url = $context.closest('[data-app-uri]').attr('data-app-uri');
		if(url)	{window[_app.vars.analyticsPointer]('send','pageview', url);}
		else	{window[_app.vars.analyticsPointer]('send','pageview');}
		}
	});


})(myApp);