PageSourceSearch

https://static.lepaysdauge.org/assets/components/simplecartJS/simpleCart.min.js

js lepaysdauge.org collected 2026-09-25 00:23:14 UTC 38,473 bytes, 1,393 lines download raw bytes

1/****************************************************************************
2Copyright (c) 2011 The Wojo Group
3
4thewojogroup.com
5simplecartjs.com
6http://github.com/thewojogroup/simplecart-js/tree/master
7
8The MIT License
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in
18all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26THE SOFTWARE.
27****************************************************************************/
28
29var Custom="Custom",GoogleCheckout="GoogleCheckout",PayPal="PayPal",Email="Email",AustralianDollar="AUD",AUD="AUD",CanadianDollar="CAD",CAD="CAD",CzechKoruna="CZK",CZK="CZK",DanishKrone="DKK",DKK="DKK",Euro="EUR",EUR="EUR",HongKongDollar="HKD",HKD="HKD",HungarianForint="HUF",HUF="HUF",IsraeliNewSheqel="ILS",ILS="ILS",JapaneseYen="JPY",JPY="JPY",MexicanPeso="MXN",MXN="MXN",NorwegianKrone="NOK",NOK="NOK",NewZealandDollar="NZD",NZD="NZD",PolishZloty="PLN",PLN="PLN",PoundSterling="GBP",GBP="GBP",SingaporeDollar="SGD",SGD="SGD",SwedishKrona="SEK",SEK="SEK",SwissFranc="CHF",CHF="CHF",ThaiBaht="THB",THB="THB",USDollar="USD",USD="USD";
30function Cart(){
31
32	var me = this;
33	/* member variables */
34	me.nextId = 1;
35	me.Version = '2.2.2';
36	me.Shelf = null;
37	me.items = {};
38	me.isLoaded = false;
39	me.pageIsReady = false;
40	me.quantity = 0;
41	me.total = 0;
42	me.taxRate = 0;
43	me.taxCost = 0;
44	me.shippingFlatRate = 0;
45	me.shippingTotalRate = 0;
46	me.shippingQuantityRate = 0;
47	me.shippingRate = 0;
48	me.shippingCost = 0;
49	me.currency = USD;
50	me.checkoutTo = PayPal;
51	me.email = "";
52	me.merchantId	 = "";
53	me.successUrl = null;
54	me.cancelUrl = null;
55	me.cookieDuration = 30; // default duration in days
56	me.storagePrefix = "sc_";
57	me.MAX_COOKIE_SIZE = 4000;
58	me.cartHeaders = ['Name','Price','Quantity','Total'];
59	me.events = {};
60	me.sandbox = false;
61	me.paypalHTTPMethod = "GET";
62	/*
63		cart headers:
64		you can set these to which ever order you would like, and the cart will display the appropriate headers
65		and item info.	any field you have for the items in the cart can be used, and 'Total' will automatically
66		be price*quantity.
67
68		there are keywords that can be used:
69
70			1) "_input" - the field will be a text input with the value set to the given field. when the user
71				changes the value, it will update the cart.	 this can be useful for quantity. (ie "Quantity_input")
72
73			2) "increment" - a link with "+" that will increase the item quantity by 1
74
75			3) "decrement" - a link with "-" that will decrease the item quantity by 1
76
77			4) "remove" - a link that will remove the item from the cart
78
79			5) "_image" or "Image" - the field will be an img tag with the src set to the value. You can simply use "Image" if
80				you set a field in the items called "Image".  If you have a field named something else, like "Thumb", you can add
81				the "_image" to create the image tag (ie "Thumb_image").
82
83			6) "_noHeader" - this will skip the header for that field (ie "increment_noHeader")
84
85
86	*/
87
88
89
90
91	/******************************************************
92			add/remove items to cart
93	 ******************************************************/
94
95	me.add = function ( values ) {
96		var me=this;
97		/* load cart values if not already loaded */
98		if( !me.pageIsReady		) {
99			me.initializeView();
100			me.update();
101		}
102		if( !me.isLoaded		) {
103			me.load();
104			me.update();
105		}
106
107		var newItem = new CartItem();
108
109		/* check to ensure arguments have been passed in */
110		if( !arguments || arguments.length === 0 ){
111			error( 'No values passed for item.');
112			return null;
113		}
114		var argumentArray = arguments;
115		if( values && typeof( values ) !== 'string' && typeof( values ) !== 'number'  ){
116			argumentArray = values;
117		}
118
119		newItem.parseValuesFromArray( argumentArray );
120		newItem.checkQuantityAndPrice();
121		
122		if( me.trigger('beforeAdd', [newItem] ) === false ){
123			return false;
124		}
125		var isNew = true;
126
127		/* if the item already exists, update the quantity */
128		if( me.hasItem(newItem) ) {
129			var foundItem=me.hasItem(newItem);
130			foundItem.quantity= parseInt(foundItem.quantity,10) + parseInt(newItem.quantity,10);
131			newItem = foundItem;
132			isNew = false;
133		} else {
134			me.items[newItem.id] = newItem;
135		}
136
137		me.update();
138		me.trigger('afterAdd', [newItem,isNew] );
139		
140		return newItem;
141		
142	};
143
144
145	me.remove = function( id ){
146		var tempArray = {};
147			
148		me.each(function(item){
149			if( item.id !== id ){
150				tempArray[item.id] = item;
151			}
152		});
153		this.items = tempArray;
154	};
155
156	me.empty = function () {
157		me.items = {};
158		me.update();
159	};
160
161	/******************************************************
162			 item accessor functions
163	 ******************************************************/
164
165	me.find = function (criteria) {
166		if( !criteria ){
167			return null;
168		}
169		
170		var results = [];
171			
172		me.each(function(item,x,next){ 	
173	
174			fits = true;
175		
176			me.each( criteria , function(value,j,name){
177				if( !item[name] || item[name] != value ){
178					fits = false;
179				}
180			});
181			
182			if( fits ){
183				results.push( item );
184			}
185		});
186		return (results.length === 0 ) ? null : results;
187	};
188	
189	
190	me.each = function( array , callback ){
191		var next,
192			x=0, 
193			result;
194
195		if( typeof array === 'function' ){
196			var cb = array
197				items = me.items;
198		} else if( typeof callback === 'function' ){
199			var cb = callback,
200				items = array;
201		} else {
202			return;
203		}
204		
205		for( next in items ){
206			if( typeof items[next] !== "function" ){
207				result = cb.call( me , items[next] , x , next );
208				if( result === false ){
209					return;
210				}
211				x++;
212			}
213		}
214		
215	};
216	
217	
218	me.chunk = function(str, n) {
219		if (typeof n==='undefined'){ 
220			n=2;
221		}
222		var result = str.match(RegExp('.{1,'+n+'}','g'));
223		return result || [];
224	};
225
226
227	/******************************************************
228			 checkout management
229	 ******************************************************/
230
231	me.checkout = function() {
232		if( me.quantity === 0 ){
233			error("Cart is empty");
234			return;
235		}
236		switch( me.checkoutTo ){
237			case PayPal:
238				me.paypalCheckout();
239				break;
240			case GoogleCheckout:
241				me.googleCheckout();
242				break;
243			case Email:
244				me.emailCheckout();
245				break;
246			default:
247				me.customCheckout();
248				break;
249		}
250	};
251
252	me.paypalCheckout = function() {
253
254		
255		var form = document.createElement("form"),
256			counter=1,
257			current,
258			item,
259			descriptionString;
260			
261		form.style.display = "none";
262		form.method = me.paypalHTTPMethod =="GET" || me.paypalHTTPMethod == "POST" ? me.paypalHTTPMethod : "GET";
263		form.action = me.sandbox ? "https://www.sandbox.paypal.com/cgi-bin/webscr" : "https://www.paypal.com/cgi-bin/webscr";
264		form.acceptCharset = "utf-8";
265			
266			
267		// setup hidden fields
268		form.appendChild(me.createHiddenElement("cmd", "_cart"));
269		form.appendChild(me.createHiddenElement("rm", me.paypalHTTPMethod == "POST" ? "2" : "0" ));
270		form.appendChild(me.createHiddenElement("upload", "1"));
271		form.appendChild(me.createHiddenElement("business", me.email ));
272		form.appendChild(me.createHiddenElement("currency_code", "me.currency"));
273		
274		if( me.taxRate ){
275			form.appendChild(me.createHiddenElement("tax_cart",me.taxCost ));
276		}
277		
278		if( me.shipping() !== 0){
279			form.appendChild(me.createHiddenElement("handling_cart",  me.shippingCost ));
280		}
281		
282		if( me.successUrl ){
283			form.appendChild(me.createHiddenElement("return",  me.successUrl ));
284		}
285		
286		if( me.cancelUrl ){
287			form.appendChild(me.createHiddenElement("cancel_return",  me.cancelUrl ));
288		}
289		
290		
291
292		me.each(function(item,iter){
293
294			counter = iter+1;
295		
296			form.appendChild( me.createHiddenElement( "item_name_"		+ counter, item.name		) );
297			form.appendChild( me.createHiddenElement( "quantity_"		+ counter, item.quantity	) );
298			form.appendChild( me.createHiddenElement( "amount_"			+ counter, item.price		) );
299			form.appendChild( me.createHiddenElement( "item_number_"	+ counter, counter			) );
300			
301			var option_count = 0;
302
303			me.each( item , function( value, x , field ){
304				if( field !== "id" && field !== "price" && field !== "quantity" && field !== "name" && field !== "shipping" && option_count < 10) {
305					form.appendChild( me.createHiddenElement( "on" + option_count + "_"	+ counter, 	field ) );
306					form.appendChild( me.createHiddenElement( "os" + option_count + "_"	+ counter, 	value ) );
307					option_count++;
308				}
309			});
310
311			form.appendChild( me.createHiddenElement( "option_index_" + counter, option_count) );
312
313		});
314
315
316		document.body.appendChild( form );
317		form.submit();
318		document.body.removeChild( form );
319		
320	};
321
322	me.googleCheckout = function() {
323		var me = this;
324		
325		
326		if( me.currency !== USD && me.currency !== GBP ){
327			error( "Google Checkout only allows the USD and GBP for currency.");
328			return;
329		} else if( me.merchantId === "" || me.merchantId === null || !me.merchantId ){
330			error( "No merchant Id for google checkout supplied.");
331			return;
332		}
333
334		var form = document.createElement("form"),
335			counter=1,
336			current,
337			item,
338			descriptionString;
339			
340		form.style.display = "none";
341		form.method = "POST";
342		form.action = "https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/" +
343						me.merchantId;
344		form.acceptCharset = "utf-8";
345
346		me.each(function(item,iter){
347				
348			counter = iter+1;
349		
350			form.appendChild( me.createHiddenElement( "item_name_"		+ counter, item.name		) );
351			form.appendChild( me.createHiddenElement( "item_quantity_"	+ counter, item.quantity	) );
352			form.appendChild( me.createHiddenElement( "item_price_"		+ counter, item.price		) );
353			form.appendChild( me.createHiddenElement( "item_currency_"	+ counter, me.currency		) );
354			form.appendChild( me.createHiddenElement( "item_tax_rate_"	+ counter, me.taxRate		) );
355			form.appendChild( me.createHiddenElement( "_charset_"				 , ""				) );
356
357			descriptionString = "";
358
359			me.each( item , function( value , x , field ){
360			
361				if( field !== "id"		&&
362					field !== "quantity" &&
363					field !== "price" ) {
364						
365						descriptionString = descriptionString + ", " + field + ": " + value;
366				}
367			});
368			
369			descriptionString = descriptionString.substring( 1 );
370			form.appendChild( me.createHiddenElement( "item_description_" + counter, descriptionString) );
371
372		});
373		
374		// hack for adding shipping
375		if( me.shipping() !== 0){
376		   form.appendChild(me.createHiddenElement("ship_method_name_1", "Shipping"));
377		   form.appendChild(me.createHiddenElement("ship_method_price_1", parseFloat(me.shippingCost).toFixed(2)));
378		   form.appendChild(me.createHiddenElement("ship_method_currency_1", me.currency));
379		}
380
381		document.body.appendChild( form );
382		form.submit();
383		document.body.removeChild( form );
384	};
385
386
387
388	me.emailCheckout = function() {
389		return;
390	};
391
392	me.customCheckout = function() {
393		var me = this;
394		
395
396		var form = document.createElement("form"),
397			counter=1,
398			current,
399			item,
400			descriptionString;
401			
402		form.style.display = "none";
403		form.method = "POST";
404		form.action = me.checkoutUrl;
405		
406		form.acceptCharset = "utf-8";
407
408
409		form.appendChild( me.createHiddenElement( "actualiser", 1		) );
410
411
412                me.each(function(item,iter){
413				
414			counter = iter+1;
415
416
417			form.appendChild( me.createHiddenElement( "item["+counter+"][itemCode]", item.code		) );
418			form.appendChild( me.createHiddenElement( "item["+counter+"][itemLibelle]", item.name		) );
419			form.appendChild( me.createHiddenElement( "item["+counter+"][itemQuantite]", item.quantity		) );
420			form.appendChild( me.createHiddenElement( "item["+counter+"][itemPrixTotal]", item.price * item.quantity) );
421			form.appendChild( me.createHiddenElement( "item["+counter+"][itemPortTotal]", item.shipping * item.quantity	) );
422			form.appendChild( me.createHiddenElement( "item["+counter+"][itemImage]", item.image	) );
423			form.appendChild( me.createHiddenElement( "item["+counter+"][itemPrixUnitaire]", item.price	) );
424			form.appendChild( me.createHiddenElement( "item["+counter+"][itemPortUnitaire]", item.shipping	) );
425			form.appendChild( me.createHiddenElement( "item["+counter+"][itemTVA]", item.tva	) );
426			form.appendChild( me.createHiddenElement( "item["+counter+"][itemTVAPort]", item.tvaport	) );
427
428
429			//form.appendChild( me.createHiddenElement( "item_currency_"	+ counter, me.currency		) );
430			//form.appendChild( me.createHiddenElement( "item_tax_rate_"	+ counter, me.taxRate		) );
431			//form.appendChild( me.createHiddenElement( "_charset_"				 , ""				) );
432
433		});
434		
435
436		document.body.appendChild( form );
437		form.submit();
438		document.body.removeChild( form );
439	};
440
441
442
443
444	/******************************************************
445				data storage and retrival
446	 ******************************************************/
447
448	/* load cart from cookie */
449	me.load = function () {
450		var me = this,
451			id;
452			
453		/* initialize variables and items array */
454		me.items = {};
455		me.total = 0.00;
456		me.quantity = 0;
457
458		/* retrieve item data from cookie */
459		if( readCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks") ){
460			var chunkCount = 1*readCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks"),
461				dataArray = [],
462				dataString = "",
463				data = "",
464				info,
465				newItem,
466				y=0;
467			if(chunkCount>0) {	
468				for( y=0;y<chunkCount;y++){
469					dataArray.push( readCookie( simpleCart.storagePrefix + 'simpleCart_' + (1 + y ) ) );
470				}
471			
472				dataString = unescape( dataArray.join("") );
473				data = dataString.split("++");
474			}
475			for(var x=0, xlen=data.length;x<xlen;x++){
476
477				info = data[x].split('||');
478				newItem = new CartItem();
479
480				if( newItem.parseValuesFromArray( info ) ){
481					newItem.checkQuantityAndPrice();
482					/* store the new item in the cart */
483					me.items[newItem.id] = newItem;
484				}
485			}
486		}
487	
488		me.isLoaded = true;
489	};
490
491
492
493	/* save cart to cookie */
494	me.save = function () {
495		var dataString = "",
496			dataArray = [],
497			chunkCount = 0;
498			
499		chunkCount = 1*readCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks");
500		for( var j=0;j<chunkCount;j++){
501			eraseCookie(simpleCart.storagePrefix + 'simpleCart_'+ j);
502		}
503		eraseCookie(simpleCart.storagePrefix + 'simpleCart_' + "chunks");
504		
505			
506		me.each(function(item){
507			dataString = dataString + "++" + item.print();
508		});
509		
510		dataArray = simpleCart.chunk( dataString.substring(2) , simpleCart.MAX_COOKIE_SIZE );
511		
512		for( var x=0,xlen = dataArray.length;x<xlen;x++){
513			createCookie(simpleCart.storagePrefix + 'simpleCart_' + (1 + x ), dataArray[x], me.cookieDuration );
514		}
515				
516		createCookie( simpleCart.storagePrefix + 'simpleCart_' + "chunks", "" + dataArray.length , me.cookieDuration );
517	};
518
519
520
521	/******************************************************
522				 view management
523	 ******************************************************/
524
525	me.initializeView = function() {
526		var me = this;
527		me.totalOutlets				= getElementsByClassName('simpleCart_total');
528		me.quantityOutlets			= getElementsByClassName('simpleCart_quantity');
529		me.cartDivs					= getElementsByClassName('simpleCart_items');
530		me.taxCostOutlets			= getElementsByClassName('simpleCart_taxCost');
531		me.taxRateOutlets			= getElementsByClassName('simpleCart_taxRate');
532		me.shippingCostOutlets		= getElementsByClassName('simpleCart_shippingCost');
533		me.finalTotalOutlets		= getElementsByClassName('simpleCart_finalTotal');
534
535		me.addEventToArray( getElementsByClassName('simpleCart_checkout') , simpleCart.checkout , "click");
536		me.addEventToArray( getElementsByClassName('simpleCart_empty')	, simpleCart.empty , "click" );
537		
538		me.Shelf = new Shelf();
539		me.Shelf.readPage();
540
541		me.pageIsReady = true;
542
543	};
544
545
546
547	me.updateView = function() {
548		me.updateViewTotals();
549		if( me.cartDivs && me.cartDivs.length > 0 ){
550			me.updateCartView();
551		}
552	};
553
554	me.updateViewTotals = function() {
555		var outlets = [ ["quantity"		, "none"		] ,
556						["total"		, "currency"	] ,
557						["shippingCost" , "currency"	] ,
558						["taxCost"		, "currency"	] ,
559						["taxRate"		, "percentage"	] ,
560						["finalTotal"	, "currency"	] ];
561
562		for( var x=0,xlen=outlets.length; x<xlen;x++){
563
564			var arrayName = outlets[x][0] + "Outlets",
565				outputString,
566				element;
567
568			for( var y = 0,ylen = me[ arrayName ].length; y<ylen; y++ ){ 
569				switch( outlets[x][1] ){
570					case "none":
571						outputString = "" + me[outlets[x][0]];
572						break;
573					case "currency":
574						outputString = me.valueToCurrencyString( me[outlets[x][0]] );
575						break;
576					case "percentage":
577						outputString = me.valueToPercentageString( me[outlets[x][0]] );
578						break;
579					default:
580						outputString = "" + me[outlets[x][0]];
581						break;
582				}
583				me[arrayName][y].innerHTML = "" + outputString;
584			}
585		}
586	};
587
588	me.updateCartView = function() {
589		var newRows = [],
590			y,newRow,current,header,newCell,info,outputValue,option,headerInfo;
591
592		/* create headers row */
593		newRow = document.createElement('div');
594		for(var y=0,ylen = me.cartHeaders.length; y<ylen; y++ ){
595			newCell = document.createElement('div');
596			headerInfo = me.cartHeaders[y].split("_");
597
598			newCell.innerHTML = me.print( headerInfo[0] );
599			newCell.className = "item" + headerInfo[0];
600			for(var z=1,zlen=headerInfo.length;z<zlen;z++){
601				if( headerInfo[z].toLowerCase() == "noheader" ){
602					newCell.style.display = "none";
603				}
604			}
605			newRow.appendChild( newCell );
606
607		}
608		newRow.className = "cartHeaders";
609		newRows[0] = newRow;
610
611		/* create a row for each item in the cart */
612		me.each(function(item, x){
613			newRow = document.createElement('div');
614
615			for(var y=0,ylen = me.cartHeaders.length; y<ylen; y++ ){
616				newCell = document.createElement('div');
617				info = me.cartHeaders[y].split("_");
618			
619				outputValue = me.createCartRow( info , item , outputValue );
620
621				newCell.innerHTML = outputValue;
622				newCell.className = "item" + info[0];
623			
624				newRow.appendChild( newCell );
625			}
626			newRow.className = "itemContainer";
627			newRows[x+1] = newRow;
628		});
629
630
631
632		for( var x=0,xlen=me.cartDivs.length; x<xlen; x++){
633
634			/* delete current rows in div */
635			var div = me.cartDivs[x];
636			if( div.childNodes && div.appendChild ){
637				while( div.childNodes[0] ){
638					div.removeChild( div.childNodes[0] );
639				}
640			
641
642				for(var j=0, jLen = newRows.length; j<jLen; j++){
643					div.appendChild( newRows[j] );
644				}
645			}
646
647		}
648	};
649	
650	me.createCartRow = function( info , item , outputValue ){
651				
652		switch( info[0].toLowerCase() ){
653			case "total":
654				outputValue = me.valueToCurrencyString(parseFloat(item.price)*parseInt(item.quantity,10) );
655				break;
656			case "increment":
657				outputValue = me.valueToLink( "+" , "javascript:;" , "onclick=\"simpleCart.items[\'" + item.id + "\'].increment();\"" );
658				break;
659			case "decrement":
660				outputValue = me.valueToLink( "-" , "javascript:;" , "onclick=\"simpleCart.items[\'" + item.id + "\'].decrement();\"" );
661				break;
662			case "remove":
663				outputValue = me.valueToLink( "Retirer" , "javascript:;" , "onclick=\"simpleCart.items[\'" + item.id + "\'].remove();\"" );
664				break;
665			case "price":
666				outputValue = me.valueToCurrencyString( item[ info[0].toLowerCase() ] ? item[info[0].toLowerCase()] : " " );
667				break;
668			default: 
669				outputValue = item[ info[0].toLowerCase() ] ? 
670							typeof 	item[info[0].toLowerCase()] === 'function' ?
671							 		item[info[0].toLowerCase()].call(item) :
672									item[info[0].toLowerCase()] :
673									" ";
674				break;
675		}	
676		
677		for( var y=1,ylen=info.length;y<ylen;y++){
678			option = info[y].toLowerCase();
679			switch( option ){
680				case "image":
681				case "img":
682					outputValue = me.valueToImageString( item.image );
683					break;
684				case "input":
685					outputValue = me.valueToTextInput( outputValue , "onchange=\"simpleCart.items[\'" + item.id + "\'].set(\'" + info[0].toLowerCase() + "\' , this.value);\""	);
686					break;
687				case "div":
688				case "span":
689				case "h1":
690				case "h2":
691				case "h3":
692				case "h4":
693				case "p":
694					outputValue = me.valueToElement( option , outputValue , "" );
695					break;
696				case "noheader":
697					break;
698				default:
699					error( "unkown header option: " + option );
700					break;
701			}
702		
703		}		  
704		return outputValue;
705	};
706
707	me.addEventToArray = function ( array , functionCall , theEvent ) {
708		var outlet, 
709			element;
710		
711		for(var x=0,xlen=array.length; x<xlen; x++ ){
712			element = array[x];
713			if( element.addEventListener ) {
714				element.addEventListener(theEvent, functionCall , false );
715			} else if( element.attachEvent ) {
716				element.attachEvent( "on" + theEvent, functionCall );
717			}
718		}
719	};
720
721
722	me.createHiddenElement = function ( name , value ){
723		var element = document.createElement("input");
724		element.type = "hidden";
725		element.name = name;
726		element.value = value;
727		return element;
728	};
729
730
731	/******************************************************
732			Event Management
733	 ******************************************************/
734	
735	// bind a callback to a simpleCart event
736	me.bind = function( name , callback ){
737		if( typeof callback !== 'function' ){
738			return me;
739		}
740		
741		
742		if (me.events[name] === true ){
743			callback.apply( me );
744		} else if( typeof me.events[name] !== 'undefined' ){
745			me.events[name].push( callback );
746		} else {
747			me.events[name] = [ callback ];
748		}
749		return me;
750	};
751	
752	
753	// trigger event
754	me.trigger = function( name , options ){
755		var returnval = true;
756		if( typeof me.events[name] !== 'undefined' && typeof me.events[name][0] === 'function'){
757			for( var x=0,xlen=me.events[name].length; x<xlen; x++ ){
758				returnval = me.events[name][x].apply( me , (options ? options : [] ) );
759			}
760		}
761		if( returnval === false ){
762			return false;
763		} else {
764			return true;
765		}
766	};
767	
768	// shortcut for ready function
769	me.ready = function( callback ){
770		if( !callback ){
771			me.trigger( 'ready' );
772			me.events['ready'] = true;
773		} else {
774			me.bind( 'ready' , callback );
775		}
776		return me;
777	};
778
779
780
781
782	/******************************************************
783				Currency management
784	 ******************************************************/
785
786	me.currencySymbol = function() {
787		switch(me.currency){
788			case CHF:
789				return "CHF&nbsp;";
790			case CZK:
791				return "CZK&nbsp;";
792			case DKK:
793				return "DKK&nbsp;";
794			case HUF:
795				return "HUF&nbsp;";
796			case NOK:
797				return "NOK&nbsp;";
798			case PLN:
799				return "PLN&nbsp;";
800			case SEK:
801				return "SEK&nbsp;";
802			case JPY:
803				return "&yen;";
804			case EUR:
805				return "&euro;";
806			case GBP:
807				return "&pound;";
808			case CHF:
809				return "CHF&nbsp;";
810			case THB: 
811				return "&#3647;";
812			case USD:
813			case CAD:
814			case AUD:
815			case NZD:
816			case HKD:
817			case SGD:
818				return "&#36;";
819			default:
820				return "";
821		}
822	};
823
824
825	me.currencyStringForPaypalCheckout = function( value ){
826		if( me.currencySymbol() == "&#36;" ){
827			return "$" + parseFloat( value ).toFixed(2);
828		} else {
829			return "" + parseFloat(value ).toFixed(2);
830		}
831	};
832
833	/******************************************************
834				Formatting
835	 ******************************************************/
836
837
838	me.valueToCurrencyString = function( value ) {
839		var val =  parseFloat( value ); 
840		if( isNaN(val))
841			val = 0;
842
843		return val.toCurrency( me.currencySymbol() );
844	};
845
846	me.valueToPercentageString = function( value ){
847		return parseFloat( 100*value ) + "%";
848	};
849
850	me.valueToImageString = function( value ){
851		if( value.match(/<\s*img.*src\=/) ){
852			return value;
853		} else {
854			return "<img src=\"" + value + "\" />";
855		}
856	};
857
858	me.valueToTextInput = function( value , html ){
859		return "<input type=\"text\" value=\"" + value + "\" " + html + " />";
860	};
861
862	me.valueToLink = function( value, link, html){
863		return "<a href=\"" + link + "\" " + html + " >" + value + "</a>";
864	};
865
866	me.valueToElement = function( type , value , html ){
867		return "<" + type + " " + html + " > " + value + "</" + type + ">";
868	};
869
870	/******************************************************
871				Duplicate management
872	 ******************************************************/
873
874	me.hasItem = function ( item ) {
875		var current, 
876			matches,
877			field,
878			match=false;
879		
880		me.each(function(testItem){ 
881			
882			matches = true;
883			
884			me.each( item , function( value , x , field ){ 
885				
886				if( field !== "quantity" && field !== "id" && item[field] !== testItem[field] ){
887					matches = false;
888				}
889			});
890			
891			if( matches ){
892				match = testItem;
893			}
894			
895		});
896		return match;
897	};
898	
899	/******************************************************
900				Language managment
901	 ******************************************************/
902	me.ln = {
903		"en_us": {
904			  quantity: "Quantity"
905			, price: "Price"
906			, total: "Total"
907			, decrement: "Decrement"
908			, increment: "Increment"
909			, remove: "Remove"
910			, tax: "Tax"
911			, shipping: "Shipping"
912			, image: "Image"
913		} 
914	};
915	
916	me.language = "en_us"; 
917	
918	me.print = function( input ) {
919		var me = this;
920		return me.ln[me.language] && me.ln[me.language][input.toLowerCase()] ? me.ln[me.language][input.toLowerCase()] : input;
921		
922	};
923
924
925	/******************************************************
926				Cart Update managment
927	 ******************************************************/
928
929	me.update = function() {
930		if( !simpleCart.isLoaded ){
931			simpleCart.load();
932		}
933		if( !simpleCart.pageIsReady ){
934			simpleCart.initializeView();
935		}
936		me.updateTotals();
937		me.updateView();
938		me.save();
939	};
940
941	me.updateTotals = function() {
942			
943		me.total = 0 ;
944		me.quantity	 = 0;
945		me.each(function(item){ 
946			
947			if( item.quantity < 1 ){
948				item.remove();
949			} else if( item.quantity !== null && item.quantity !== "undefined" ){
950				me.quantity = parseInt(me.quantity,10) + parseInt(item.quantity,10);
951			}
952			if( item.price ){
953				me.total = parseFloat(me.total) + parseInt(item.quantity,10)*parseFloat(item.price);
954			}
955			
956		});
957		me.shippingCost = me.shipping();
958		me.taxCost = parseFloat(me.total)*me.taxRate;
959		me.finalTotal = me.shippingCost + me.taxCost + me.total;
960	};
961
962	me.shipping = function(){
963		if( parseInt(me.quantity,10)===0 )
964			return 0;
965		var shipping =	parseFloat(me.shippingFlatRate) +
966						parseFloat(me.shippingTotalRate)*parseFloat(me.total) +
967						parseFloat(me.shippingQuantityRate)*parseInt(me.quantity,10),
968			next;
969		
970		me.each(function(nextItem){ 		
971			if( nextItem.shipping ){
972				if( typeof nextItem.shipping == 'function' ){
973					shipping += parseFloat(nextItem.shipping());
974				} else {
975					shipping += parseFloat(nextItem.shipping);
976				}
977			}
978		});
979
980		return shipping;
981	}
982
983	me.initialize = function() {
984		me.initializeView();
985		me.load();
986		me.update();
987		me.ready();
988	};
989
990}
991
992/********************************************************************************************************
993 *			Cart Item Object
994 ********************************************************************************************************/
995
996function CartItem() {
997	while( simpleCart.items["c" + simpleCart.nextId] )	
998		simpleCart.nextId++;
999		
1000	this.id = "c" + simpleCart.nextId;
1001}
1002
1003
1004CartItem.prototype = {
1005	
1006	set : function ( field , value ){
1007		field = field.toLowerCase();
1008		if( typeof( this[field] ) !== "function" && field !== "id" ){
1009			value = "" + value;
1010			if( field == "quantity"){
1011				value = value.replace( /[^(\d|\.)]*/gi , "" );
1012				value = value.replace(/,*/gi, "");
1013				value = parseInt(value,10);
1014			} else if( field == "price" ){
1015				value = value.replace( /[^(\d|\.)]*/gi, "");
1016				value = value.replace(/,*/gi , "");
1017				value = parseFloat( value );
1018			}
1019			if( typeof(value) == "number" && isNaN( value ) ){
1020				error( "Improperly formatted input.");
1021			} else {
1022				if( typeof( value ) === "string" ){
1023					if( value.match(/\~|\=/) ){
1024						error("Special character ~ or = not allowed: " + value);
1025					}
1026					value = value.replace(/\~|\=/g, "");
1027				}
1028				this[field] = value;
1029				this.checkQuantityAndPrice();
1030			}
1031		} else {
1032			error( "Cannot change " + field + ", this is a reserved field.");
1033		}
1034		simpleCart.update();
1035	},
1036
1037	increment : function(){
1038		this.quantity = parseInt(this.quantity,10) + 1;
1039		simpleCart.update();
1040	},
1041
1042	decrement : function(){
1043		if( parseInt(this.quantity,10) < 2 ){
1044			this.remove();
1045		} else {
1046			this.quantity = parseInt(this.quantity,10) - 1;
1047			simpleCart.update();
1048		}
1049	},
1050
1051	print : function () {
1052		var returnString = '',
1053			field;
1054		simpleCart.each(this ,function(item,x,name){ 	
1055			returnString+= escape(name) + "=" + escape(item) + "||";
1056		});
1057		return returnString.substring(0,returnString.length-2);
1058	},
1059
1060
1061	checkQuantityAndPrice : function() {
1062
1063		if( !this.quantity || this.quantity == null || this.quantity == 'undefined'){ 
1064			this.quantity = 1;
1065			error('No quantity for item.');
1066		} else {
1067			this.quantity = ("" + this.quantity).replace(/,*/gi, "" );
1068			this.quantity = parseInt( ("" + this.quantity).replace( /[^(\d|\.)]*/gi, "") , 10);
1069			if( isNaN(this.quantity) ){
1070				error('Quantity is not a number.');
1071				this.quantity = 1;
1072			}
1073		}
1074
1075		if( !this.price || this.price == null || this.price == 'undefined'){
1076			this.price=0.00;
1077			error('No price for item or price not properly formatted.');
1078		} else {
1079			this.price = ("" + this.price).replace(/,*/gi, "" );
1080			this.price = parseFloat( ("" + this.price).replace( /[^(\d|\.)]*/gi, "") );
1081			if( isNaN(this.price) ){
1082				error('Price is not a number.');
1083				this.price = 0.00;
1084			}
1085		}
1086	},
1087
1088
1089	parseValuesFromArray : function( array ) {
1090		if( array && array.length && array.length > 0) {
1091			for(var x=0, xlen=array.length; x<xlen;x++ ){
1092
1093				/* ensure the pair does not have key delimeters */
1094				array[x] = array[x].replace(/\|\|/g, "| |");
1095				array[x] = array[x].replace(/\+\+/g, "+ +");
1096				if( array[x].match(/\~/) ){
1097					error("Special character ~ not allowed: " + array[x]);
1098				}
1099				array[x] = array[x].replace(/\~/g, "");
1100				
1101
1102				/* split the pair and save the unescaped values to the item */
1103				var value = array[x].split('=');
1104				if( value.length>1 ){
1105					if( value.length>2 ){
1106						for(var j=2, jlen=value.length;j<jlen;j++){
1107							value[1] = value[1] + "=" + value[j];
1108						}
1109					}
1110					this[ unescape(value[0]).toLowerCase() ] = unescape(value[1]);
1111				}
1112			}
1113			return true;
1114		} else {
1115			return false;
1116		}
1117	},
1118
1119	remove : function() {
1120		simpleCart.remove(this.id);
1121		simpleCart.update();
1122	}
1123};
1124
1125
1126
1127/********************************************************************************************************
1128 *			Shelf Object for managing items on shelf that can be added to cart
1129 ********************************************************************************************************/
1130
1131function Shelf(){
1132	this.items = {};
1133}
1134Shelf.prototype = { 
1135		
1136	readPage : function () {
1137		this.items = {};
1138		var newItems = getElementsByClassName( "simpleCart_shelfItem" ),
1139			newItem;
1140			me = this;
1141		
1142		for( var x = 0, xlen = newItems.length; x<xlen; x++){
1143			newItem = new ShelfItem();
1144			me.checkChildren( newItems[x] , newItem );
1145			me.items[newItem.id] = newItem;
1146		}
1147	},
1148
1149	checkChildren : function ( item , newItem) {
1150		if( !item.childNodes )
1151			return;
1152		for(var x=0;item.childNodes[x];x++){
1153
1154			var node = item.childNodes[x];
1155			if( node.className && node.className.match(/item_[^ ]+/) ){
1156
1157				var data = /item_[^ ]+/.exec(node.className)[0].split("_");
1158
1159				if( data[1] == "add" || data[1] == "Add" ){
1160					var tempArray = [];
1161					tempArray.push( node );
1162					var addFunction = simpleCart.Shelf.addToCart(newItem.id);
1163					simpleCart.addEventToArray( tempArray , addFunction , "click");
1164					node.id = newItem.id;
1165				} else {
1166					newItem[data[1]]  = node;
1167				}
1168			}
1169			if( node.childNodes[0] ){
1170				this.checkChildren( node , newItem );
1171			}
1172		}
1173	},
1174
1175	empty : function () {
1176		this.items = {};
1177	},
1178
1179
1180	addToCart : function ( id ) {
1181		return function(){
1182			if( simpleCart.Shelf.items[id]){
1183				simpleCart.Shelf.items[id].addToCart();
1184			} else {
1185				error( "Shelf item with id of " + id + " does not exist.");
1186			}
1187		};
1188	}
1189};
1190
1191
1192/********************************************************************************************************
1193 *			Shelf Item Object
1194 ********************************************************************************************************/
1195
1196
1197function ShelfItem(){
1198	this.id = "s" + simpleCart.nextId++;
1199}
1200
1201ShelfItem.prototype = {
1202	
1203	remove : function () {
1204		simpleCart.Shelf.items[this.id] = null;
1205	},
1206
1207	addToCart : function () {
1208		var outStrings = [],
1209			valueString,
1210			field;
1211			
1212		for( field in this ){
1213			if( typeof( this[field] ) !== "function" && field !== "id" ){
1214				valueString = "";
1215
1216				switch(field){
1217					case "price":
1218						if( this[field].value ){
1219							valueString = this[field].value;
1220						} else if( this[field].innerHTML ) {
1221							valueString = this[field].innerHTML;
1222						}
1223						/* remove all characters from price except digits and a period */
1224						valueString = valueString.replace( /[^(\d|\.)]*/gi , "" );
1225						valueString = valueString.replace( /,*/ , "" );
1226						break;
1227					case "image":
1228						valueString = this[field].src;
1229						break;
1230					default:
1231						if( this[field].value ){
1232							valueString = this[field].value;
1233						} else if( this[field].innerHTML ) {
1234							valueString = this[field].innerHTML;
1235						} else if( this[field].src ){
1236							valueString = this[field].src;
1237						} else {
1238							valueString = this[field];
1239						}
1240						break;
1241				}
1242				outStrings.push( field + "=" + valueString );
1243			}
1244		}
1245
1246		simpleCart.add( outStrings );
1247	}
1248};
1249
1250
1251
1252/********************************************************************************************************
1253 * Thanks to Peter-Paul Koch for these cookie functions (http://www.quirksmode.org/js/cookies.html)
1254 ********************************************************************************************************/
1255function createCookie(name,value,days) {
1256	if (days) {
1257		var date = new Date();
1258		date.setTime(date.getTime()+(days*24*60*60*1000));
1259		var expires = "; expires="+date.toGMTString();
1260	}
1261	else var expires = "";
1262	value = value.replace(/\=/g, '~');
1263	document.cookie = name + "=" + escape(value) + expires + "; path=/";
1264}
1265
1266function readCookie(name) {
1267	var nameEQ = name + "=";
1268	var ca = document.cookie.split(';');
1269	for(var i=0;i < ca.length;i++) {
1270		var c = ca[i];
1271		while (c.charAt(0)==' ') c = c.substring(1,c.length);
1272		if (c.indexOf(nameEQ) === 0){
1273			var value = unescape(c.substring(nameEQ.length, c.length));
1274			return value.replace(/\~/g, '=');
1275		} 
1276	}
1277	return null;
1278}
1279
1280function eraseCookie(name) {
1281	createCookie(name,"",-1);
1282}
1283
1284
1285//*************************************************************************************************
1286/*
1287	Developed by Robert Nyman, http://www.robertnyman.com
1288	Code/licensing: http://code.google.com/p/getelementsbyclassname/
1289*/
1290var getElementsByClassName = function (className, tag, elm){
1291	if (document.getElementsByClassName) {
1292		getElementsByClassName = function (className, tag, elm) {
1293			elm = elm || document;
1294			var elements = elm.getElementsByClassName(className),
1295				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
1296				returnElements = [],
1297				current;
1298			for(var i=0, il=elements.length; i<il; i+=1){
1299				current = elements[i];
1300				if(!nodeName || nodeName.test(current.nodeName)) {
1301					returnElements.push(current);
1302				}
1303			}
1304			return returnElements;
1305		};
1306	}
1307	else if (document.evaluate) {
1308		getElementsByClassName = function (className, tag, elm) {
1309			tag = tag || "*";
1310			elm = elm || document;
1311			var classes = className.split(" "),
1312				classesToCheck = "",
1313				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
1314				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
1315				returnElements = [],
1316				elements,
1317				node;
1318			for(var j=0, jl=classes.length; j<jl; j+=1){
1319				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
1320			}
1321			try {
1322				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
1323			}
1324			catch (e) {
1325				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
1326			}
1327			while ((node = elements.iterateNext())) {
1328				returnElements.push(node);
1329			}
1330			return returnElements;
1331		};
1332	}
1333	else {
1334		getElementsByClassName = function (className, tag, elm) {
1335			tag = tag || "*";
1336			elm = elm || document;
1337			var classes = className.split(" "),
1338				classesToCheck = [],
1339				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
1340				current,
1341				returnElements = [],
1342				match;
1343			for(var k=0, kl=classes.length; k<kl; k+=1){
1344				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
1345			}
1346			for(var l=0, ll=elements.length; l<ll; l+=1){
1347				current = elements[l];
1348				match = false;
1349				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
1350					match = classesToCheck[m].test(current.className);
1351					if (!match) {
1352						break;
1353					}
1354				}
1355				if (match) {
1356					returnElements.push(current);
1357				}
1358			}
1359			return returnElements;
1360		};
1361	}
1362	return getElementsByClassName(className, tag, elm);
1363};
1364
1365
1366/********************************************************************************************************
1367 *	Helpers
1368 ********************************************************************************************************/
1369
1370
1371String.prototype.reverse=function(){return this.split("").reverse().join("");};
1372Number.prototype.withCommas=function(){var x=6,y=parseFloat(this).toFixed(2).toString().reverse();while(x<y.length){y=y.substring(0,x)+","+y.substring(x);x+=4;}return y.reverse();};
1373Number.prototype.toCurrency=function(){return this.withCommas()+(arguments[0]?arguments[0]:"$");};
1374
1375
1376/********************************************************************************************************
1377 * error management
1378 ********************************************************************************************************/
1379
1380function error( message ){
1381	try{
1382		console.log( message );
1383	}catch(err){
1384	//	alert( message );
1385	}
1386}
1387
1388
1389var simpleCart = new Cart();
1390
1391if( typeof jQuery !== 'undefined' ) $(document).ready(function(){simpleCart.initialize();});
1392else if( typeof Prototype !== 'undefined') Event.observe( window, 'load', function(){simpleCart.initialize();});
1393else window.onload = simpleCart.initialize;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.