PageSourceSearch

https://www.cleeks.com/themes/cleeks/js/tools/jquery.slider.js

js cleeks.com collected 2026-09-29 12:10:35 UTC 52,121 bytes, 1,876 lines download raw bytes

1
2/**
3 * Copyright 2010 Tim Down.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/**
19 * jshashtable
20 *
21 * jshashtable is a JavaScript implementation of a hash table. It creates a single constructor function called Hashtable
22 * in the global scope.
23 *
24 * Author: Tim Down <[email protected]>
25 * Version: 2.1
26 * Build date: 21 March 2010
27 * Website: http://www.timdown.co.uk/jshashtable
28 */
29
30var Hashtable = (function() {
31	var FUNCTION = "function";
32
33	var arrayRemoveAt = (typeof Array.prototype.splice == FUNCTION) ?
34		function(arr, idx) {
35			arr.splice(idx, 1);
36		} :
37
38		function(arr, idx) {
39			var itemsAfterDeleted, i, len;
40			if (idx === arr.length - 1) {
41				arr.length = idx;
42			} else {
43				itemsAfterDeleted = arr.slice(idx + 1);
44				arr.length = idx;
45				for (i = 0, len = itemsAfterDeleted.length; i < len; ++i) {
46					arr[idx + i] = itemsAfterDeleted[i];
47				}
48			}
49		};
50
51	function hashObject(obj) {
52		var hashCode;
53		if (typeof obj == "string") {
54			return obj;
55		} else if (typeof obj.hashCode == FUNCTION) {
56			// Check the hashCode method really has returned a string
57			hashCode = obj.hashCode();
58			return (typeof hashCode == "string") ? hashCode : hashObject(hashCode);
59		} else if (typeof obj.toString == FUNCTION) {
60			return obj.toString();
61		} else {
62			try {
63				return String(obj);
64			} catch (ex) {
65				// For host objects (such as ActiveObjects in IE) that have no toString() method and throw an error when
66				// passed to String()
67				return Object.prototype.toString.call(obj);
68			}
69		}
70	}
71
72	function equals_fixedValueHasEquals(fixedValue, variableValue) {
73		return fixedValue.equals(variableValue);
74	}
75
76	function equals_fixedValueNoEquals(fixedValue, variableValue) {
77		return (typeof variableValue.equals == FUNCTION) ?
78			   variableValue.equals(fixedValue) : (fixedValue === variableValue);
79	}
80
81	function createKeyValCheck(kvStr) {
82		return function(kv) {
83			if (kv === null) {
84				throw new Error("null is not a valid " + kvStr);
85			} else if (typeof kv == "undefined") {
86				throw new Error(kvStr + " must not be undefined");
87			}
88		};
89	}
90
91	var checkKey = createKeyValCheck("key"), checkValue = createKeyValCheck("value");
92
93	/*----------------------------------------------------------------------------------------------------------------*/
94
95	function Bucket(hash, firstKey, firstValue, equalityFunction) {
96        this[0] = hash;
97		this.entries = [];
98		this.addEntry(firstKey, firstValue);
99
100		if (equalityFunction !== null) {
101			this.getEqualityFunction = function() {
102				return equalityFunction;
103			};
104		}
105	}
106
107	var EXISTENCE = 0, ENTRY = 1, ENTRY_INDEX_AND_VALUE = 2;
108
109	function createBucketSearcher(mode) {
110		return function(key) {
111			var i = this.entries.length, entry, equals = this.getEqualityFunction(key);
112			while (i--) {
113				entry = this.entries[i];
114				if ( equals(key, entry[0]) ) {
115					switch (mode) {
116						case EXISTENCE:
117							return true;
118						case ENTRY:
119							return entry;
120						case ENTRY_INDEX_AND_VALUE:
121							return [ i, entry[1] ];
122					}
123				}
124			}
125			return false;
126		};
127	}
128
129	function createBucketLister(entryProperty) {
130		return function(aggregatedArr) {
131			var startIndex = aggregatedArr.length;
132			for (var i = 0, len = this.entries.length; i < len; ++i) {
133				aggregatedArr[startIndex + i] = this.entries[i][entryProperty];
134			}
135		};
136	}
137
138	Bucket.prototype = {
139		getEqualityFunction: function(searchValue) {
140			return (typeof searchValue.equals == FUNCTION) ? equals_fixedValueHasEquals : equals_fixedValueNoEquals;
141		},
142
143		getEntryForKey: createBucketSearcher(ENTRY),
144
145		getEntryAndIndexForKey: createBucketSearcher(ENTRY_INDEX_AND_VALUE),
146
147		removeEntryForKey: function(key) {
148			var result = this.getEntryAndIndexForKey(key);
149			if (result) {
150				arrayRemoveAt(this.entries, result[0]);
151				return result[1];
152			}
153			return null;
154		},
155
156		addEntry: function(key, value) {
157			this.entries[this.entries.length] = [key, value];
158		},
159
160		keys: createBucketLister(0),
161
162		values: createBucketLister(1),
163
164		getEntries: function(entries) {
165			var startIndex = entries.length;
166			for (var i = 0, len = this.entries.length; i < len; ++i) {
167				// Clone the entry stored in the bucket before adding to array
168				entries[startIndex + i] = this.entries[i].slice(0);
169			}
170		},
171
172		containsKey: createBucketSearcher(EXISTENCE),
173
174		containsValue: function(value) {
175			var i = this.entries.length;
176			while (i--) {
177				if ( value === this.entries[i][1] ) {
178					return true;
179				}
180			}
181			return false;
182		}
183	};
184
185	/*----------------------------------------------------------------------------------------------------------------*/
186
187	// Supporting functions for searching hashtable buckets
188
189	function searchBuckets(buckets, hash) {
190		var i = buckets.length, bucket;
191		while (i--) {
192			bucket = buckets[i];
193			if (hash === bucket[0]) {
194				return i;
195			}
196		}
197		return null;
198	}
199
200	function getBucketForHash(bucketsByHash, hash) {
201		var bucket = bucketsByHash[hash];
202
203		// Check that this is a genuine bucket and not something inherited from the bucketsByHash's prototype
204		return ( bucket && (bucket instanceof Bucket) ) ? bucket : null;
205	}
206
207	/*----------------------------------------------------------------------------------------------------------------*/
208
209	function Hashtable(hashingFunctionParam, equalityFunctionParam) {
210		var that = this;
211		var buckets = [];
212		var bucketsByHash = {};
213
214		var hashingFunction = (typeof hashingFunctionParam == FUNCTION) ? hashingFunctionParam : hashObject;
215		var equalityFunction = (typeof equalityFunctionParam == FUNCTION) ? equalityFunctionParam : null;
216
217		this.put = function(key, value) {
218			checkKey(key);
219			checkValue(value);
220			var hash = hashingFunction(key), bucket, bucketEntry, oldValue = null;
221
222			// Check if a bucket exists for the bucket key
223			bucket = getBucketForHash(bucketsByHash, hash);
224			if (bucket) {
225				// Check this bucket to see if it already contains this key
226				bucketEntry = bucket.getEntryForKey(key);
227				if (bucketEntry) {
228					// This bucket entry is the current mapping of key to value, so replace old value and we're done.
229					oldValue = bucketEntry[1];
230					bucketEntry[1] = value;
231				} else {
232					// The bucket does not contain an entry for this key, so add one
233					bucket.addEntry(key, value);
234				}
235			} else {
236				// No bucket exists for the key, so create one and put our key/value mapping in
237				bucket = new Bucket(hash, key, value, equalityFunction);
238				buckets[buckets.length] = bucket;
239				bucketsByHash[hash] = bucket;
240			}
241			return oldValue;
242		};
243
244		this.get = function(key) {
245			checkKey(key);
246
247			var hash = hashingFunction(key);
248
249			// Check if a bucket exists for the bucket key
250			var bucket = getBucketForHash(bucketsByHash, hash);
251			if (bucket) {
252				// Check this bucket to see if it contains this key
253				var bucketEntry = bucket.getEntryForKey(key);
254				if (bucketEntry) {
255					// This bucket entry is the current mapping of key to value, so return the value.
256					return bucketEntry[1];
257				}
258			}
259			return null;
260		};
261
262		this.containsKey = function(key) {
263			checkKey(key);
264			var bucketKey = hashingFunction(key);
265
266			// Check if a bucket exists for the bucket key
267			var bucket = getBucketForHash(bucketsByHash, bucketKey);
268
269			return bucket ? bucket.containsKey(key) : false;
270		};
271
272		this.containsValue = function(value) {
273			checkValue(value);
274			var i = buckets.length;
275			while (i--) {
276				if (buckets[i].containsValue(value)) {
277					return true;
278				}
279			}
280			return false;
281		};
282
283		this.clear = function() {
284			buckets.length = 0;
285			bucketsByHash = {};
286		};
287
288		this.isEmpty = function() {
289			return !buckets.length;
290		};
291
292		var createBucketAggregator = function(bucketFuncName) {
293			return function() {
294				var aggregated = [], i = buckets.length;
295				while (i--) {
296					buckets[i][bucketFuncName](aggregated);
297				}
298				return aggregated;
299			};
300		};
301
302		this.keys = createBucketAggregator("keys");
303		this.values = createBucketAggregator("values");
304		this.entries = createBucketAggregator("getEntries");
305
306		this.remove = function(key) {
307			checkKey(key);
308
309			var hash = hashingFunction(key), bucketIndex, oldValue = null;
310
311			// Check if a bucket exists for the bucket key
312			var bucket = getBucketForHash(bucketsByHash, hash);
313
314			if (bucket) {
315				// Remove entry from this bucket for this key
316				oldValue = bucket.removeEntryForKey(key);
317				if (oldValue !== null) {
318					// Entry was removed, so check if bucket is empty
319					if (!bucket.entries.length) {
320						// Bucket is empty, so remove it from the bucket collections
321						bucketIndex = searchBuckets(buckets, hash);
322						arrayRemoveAt(buckets, bucketIndex);
323						delete bucketsByHash[hash];
324					}
325				}
326			}
327			return oldValue;
328		};
329
330		this.size = function() {
331			var total = 0, i = buckets.length;
332			while (i--) {
333				total += buckets[i].entries.length;
334			}
335			return total;
336		};
337
338		this.each = function(callback) {
339			var entries = that.entries(), i = entries.length, entry;
340			while (i--) {
341				entry = entries[i];
342				callback(entry[0], entry[1]);
343			}
344		};
345
346		this.putAll = function(hashtable, conflictCallback) {
347			var entries = hashtable.entries();
348			var entry, key, value, thisValue, i = entries.length;
349			var hasConflictCallback = (typeof conflictCallback == FUNCTION);
350			while (i--) {
351				entry = entries[i];
352				key = entry[0];
353				value = entry[1];
354
355				// Check for a conflict. The default behaviour is to overwrite the value for an existing key
356				if ( hasConflictCallback && (thisValue = that.get(key)) ) {
357					value = conflictCallback(key, thisValue, value);
358				}
359				that.put(key, value);
360			}
361		};
362
363		this.clone = function() {
364			var clone = new Hashtable(hashingFunctionParam, equalityFunctionParam);
365			clone.putAll(that);
366			return clone;
367		};
368	}
369
370	return Hashtable;
371})();
372
373/**
374 * jquery.numberformatter - Formatting/Parsing Numbers in jQuery
375 * 
376 * Written by
377 * Michael Abernethy ([email protected]),
378 * Andrew Parry ([email protected])
379 *
380 * Dual licensed under the MIT (MIT-LICENSE.txt)
381 * and GPL (GPL-LICENSE.txt) licenses.
382 *
383 * @author Michael Abernethy, Andrew Parry
384 * @version 1.2.3-SNAPSHOT ($Id$)
385 * 
386 * Dependencies
387 * 
388 * jQuery (http://jquery.com)
389 * jshashtable (http://www.timdown.co.uk/jshashtable)
390 * 
391 * Notes & Thanks
392 * 
393 * many thanks to advweb.nanasi.jp for his bug fixes
394 * jsHashtable is now used also, so thanks to the author for that excellent little class.
395 *
396 * This plugin can be used to format numbers as text and parse text as Numbers
397 * Because we live in an international world, we cannot assume that everyone
398 * uses "," to divide thousands, and "." as a decimal point.
399 *
400 * As of 1.2 the way this plugin works has changed slightly, parsing text to a number
401 * has 1 set of functions, formatting a number to text has it's own. Before things
402 * were a little confusing, so I wanted to separate the 2 out more.
403 *
404 *
405 * jQuery extension functions:
406 *
407 * formatNumber(options, writeBack, giveReturnValue) - Reads the value from the subject, parses to
408 * a Javascript Number object, then formats back to text using the passed options and write back to
409 * the subject.
410 * 
411 * parseNumber(options) - Parses the value in the subject to a Number object using the passed options
412 * to decipher the actual number from the text, then writes the value as text back to the subject.
413 * 
414 * 
415 * Generic functions:
416 * 
417 * formatNumber(numberString, options) - Takes a plain number as a string (e.g. '1002.0123') and returns
418 * a string of the given format options.
419 * 
420 * parseNumber(numberString, options) - Takes a number as text that is formatted the same as the given
421 * options then and returns it as a plain Number object.
422 * 
423 * To achieve the old way of combining parsing and formatting to keep say a input field always formatted
424 * to a given format after it has lost focus you'd simply use a combination of the functions.
425 * 
426 * e.g.
427 * $("#salary").blur(function(){
428 * 		$(this).parseNumber({format:"#,###.00", locale:"us"});
429 * 		$(this).formatNumber({format:"#,###.00", locale:"us"});
430 * });
431 *
432 * The syntax for the formatting is:
433 * 0 = Digit
434 * # = Digit, zero shows as absent
435 * . = Decimal separator
436 * - = Negative sign
437 * , = Grouping Separator
438 * % = Percent (multiplies the number by 100)
439 * 
440 * For example, a format of "#,###.00" and text of 4500.20 will
441 * display as "4.500,20" with a locale of "de", and "4,500.20" with a locale of "us"
442 *
443 *
444 * As of now, the only acceptable locales are 
445 * Arab Emirates -> "ae"
446 * Australia -> "au"
447 * Austria -> "at"
448 * Brazil -> "br"
449 * Canada -> "ca"
450 * China -> "cn"
451 * Czech -> "cz"
452 * Denmark -> "dk"
453 * Egypt -> "eg"
454 * Finland -> "fi"
455 * France  -> "fr"
456 * Germany -> "de"
457 * Greece -> "gr"
458 * Great Britain -> "gb"
459 * Hong Kong -> "hk"
460 * India -> "in"
461 * Israel -> "il"
462 * Japan -> "jp"
463 * Russia -> "ru"
464 * South Korea -> "kr"
465 * Spain -> "es"
466 * Sweden -> "se"
467 * Switzerland -> "ch"
468 * Taiwan -> "tw"
469 * Thailand -> "th"
470 * United States -> "us"
471 * Vietnam -> "vn"
472 **/
473
474(function(jQuery) {
475
476	var nfLocales = new Hashtable();
477	
478	var nfLocalesLikeUS = [ 'ae','au','ca','cn','eg','gb','hk','il','in','jp','sk','th','tw','us' ];
479	var nfLocalesLikeDE = [ 'at','br','de','dk','es','gr','it','nl','pt','tr','vn' ];
480	var nfLocalesLikeFR = [ 'cz','fi','fr','ru','se','pl' ];
481	var nfLocalesLikeCH = [ 'ch' ];
482	
483	var nfLocaleFormatting = [ [".", ","], [",", "."], [",", " "], [".", "'"] ]; 
484	var nfAllLocales = [ nfLocalesLikeUS, nfLocalesLikeDE, nfLocalesLikeFR, nfLocalesLikeCH ]
485
486	function FormatData(dec, group, neg) {
487		this.dec = dec;
488		this.group = group;
489		this.neg = neg;
490	};
491
492	function init() {
493		// write the arrays into the hashtable
494		for (var localeGroupIdx = 0; localeGroupIdx < nfAllLocales.length; localeGroupIdx++) {
495			localeGroup = nfAllLocales[localeGroupIdx];
496			for (var i = 0; i < localeGroup.length; i++) {
497				nfLocales.put(localeGroup[i], localeGroupIdx);
498			}
499		}
500	};
501
502	function formatCodes(locale, isFullLocale) {
503		if (nfLocales.size() == 0)
504			init();
505
506         // default values
507         var dec = ".";
508         var group = ",";
509         var neg = "-";
510         
511         if (isFullLocale == false) {
512	         // Extract and convert to lower-case any language code from a real 'locale' formatted string, if not use as-is
513	         // (To prevent locale format like : "fr_FR", "en_US", "de_DE", "fr_FR", "en-US", "de-DE")
514	         if (locale.indexOf('_') != -1)
515				locale = locale.split('_')[1].toLowerCase();
516			 else if (locale.indexOf('-') != -1)
517				locale = locale.split('-')[1].toLowerCase();
518		}
519
520		 // hashtable lookup to match locale with codes
521		 var codesIndex = nfLocales.get(locale);
522		 if (codesIndex) {
523		 	var codes = nfLocaleFormatting[codesIndex];
524			if (codes) {
525				dec = codes[0];
526				group = codes[1];
527			}
528		 }
529		 return new FormatData(dec, group, neg);
530    };
531	
532	
533	/*	Formatting Methods	*/
534	
535	
536	/**
537	 * Formats anything containing a number in standard js number notation.
538	 * 
539	 * @param {Object}	options			The formatting options to use
540	 * @param {Boolean}	writeBack		(true) If the output value should be written back to the subject
541	 * @param {Boolean} giveReturnValue	(true) If the function should return the output string
542	 */
543	jQuery.fn.formatNumber = function(options, writeBack, giveReturnValue) {
544	
545		return this.each(function() {
546			// enforce defaults
547			if (writeBack == null)
548				writeBack = true;
549			if (giveReturnValue == null)
550				giveReturnValue = true;
551			
552			// get text
553			var text;
554			if (jQuery(this).is(":input"))
555				text = new String(jQuery(this).val());
556			else
557				text = new String(jQuery(this).text());
558
559			// format
560			var returnString = jQuery.formatNumber(text, options);
561		
562			// set formatted string back, only if a success
563//			if (returnString) {
564				if (writeBack) {
565					if (jQuery(this).is(":input"))
566						jQuery(this).val(returnString);
567					else
568						jQuery(this).text(returnString);
569				}
570				if (giveReturnValue)
571					return returnString;
572//			}
573//			return '';
574		});
575	};
576	
577	/**
578	 * First parses a string and reformats it with the given options.
579	 * 
580	 * @param {Object} numberString
581	 * @param {Object} options
582	 */
583	jQuery.formatNumber = function(numberString, options){
584		var options = jQuery.extend({}, jQuery.fn.formatNumber.defaults, options);
585		var formatData = formatCodes(options.locale.toLowerCase(), options.isFullLocale);
586		
587		var dec = formatData.dec;
588		var group = formatData.group;
589		var neg = formatData.neg;
590		
591		var validFormat = "0#-,.";
592		
593		// strip all the invalid characters at the beginning and the end
594		// of the format, and we'll stick them back on at the end
595		// make a special case for the negative sign "-" though, so 
596		// we can have formats like -$23.32
597		var prefix = "";
598		var negativeInFront = false;
599		for (var i = 0; i < options.format.length; i++) {
600			if (validFormat.indexOf(options.format.charAt(i)) == -1) 
601				prefix = prefix + options.format.charAt(i);
602			else 
603				if (i == 0 && options.format.charAt(i) == '-') {
604					negativeInFront = true;
605					continue;
606				}
607				else 
608					break;
609		}
610		var suffix = "";
611		for (var i = options.format.length - 1; i >= 0; i--) {
612			if (validFormat.indexOf(options.format.charAt(i)) == -1) 
613				suffix = options.format.charAt(i) + suffix;
614			else 
615				break;
616		}
617		
618		options.format = options.format.substring(prefix.length);
619		options.format = options.format.substring(0, options.format.length - suffix.length);
620		
621		// now we need to convert it into a number
622		//while (numberString.indexOf(group) > -1) 
623		//	numberString = numberString.replace(group, '');
624		//var number = new Number(numberString.replace(dec, ".").replace(neg, "-"));
625		var number = new Number(numberString);
626		
627		return jQuery._formatNumber(number, options, suffix, prefix, negativeInFront);
628	};
629	
630	/**
631	 * Formats a Number object into a string, using the given formatting options
632	 * 
633	 * @param {Object} numberString
634	 * @param {Object} options
635	 */
636	jQuery._formatNumber = function(number, options, suffix, prefix, negativeInFront) {
637		var options = jQuery.extend({}, jQuery.fn.formatNumber.defaults, options);
638		var formatData = formatCodes(options.locale.toLowerCase(), options.isFullLocale);
639		
640		var dec = formatData.dec;
641		var group = formatData.group;
642		var neg = formatData.neg;
643		
644		var forcedToZero = false;
645		if (isNaN(number)) {
646			if (options.nanForceZero == true) {
647				number = 0;
648				forcedToZero = true;
649			} else 
650				return null;
651		}
652
653		// special case for percentages
654        if (suffix == "%")
655        	number = number * 100;
656
657		var returnString = "";
658		if (options.format.indexOf(".") > -1) {
659			var decimalPortion = dec;
660			var decimalFormat = options.format.substring(options.format.lastIndexOf(".") + 1);
661			
662			// round or truncate number as needed
663			if (options.round == true)
664				number = new Number(number.toFixed(decimalFormat.length));
665			else {
666				var numStr = number.toString();
667				numStr = numStr.substring(0, numStr.lastIndexOf('.') + decimalFormat.length + 1);
668				number = new Number(numStr);
669			}
670			
671			var decimalValue = number % 1;
672			var decimalString = new String(decimalValue.toFixed(decimalFormat.length));
673			decimalString = decimalString.substring(decimalString.lastIndexOf(".") + 1);
674			
675			for (var i = 0; i < decimalFormat.length; i++) {
676				if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) != '0') {
677                	decimalPortion += decimalString.charAt(i);
678					continue;
679				} else if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) == '0') {
680					var notParsed = decimalString.substring(i);
681					if (notParsed.match('[1-9]')) {
682						decimalPortion += decimalString.charAt(i);
683						continue;
684					} else
685						break;
686				} else if (decimalFormat.charAt(i) == "0")
687					decimalPortion += decimalString.charAt(i);
688			}
689			returnString += decimalPortion
690         } else
691			number = Math.round(number);
692
693		var ones = Math.floor(number);
694		if (number < 0)
695			ones = Math.ceil(number);
696
697		var onesFormat = "";
698		if (options.format.indexOf(".") == -1)
699			onesFormat = options.format;
700		else
701			onesFormat = options.format.substring(0, options.format.indexOf("."));
702
703		var onePortion = "";
704		if (!(ones == 0 && onesFormat.substr(onesFormat.length - 1) == '#') || forcedToZero) {
705			// find how many digits are in the group
706			var oneText = new String(Math.abs(ones));
707			var groupLength = 9999;
708			if (onesFormat.lastIndexOf(",") != -1)
709				groupLength = onesFormat.length - onesFormat.lastIndexOf(",") - 1;
710			var groupCount = 0;
711			for (var i = oneText.length - 1; i > -1; i--) {
712				onePortion = oneText.charAt(i) + onePortion;
713				groupCount++;
714				if (groupCount == groupLength && i != 0) {
715					onePortion = group + onePortion;
716					groupCount = 0;
717				}
718			}
719			
720			// account for any pre-data padding
721			if (onesFormat.length > onePortion.length) {
722				var padStart = onesFormat.indexOf('0');
723				if (padStart != -1) {
724					var padLen = onesFormat.length - padStart;
725					
726					// pad to left with 0's or group char
727					var pos = onesFormat.length - onePortion.length - 1;
728					while (onePortion.length < padLen) {
729						var padChar = onesFormat.charAt(pos);
730						// replace with real group char if needed
731						if (padChar == ',')
732							padChar = group;
733						onePortion = padChar + onePortion;
734						pos--;
735					}
736				}
737			}
738		}
739		
740		if (!onePortion && onesFormat.indexOf('0', onesFormat.length - 1) !== -1)
741   			onePortion = '0';
742
743		returnString = onePortion + returnString;
744
745		// handle special case where negative is in front of the invalid characters
746		if (number < 0 && negativeInFront && prefix.length > 0)
747			prefix = neg + prefix;
748		else if (number < 0)
749			returnString = neg + returnString;
750		
751		if (!options.decimalSeparatorAlwaysShown) {
752			if (returnString.lastIndexOf(dec) == returnString.length - 1) {
753				returnString = returnString.substring(0, returnString.length - 1);
754			}
755		}
756		returnString = prefix + returnString + suffix;
757		return returnString;
758	};
759
760
761	/*	Parsing Methods	*/
762
763
764	/**
765	 * Parses a number of given format from the element and returns a Number object.
766	 * @param {Object} options
767	 */
768	jQuery.fn.parseNumber = function(options, writeBack, giveReturnValue) {
769		// enforce defaults
770		if (writeBack == null)
771			writeBack = true;
772		if (giveReturnValue == null)
773			giveReturnValue = true;
774		
775		// get text
776		var text;
777		if (jQuery(this).is(":input"))
778			text = new String(jQuery(this).val());
779		else
780			text = new String(jQuery(this).text());
781	
782		// parse text
783		var number = jQuery.parseNumber(text, options);
784		
785		if (number) {
786			if (writeBack) {
787				if (jQuery(this).is(":input"))
788					jQuery(this).val(number.toString());
789				else
790					jQuery(this).text(number.toString());
791			}
792			if (giveReturnValue)
793				return number;
794		}
795	};
796	
797	/**
798	 * Parses a string of given format into a Number object.
799	 * 
800	 * @param {Object} string
801	 * @param {Object} options
802	 */
803	jQuery.parseNumber = function(numberString, options) {
804		var options = jQuery.extend({}, jQuery.fn.parseNumber.defaults, options);
805		var formatData = formatCodes(options.locale.toLowerCase(), options.isFullLocale);
806
807		var dec = formatData.dec;
808		var group = formatData.group;
809		var neg = formatData.neg;
810
811		var valid = "1234567890.-";
812		
813		// now we need to convert it into a number
814		while (numberString.indexOf(group)>-1)
815			numberString = numberString.replace(group,'');
816		numberString = numberString.replace(dec,".").replace(neg,"-");
817		var validText = "";
818		var hasPercent = false;
819		if (numberString.charAt(numberString.length - 1) == "%" || options.isPercentage == true)
820			hasPercent = true;
821		for (var i=0; i<numberString.length; i++) {
822			if (valid.indexOf(numberString.charAt(i))>-1)
823				validText = validText + numberString.charAt(i);
824		}
825		var number = new Number(validText);
826		if (hasPercent) {
827			number = number / 100;
828			var decimalPos = validText.indexOf('.');
829			if (decimalPos != -1) {
830				var decimalPoints = validText.length - decimalPos - 1;
831				number = number.toFixed(decimalPoints + 2);
832			} else {
833				number = number.toFixed(validText.length - 1);
834			}
835		}
836
837		return number;
838	};
839
840	jQuery.fn.parseNumber.defaults = {
841		locale: "us",
842		decimalSeparatorAlwaysShown: false,
843		isPercentage: false,
844		isFullLocale: false
845	};
846
847	jQuery.fn.formatNumber.defaults = {
848		format: "#,###.00",
849		locale: "us",
850		decimalSeparatorAlwaysShown: false,
851		nanForceZero: true,
852		round: true,
853		isFullLocale: false
854	};
855	
856	Number.prototype.toFixed = function(precision) {
857    	return jQuery._roundNumber(this, precision);
858	};
859	
860	jQuery._roundNumber = function(number, decimalPlaces) {
861		var power = Math.pow(10, decimalPlaces || 0);
862    	var value = String(Math.round(number * power) / power);
863    	
864    	// ensure the decimal places are there
865    	if (decimalPlaces > 0) {
866    		var dp = value.indexOf(".");
867    		if (dp == -1) {
868    			value += '.';
869    			dp = 0;
870    		} else {
871    			dp = value.length - (dp + 1);
872    		}
873    		
874    		while (dp < decimalPlaces) {
875    			value += '0';
876    			dp++;
877    		}
878    	}
879    	return value;
880	};
881
882 })(jQuery);
883
884 // Simple JavaScript Templating
885// John Resig - http://ejohn.org/ - MIT Licensed
886(function(){
887  var cache = {};
888  
889  this.tmpl = function tmpl(str, data){
890    // Figure out if we're getting a template, or if we need to
891    // load the template - and be sure to cache the result.
892    var fn = !/\W/.test(str) ?
893      cache[str] = cache[str] ||
894        tmpl(document.getElementById(str).innerHTML) :
895      
896      // Generate a reusable function that will serve as a template
897      // generator (and which will be cached).
898      new Function("obj",
899        "var p=[],print=function(){p.push.apply(p,arguments);};" +
900        
901        // Introduce the data as local variables using with(){}
902        "with(obj){p.push('" +
903        
904        // Convert the template into pure JavaScript
905        str
906          .replace(/[\r\t\n]/g, " ")
907          .split("<%").join("\t")
908          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
909          .replace(/\t=(.*?)%>/g, "',$1,'")
910          .split("\t").join("');")
911          .split("%>").join("p.push('")
912          .split("\r").join("\\'")
913      + "');}return p.join('');");
914    
915    // Provide some basic currying to the user
916    return data ? fn( data ) : fn;
917  };
918})();
919
920/**
921 * jquery.dependClass - Attach class based on first class in list of current element
922 * 
923 * Written by
924 * Egor Khmelev ([email protected])
925 *
926 * Licensed under the MIT (MIT-LICENSE.txt).
927 *
928 * @author Egor Khmelev
929 * @version 0.1.0-BETA ($Id$)
930 * 
931 **/
932
933(function($) {
934	$.baseClass = function(obj){
935	  obj = $(obj);
936	  return obj.get(0).className.match(/([^ ]+)/)[1];
937	};
938	
939	$.fn.addDependClass = function(className, delimiter){
940		var options = {
941		  delimiter: delimiter ? delimiter : '-'
942		}
943		return this.each(function(){
944		  var baseClass = $.baseClass(this);
945		  if(baseClass)
946    		$(this).addClass(baseClass + options.delimiter + className);
947		});
948	};
949
950	$.fn.removeDependClass = function(className, delimiter){
951		var options = {
952		  delimiter: delimiter ? delimiter : '-'
953		}
954		return this.each(function(){
955		  var baseClass = $.baseClass(this);
956		  if(baseClass)
957    		$(this).removeClass(baseClass + options.delimiter + className);
958		});
959	};
960
961	$.fn.toggleDependClass = function(className, delimiter){
962		var options = {
963		  delimiter: delimiter ? delimiter : '-'
964		}
965		return this.each(function(){
966		  var baseClass = $.baseClass(this);
967		  if(baseClass)
968		    if($(this).is("." + baseClass + options.delimiter + className))
969    		  $(this).removeClass(baseClass + options.delimiter + className);
970    		else
971    		  $(this).addClass(baseClass + options.delimiter + className);
972		});
973	};
974
975})(jQuery);
976
977/**
978 * draggable - Class allows to make any element draggable
979 * 
980 * Written by
981 * Egor Khmelev ([email protected])
982 *
983 * Licensed under the MIT (MIT-LICENSE.txt).
984 *
985 * @author Egor Khmelev
986 * @version 0.1.0-BETA ($Id$)
987 * 
988 **/
989
990(function( $ ){
991
992  function Draggable(){
993  	this._init.apply( this, arguments );
994  };
995
996	Draggable.prototype.oninit = function(){
997	  
998	};
999	
1000	Draggable.prototype.events = function(){
1001	  
1002	};
1003	
1004	Draggable.prototype.onmousedown = function(){
1005		this.ptr.css({ position: "absolute" });
1006	};
1007	
1008	Draggable.prototype.onmousemove = function( evt, x, y ){
1009		this.ptr.css({ left: x, top: y });
1010	};
1011	
1012	Draggable.prototype.onmouseup = function(){
1013	  
1014	};
1015
1016	Draggable.prototype.isDefault = {
1017		drag: false,
1018		clicked: false,
1019		toclick: true,
1020		mouseup: false
1021	};
1022
1023	Draggable.prototype._init = function(){
1024		if( arguments.length > 0 ){
1025			this.ptr = $(arguments[0]);
1026			this.outer = $(".draggable-outer");
1027
1028			this.is = {};
1029			$.extend( this.is, this.isDefault );
1030
1031			var _offset = this.ptr.offset();
1032			this.d = {
1033				left: _offset.left,
1034				top: _offset.top,
1035				width: this.ptr.width(),
1036				height: this.ptr.height()
1037			};
1038
1039			this.oninit.apply( this, arguments );
1040
1041			this._events();
1042		}
1043	};
1044	
1045	Draggable.prototype._getPageCoords = function( event ){
1046	  if( event.targetTouches && event.targetTouches[0] ){
1047	    return { x: event.targetTouches[0].pageX, y: event.targetTouches[0].pageY };
1048	  } else
1049	    return { x: event.pageX, y: event.pageY };
1050	};
1051	
1052	Draggable.prototype._bindEvent = function( ptr, eventType, handler ){
1053	  var self = this;
1054
1055	  if( this.supportTouches_ )
1056      ptr.get(0).addEventListener( this.events_[ eventType ], handler, false );
1057	  
1058	  else
1059	    ptr.bind( this.events_[ eventType ], handler );
1060	};
1061	
1062	Draggable.prototype._events = function(){
1063		var self = this;
1064
1065    this.supportTouches_ = 'ontouchend' in document;
1066    this.events_ = {
1067      "click": this.supportTouches_ ? "touchstart" : "click",
1068      "down": this.supportTouches_ ? "touchstart" : "mousedown",
1069      "move": this.supportTouches_ ? "touchmove" : "mousemove",
1070      "up"  : this.supportTouches_ ? "touchend" : "mouseup"
1071    };
1072
1073    this._bindEvent( $( document ), "move", function( event ){
1074			if( self.is.drag ){
1075        event.stopPropagation();
1076        event.preventDefault();
1077				self._mousemove( event );
1078			}
1079		});
1080    this._bindEvent( $( document ), "down", function( event ){
1081			if( self.is.drag ){
1082        event.stopPropagation();
1083        event.preventDefault();
1084			}
1085		});
1086    this._bindEvent( $( document ), "up", function( event ){
1087			self._mouseup( event );
1088		});
1089		
1090    this._bindEvent( this.ptr, "down", function( event ){
1091			self._mousedown( event );
1092			return false;
1093		});
1094    this._bindEvent( this.ptr, "up", function( event ){
1095			self._mouseup( event );
1096		});
1097		
1098		this.ptr.find("a")
1099			.click(function(){
1100				self.is.clicked = true;
1101
1102				if( !self.is.toclick ){
1103					self.is.toclick = true;
1104					return false;
1105				}
1106			})
1107			.mousedown(function( event ){
1108				self._mousedown( event );
1109				return false;
1110			});
1111
1112		this.events();
1113	};
1114	
1115	Draggable.prototype._mousedown = function( evt ){
1116		this.is.drag = true;
1117		this.is.clicked = false;
1118		this.is.mouseup = false;
1119
1120		var _offset = this.ptr.offset();
1121		var coords = this._getPageCoords( evt );
1122		this.cx = coords.x - _offset.left;
1123		this.cy = coords.y - _offset.top;
1124
1125		$.extend(this.d, {
1126			left: _offset.left,
1127			top: _offset.top,
1128			width: this.ptr.width(),
1129			height: this.ptr.height()
1130		});
1131
1132		if( this.outer && this.outer.get(0) ){
1133			this.outer.css({ height: Math.max(this.outer.height(), $(document.body).height()), overflow: "hidden" });
1134		}
1135
1136		this.onmousedown( evt );
1137	};
1138	
1139	Draggable.prototype._mousemove = function( evt ){
1140		this.is.toclick = false;
1141		var coords = this._getPageCoords( evt );
1142		this.onmousemove( evt, coords.x - this.cx, coords.y - this.cy );
1143	};
1144	
1145	Draggable.prototype._mouseup = function( evt ){
1146		var oThis = this;
1147
1148		if( this.is.drag ){
1149			this.is.drag = false;
1150
1151			if( this.outer && this.outer.get(0) ){
1152
1153				if( $.browser.mozilla ){
1154					this.outer.css({ overflow: "hidden" });
1155				} else {
1156					this.outer.css({ overflow: "visible" });
1157				}
1158
1159        if( $.browser.msie && $.browser.version == '6.0' ){
1160         this.outer.css({ height: "100%" });
1161        } else {
1162         this.outer.css({ height: "auto" });
1163        }  
1164			}
1165
1166			this.onmouseup( evt );
1167		}
1168	};
1169	
1170	window.Draggable = Draggable;
1171
1172})( jQuery );
1173
1174
1175/**
1176 * jquery.slider - Slider ui control in jQuery
1177 *
1178 * Written by
1179 * Egor Khmelev ([email protected])
1180 *
1181 * Licensed under the MIT (MIT-LICENSE.txt).
1182 *
1183 * @author Egor Khmelev
1184 * @version 1.1.0-RELEASE ($Id$)
1185 *
1186 * Dependencies
1187 *
1188 * jQuery (http://jquery.com)
1189 * jquery.numberformatter (http://code.google.com/p/jquery-numberformatter/)
1190 * tmpl (http://ejohn.org/blog/javascript-micro-templating/)
1191 * jquery.dependClass
1192 * draggable
1193 *
1194 **/
1195
1196(function( $ ) {
1197
1198  function isArray( value ){
1199    if( typeof value == "undefined" ) return false;
1200
1201    if (value instanceof Array || (!(value instanceof Object) &&
1202         (Object.prototype.toString.call((value)) == '[object Array]') ||
1203         typeof value.length == 'number' &&
1204         typeof value.splice != 'undefined' &&
1205         typeof value.propertyIsEnumerable != 'undefined' &&
1206         !value.propertyIsEnumerable('splice')
1207        )) {
1208      return true;
1209    }
1210
1211    return false;
1212  }
1213
1214	$.slider = function( node, settings ){
1215	  var jNode = $(node);
1216	  if( !jNode.data( "jslider" ) )
1217	    jNode.data( "jslider", new jSlider( node, settings ) );
1218
1219	  return jNode.data( "jslider" );
1220	};
1221
1222	$.fn.slider = function( action, opt_value ){
1223	  var returnValue, args = arguments;
1224
1225	  function isDef( val ){
1226	    return val !== undefined;
1227	  };
1228
1229	  function isDefAndNotNull( val ){
1230      return val != null;
1231	  };
1232
1233		this.each(function(){
1234		  var self = $.slider( this, action );
1235
1236		  // do actions
1237		  if( typeof action == "string" ){
1238		    switch( action ){
1239		      case "value":
1240		        if( isDef( args[ 1 ] ) && isDef( args[ 2 ] ) ){
1241		          var pointers = self.getPointers();
1242		          if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){
1243		            pointers[0].set( args[ 1 ] );
1244		            pointers[0].setIndexOver();
1245		          }
1246
1247		          if( isDefAndNotNull( pointers[1] ) && isDefAndNotNull( args[2] ) ){
1248		            pointers[1].set( args[ 2 ] );
1249		            pointers[1].setIndexOver();
1250		          }
1251		        }
1252
1253		        else if( isDef( args[ 1 ] ) ){
1254		          var pointers = self.getPointers();
1255		          if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){
1256		            pointers[0].set( args[ 1 ] );
1257		            pointers[0].setIndexOver();
1258		          }
1259		        }
1260
1261		        else
1262  		        returnValue = self.getValue();
1263
1264		        break;
1265
1266		      case "prc":
1267		        if( isDef( args[ 1 ] ) && isDef( args[ 2 ] ) ){
1268		          var pointers = self.getPointers();
1269		          if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){
1270		            pointers[0]._set( args[ 1 ] );
1271		            pointers[0].setIndexOver();
1272		          }
1273
1274		          if( isDefAndNotNull( pointers[1] ) && isDefAndNotNull( args[2] ) ){
1275		            pointers[1]._set( args[ 2 ] );
1276		            pointers[1].setIndexOver();
1277		          }
1278		        }
1279
1280		        else if( isDef( args[ 1 ] ) ){
1281		          var pointers = self.getPointers();
1282		          if( isDefAndNotNull( pointers[0] ) && isDefAndNotNull( args[1] ) ){
1283		            pointers[0]._set( args[ 1 ] );
1284		            pointers[0].setIndexOver();
1285		          }
1286		        }
1287
1288		        else
1289  		        returnValue = self.getPrcValue();
1290
1291		        break;
1292
1293  		    case "calculatedValue":
1294  		      var value = self.getValue().split(";");
1295  		      returnValue = "";
1296  		      for (var i=0; i < value.length; i++) {
1297  		        returnValue += (i > 0 ? ";" : "") + self.nice( value[i] );
1298  		      };
1299
1300  		      break;
1301
1302  		    case "skin":
1303		        self.setSkin( args[1] );
1304
1305  		      break;
1306		    };
1307
1308		  }
1309
1310		  // return actual object
1311		  else if( !action && !opt_value ){
1312		    if( !isArray( returnValue ) )
1313		      returnValue = [];
1314
1315		    returnValue.push( self );
1316		  }
1317		});
1318
1319		// flatten array just with one slider
1320		if( isArray( returnValue ) && returnValue.length == 1 )
1321		  returnValue = returnValue[ 0 ];
1322
1323		return returnValue || this;
1324	};
1325
1326  var OPTIONS = {
1327
1328    settings: {
1329      from: 1,
1330      to: 10,
1331      step: 1,
1332      smooth: true,
1333      limits: true,
1334      round: 0,
1335      format: { format: "#,##0.##" },
1336      value: "5;7",
1337      dimension: ""
1338    },
1339
1340    className: "jslider",
1341    selector: ".jslider-",
1342
1343    template: tmpl(
1344      '<span class="<%=className%>">' +
1345        '<table><tr><td>' +
1346          '<div class="<%=className%>-bg">' +
1347            '<i class="l"></i><i class="f"></i><i class="r"></i>' +
1348            '<i class="v"></i>' +
1349          '</div>' +
1350
1351          '<div class="<%=className%>-pointer"></div>' +
1352          '<div class="<%=className%>-pointer <%=className%>-pointer-to"></div>' +
1353
1354          '<div class="<%=className%>-label"><%=settings.dimension%><span><%=settings.from%></span></div>' +
1355          '<div class="<%=className%>-label <%=className%>-label-to"><%=settings.dimension%><span><%=settings.to%></span></div>' +
1356
1357          '<div class="<%=className%>-value"><%=settings.dimension%><span></span></div>' +
1358          '<div class="<%=className%>-value <%=className%>-value-to"><%=settings.dimension%><span></span></div>' +
1359
1360          '<div class="<%=className%>-scale"><%=scale%></div>'+
1361
1362        '</td></tr></table>' +
1363      '</span>'
1364    )
1365
1366  };
1367
1368  function jSlider(){
1369  	return this.init.apply( this, arguments );
1370  };
1371
1372  jSlider.prototype.init = function( node, settings ){
1373    this.settings = $.extend(true, {}, OPTIONS.settings, settings ? settings : {});
1374
1375    // obj.sliderHandler = this;
1376    this.inputNode = $( node ).hide();
1377
1378		this.settings.interval = this.settings.to-this.settings.from;
1379		this.settings.value = this.inputNode.attr("value");
1380
1381		if( this.settings.calculate && $.isFunction( this.settings.calculate ) )
1382		  this.nice = this.settings.calculate;
1383
1384		if( this.settings.onstatechange && $.isFunction( this.settings.onstatechange ) )
1385		  this.onstatechange = this.settings.onstatechange;
1386
1387    this.is = {
1388      init: false
1389    };
1390		this.o = {};
1391
1392    this.create();
1393  };
1394
1395  jSlider.prototype.onstatechange = function(){
1396
1397  };
1398
1399  jSlider.prototype.create = function(){
1400    var $this = this;
1401
1402    this.domNode = $( OPTIONS.template({
1403      className: OPTIONS.className,
1404      settings: {
1405        from: this.nice( this.settings.from ),
1406        to: this.nice( this.settings.to ),
1407        dimension: this.settings.dimension
1408      },
1409      scale: this.generateScale()
1410    }) );
1411
1412    this.inputNode.after( this.domNode );
1413    this.drawScale();
1414
1415    // set skin class
1416    if( this.settings.skin && this.settings.skin.length > 0 )
1417      this.setSkin( this.settings.skin );
1418
1419		this.sizes = {
1420		  domWidth: this.domNode.width(),
1421		  domOffset: this.domNode.offset()
1422		};
1423
1424    // find some objects
1425    $.extend(this.o, {
1426      pointers: {},
1427      labels: {
1428        0: {
1429          o: this.domNode.find(OPTIONS.selector + "value").not(OPTIONS.selector + "value-to")
1430        },
1431        1: {
1432          o: this.domNode.find(OPTIONS.selector + "value").filter(OPTIONS.selector + "value-to")
1433        }
1434      },
1435      limits: {
1436        0: this.domNode.find(OPTIONS.selector + "label").not(OPTIONS.selector + "label-to"),
1437        1: this.domNode.find(OPTIONS.selector + "label").filter(OPTIONS.selector + "label-to")
1438      }
1439    });
1440
1441    $.extend(this.o.labels[0], {
1442      value: this.o.labels[0].o.find("span")
1443    });
1444
1445    $.extend(this.o.labels[1], {
1446      value: this.o.labels[1].o.find("span")
1447    });
1448
1449
1450    if( !$this.settings.value.split(";")[1] ){
1451      this.settings.single = true;
1452      this.domNode.addDependClass("single");
1453    }
1454
1455    if( !$this.settings.limits )
1456      this.domNode.addDependClass("limitless");
1457
1458    this.domNode.find(OPTIONS.selector + "pointer").each(function( i ){
1459      var value = $this.settings.value.split(";")[i];
1460      if( value ){
1461        $this.o.pointers[i] = new jSliderPointer( this, i, $this );
1462
1463        var prev = $this.settings.value.split(";")[i-1];
1464        if( prev && new Number(value) < new Number(prev) ) value = prev;
1465
1466        value = value < $this.settings.from ? $this.settings.from : value;
1467        value = value > $this.settings.to ? $this.settings.to : value;
1468
1469        $this.o.pointers[i].set( value, true );
1470      }
1471    });
1472
1473    this.o.value = this.domNode.find(".v");
1474    this.is.init = true;
1475
1476    $.each(this.o.pointers, function(i){
1477      $this.redraw(this);
1478    });
1479
1480    (function(self){
1481      $(window).resize(function(){
1482        self.onresize();
1483      });
1484    })(this);
1485
1486  };
1487
1488  jSlider.prototype.setSkin = function( skin ){
1489    if( this.skin_ )
1490      this.domNode.removeDependClass( this.skin_, "_" );
1491
1492    this.domNode.addDependClass( this.skin_ = skin, "_" );
1493  };
1494
1495  jSlider.prototype.setPointersIndex = function( i ){
1496    $.each(this.getPointers(), function(i){
1497      this.index( i );
1498    });
1499  };
1500
1501  jSlider.prototype.getPointers = function(){
1502    return this.o.pointers;
1503  };
1504
1505  jSlider.prototype.generateScale = function(){
1506    if( this.settings.scale && this.settings.scale.length > 0 ){
1507      var str = "";
1508      var s = this.settings.scale;
1509      var prc = Math.round((100/(s.length-1))*10)/10;
1510      for( var i=0; i < s.length; i++ ){
1511        str += '<span style="left: ' + i*prc + '%">' + ( s[i] != '|' ? '<ins>' + s[i] + '</ins>' : '' ) + '</span>';
1512      };
1513      return str;
1514    } else return "";
1515
1516    return "";
1517  };
1518
1519  jSlider.prototype.drawScale = function(){
1520    this.domNode.find(OPTIONS.selector + "scale span ins").each(function(){
1521      $(this).css({ marginLeft: -$(this).outerWidth()/2 });
1522    });
1523  };
1524
1525  jSlider.prototype.onresize = function(){
1526    var self = this;
1527		this.sizes = {
1528		  domWidth: this.domNode.width(),
1529		  domOffset: this.domNode.offset()
1530		};
1531
1532    $.each(this.o.pointers, function(i){
1533      self.redraw(this);
1534    });
1535  };
1536
1537  jSlider.prototype.update = function(){
1538    this.onresize();
1539    this.drawScale();
1540  };
1541
1542  jSlider.prototype.limits = function( x, pointer ){
1543	  // smooth
1544	  if( !this.settings.smooth ){
1545	    var step = this.settings.step*100 / ( this.settings.interval );
1546	    x = Math.round( x/step ) * step;
1547	  }
1548
1549	  var another = this.o.pointers[1-pointer.uid];
1550	  if( another && pointer.uid && x < another.value.prc ) x = another.value.prc;
1551	  if( another && !pointer.uid && x > another.value.prc ) x = another.value.prc;
1552
1553    // base limit
1554	  if( x < 0 ) x = 0;
1555	  if( x > 100 ) x = 100;
1556
1557    return Math.round( x*10 ) / 10;
1558  };
1559
1560  jSlider.prototype.redraw = function( pointer ){
1561    if( !this.is.init ) return false;
1562
1563    this.setValue();
1564
1565    // redraw range line
1566    if( this.o.pointers[0] && this.o.pointers[1] )
1567      this.o.value.css({ left: this.o.pointers[0].value.prc + "%", width: ( this.o.pointers[1].value.prc - this.o.pointers[0].value.prc ) + "%" });
1568
1569    this.o.labels[pointer.uid].value.html(
1570      this.nice(
1571        pointer.value.origin
1572      )
1573    );
1574
1575    // redraw position of labels
1576    this.redrawLabels( pointer );
1577
1578  };
1579
1580  jSlider.prototype.redrawLabels = function( pointer ){
1581
1582    function setPosition( label, sizes, prc ){
1583  	  sizes.margin = -sizes.label/2;
1584
1585      // left limit
1586      label_left = sizes.border + sizes.margin;
1587      if( label_left < 0 )
1588        sizes.margin -= label_left;
1589
1590      // right limit
1591      if( sizes.border+sizes.label / 2 > self.sizes.domWidth ){
1592        sizes.margin = 0;
1593        sizes.right = true;
1594      } else
1595        sizes.right = false;
1596
1597      label.o.css({ left: prc + "%", marginLeft: sizes.margin, right: "auto" });
1598      if( sizes.right ) label.o.css({ left: "auto", right: 0 });
1599      return sizes;
1600    }
1601
1602    var self = this;
1603	  var label = this.o.labels[pointer.uid];
1604	  var prc = pointer.value.prc;
1605
1606	  var sizes = {
1607	    label: label.o.outerWidth(),
1608	    right: false,
1609	    border: ( prc * this.sizes.domWidth ) / 100
1610	  };
1611
1612    if( !this.settings.single ){
1613      // glue if near;
1614      var another = this.o.pointers[1-pointer.uid];
1615    	var another_label = this.o.labels[another.uid];
1616
1617      switch( pointer.uid ){
1618        case 0:
1619          if( sizes.border+sizes.label / 2 > another_label.o.offset().left-this.sizes.domOffset.left ){
1620            another_label.o.css({ visibility: "hidden" });
1621        	  another_label.value.html( this.nice( another.value.origin ) );
1622
1623          	label.o.css({ visibility: "visible" });
1624
1625          	prc = ( another.value.prc - prc ) / 2 + prc;
1626          	if( another.value.prc != pointer.value.prc ){
1627              //label.value.html( this.nice(pointer.value.origin) + "&nbsp;&ndash;&nbsp;" + this.nice(another.value.origin) );
1628              label.value.html( this.nice(pointer.value.origin) );
1629            	sizes.label = label.o.outerWidth();
1630            	sizes.border = ( prc * this.sizes.domWidth ) / 100;
1631            }
1632          } else {
1633          	another_label.o.css({ visibility: "visible" });
1634          }
1635          break;
1636
1637        case 1:
1638          if( sizes.border - sizes.label / 2 < another_label.o.offset().left - this.sizes.domOffset.left + another_label.o.outerWidth() ){
1639            another_label.o.css({ visibility: "hidden" });
1640        	  another_label.value.html( this.nice(another.value.origin) );
1641
1642          	label.o.css({ visibility: "visible" });
1643            //modified by george
1644          	//prc = ( prc - another.value.prc ) / 2 + another.value.prc;
1645          	if( another.value.prc != pointer.value.prc ){
1646              //label.value.html( this.nice(another.value.origin) + "&nbsp;&ndash;&nbsp;" + this.nice(pointer.value.origin) );
1647              label.value.html( this.nice(pointer.value.origin) );
1648            	sizes.label = label.o.outerWidth();
1649            	sizes.border = ( prc * this.sizes.domWidth ) / 100;
1650            }
1651          } else {
1652            another_label.o.css({ visibility: "visible" });
1653          }
1654          break;
1655      }
1656    }
1657
1658    sizes = setPosition( label, sizes, prc );
1659
1660    /* draw second label */
1661    if( another_label ){
1662      var sizes = {
1663  	    label: another_label.o.outerWidth(),
1664  	    right: false,
1665  	    border: ( another.value.prc * this.sizes.domWidth ) / 100
1666  	  };
1667      sizes = setPosition( another_label, sizes, another.value.prc );
1668    }
1669
1670    this.redrawLimits();
1671  };
1672
1673  jSlider.prototype.redrawLimits = function(){
1674	  if( this.settings.limits ){
1675
1676      var limits = [ true, true ];
1677
1678      for( key in this.o.pointers ){
1679
1680        if( !this.settings.single || key == 0 ){
1681
1682      	  var pointer = this.o.pointers[key];
1683          var label = this.o.labels[pointer.uid];
1684          var label_left = label.o.offset().left - this.sizes.domOffset.left;
1685
1686      	  var limit = this.o.limits[0];
1687          if( label_left < limit.outerWidth() )
1688            limits[0] = false;
1689
1690      	  var limit = this.o.limits[1];
1691      	  if( label_left + label.o.outerWidth() > this.sizes.domWidth - limit.outerWidth() )
1692      	    limits[1] = false;
1693      	}
1694
1695      };
1696
1697      for( var i=0; i < limits.length; i++ ){
1698        if( limits[i] )
1699          this.o.limits[i].fadeIn("fast");
1700        else
1701          this.o.limits[i].fadeOut("fast");
1702      };
1703
1704	  }
1705  };
1706
1707  jSlider.prototype.setValue = function(){
1708    var value = this.getValue();
1709    this.inputNode.attr( "value", value );
1710    this.onstatechange.call( this, value );
1711  };
1712
1713  jSlider.prototype.getValue = function(){
1714    if(!this.is.init) return false;
1715    var $this = this;
1716
1717    var value = "";
1718    $.each( this.o.pointers, function(i){
1719      if( this.value.prc != undefined && !isNaN(this.value.prc) ) value += (i > 0 ? ";" : "") + $this.prcToValue( this.value.prc );
1720    });
1721    return value;
1722  };
1723
1724  jSlider.prototype.getPrcValue = function(){
1725    if(!this.is.init) return false;
1726    var $this = this;
1727
1728    var value = "";
1729    $.each( this.o.pointers, function(i){
1730      if( this.value.prc != undefined && !isNaN(this.value.prc) ) value += (i > 0 ? ";" : "") + this.value.prc;
1731    });
1732    return value;
1733  };
1734
1735  jSlider.prototype.prcToValue = function( prc ){
1736
1737	  if( this.settings.heterogeneity && this.settings.heterogeneity.length > 0 ){
1738  	  var h = this.settings.heterogeneity;
1739
1740  	  var _start = 0;
1741  	  var _from = this.settings.from;
1742
1743  	  for( var i=0; i <= h.length; i++ ){
1744  	    if( h[i] ) var v = h[i].split("/");
1745  	    else       var v = [100, this.settings.to];
1746
1747  	    v[0] = new Number(v[0]);
1748  	    v[1] = new Number(v[1]);
1749
1750  	    if( prc >= _start && prc <= v[0] ) {
1751  	      var value = _from + ( (prc-_start) * (v[1]-_from) ) / (v[0]-_start);
1752  	    }
1753
1754  	    _start = v[0];
1755  	    _from = v[1];
1756  	  };
1757
1758	  } else {
1759      var value = this.settings.from + ( prc * this.settings.interval ) / 100;
1760	  }
1761
1762    return this.round( value );
1763  };
1764
1765	jSlider.prototype.valueToPrc = function( value, pointer ){
1766	  if( this.settings.heterogeneity && this.settings.heterogeneity.length > 0 ){
1767  	  var h = this.settings.heterogeneity;
1768
1769  	  var _start = 0;
1770  	  var _from = this.settings.from;
1771
1772  	  for (var i=0; i <= h.length; i++) {
1773  	    if(h[i]) var v = h[i].split("/");
1774  	    else     var v = [100, this.settings.to];
1775  	    v[0] = new Number(v[0]); v[1] = new Number(v[1]);
1776
1777  	    if(value >= _from && value <= v[1]){
1778  	      var prc = pointer.limits(_start + (value-_from)*(v[0]-_start)/(v[1]-_from));
1779  	    }
1780
1781  	    _start = v[0]; _from = v[1];
1782  	  };
1783
1784	  } else {
1785  	  var prc = pointer.limits((value-this.settings.from)*100/this.settings.interval);
1786	  }
1787
1788	  return prc;
1789	};
1790
1791	jSlider.prototype.round = function( value ){
1792    value = Math.round( value / this.settings.step ) * this.settings.step;
1793		if( this.settings.round ) value = Math.round( value * Math.pow(10, this.settings.round) ) / Math.pow(10, this.settings.round);
1794		else value = Math.round( value );
1795		return value;
1796	};
1797
1798	jSlider.prototype.nice = function( value ){
1799		value = value.toString().replace(/,/gi, ".").replace(/ /gi, "");;
1800
1801		if( $.formatNumber ){
1802		  return $.formatNumber( new Number(value), this.settings.format || {} ).replace( /-/gi, "&minus;" );
1803		}
1804
1805		else {
1806		  return new Number(value);
1807		}
1808	};
1809
1810
1811  function jSliderPointer(){
1812  	Draggable.apply( this, arguments );
1813  }
1814  jSliderPointer.prototype = new Draggable();
1815
1816  jSliderPointer.prototype.oninit = function( ptr, id, _constructor ){
1817    this.uid = id;
1818    this.parent = _constructor;
1819    this.value = {};
1820    this.settings = this.parent.settings;
1821  };
1822
1823  jSliderPointer.prototype.onmousedown = function(evt){
1824	  this._parent = {
1825	    offset: this.parent.domNode.offset(),
1826	    width: this.parent.domNode.width()
1827	  };
1828	  this.ptr.addDependClass("hover");
1829	  this.setIndexOver();
1830	};
1831
1832	jSliderPointer.prototype.onmousemove = function( evt, x ){
1833	  var coords = this._getPageCoords( evt );
1834	  this._set( this.calc( coords.x ) );
1835	};
1836
1837	jSliderPointer.prototype.onmouseup = function( evt ){
1838	  if( this.parent.settings.callback && $.isFunction(this.parent.settings.callback) )
1839	    this.parent.settings.callback.call( this.parent, this.parent.getValue() );
1840
1841	  this.ptr.removeDependClass("hover");
1842	};
1843
1844	jSliderPointer.prototype.setIndexOver = function(){
1845	  this.parent.setPointersIndex( 1 );
1846	  this.index( 2 );
1847	};
1848
1849	jSliderPointer.prototype.index = function( i ){
1850	  this.ptr.css({ zIndex: i });
1851	};
1852
1853	jSliderPointer.prototype.limits = function( x ){
1854	  return this.parent.limits( x, this );
1855	};
1856
1857	jSliderPointer.prototype.calc = function(coords){
1858	  var x = this.limits(((coords-this._parent.offset.left)*100)/this._parent.width);
1859	  return x;
1860	};
1861
1862	jSliderPointer.prototype.set = function( value, opt_origin ){
1863	  this.value.origin = this.parent.round(value);
1864	  this._set( this.parent.valueToPrc( value, this ), opt_origin );
1865	};
1866
1867	jSliderPointer.prototype._set = function( prc, opt_origin ){
1868	  if( !opt_origin )
1869	    this.value.origin = this.parent.prcToValue(prc);
1870
1871	  this.value.prc = prc;
1872		this.ptr.css({ left: prc + "%" });
1873	  this.parent.redraw(this);
1874	};
1875
1876})(jQuery);

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.