
var sb = {
	
	
	base : (typeof window.sbBase !='undefined') ? window.sbBase : '/surebert',
	
	
	colors : {},
	
	
	consol : {
		log : function(){},
		write : function(){},
		error : function(){}
	},

	
	createIfNotExists : function(i, o){
		if(!window[i] && o!==null){
			window[i] = o;
		}
	},
	
	
	css : {},
	
	
	included : [],
	
	include : function(module){
		
		var mods = module.split('.');
		var path ='', file, unit=sb,m;
		if(mods[0] == 'String' || mods[0] == 'Element' || mods[0] == 'Array'){
			unit = window;
		}
		
		for(m=0;m<mods.length;m++){
			
			if(m !==0 && m < mods.length && mods.length >1){
				path +='.';
			}
			path +=mods[m];
			
			try{
				
				unit = unit[mods[m]];
				
			} catch(e){}
		
			if(typeof unit == 'undefined'){
					
				this.included.push(path);
				file = path.replace(/\./g, "/");
				sb.load(sb.base+'/'+file+'.js');
			
			}
		}
	},
	
	
	load : function(url){
		var evaled = 0;

		(function(){
			var load = new sb.ajax({
				url : url,
				async : 0,
				method : 'get',
				format : 'js',
				debug : sb.loadDebug ? 1 : 0,
				onResponse: function(r){
				//#######look into this 
					
					try{
						evaled=1;
					}catch(e){
							
						evaled=0;
						delete e.stack;
						
						sb.consol.error(sb.messages[13]+"\nURL: "+url+"\n"+sb.objects.dump(e));
						
					}
					load=null;
				}
			}).fetch();}());
			
		return evaled;
	},
	
	
	math : {},
	
	

	messages : [],
	
	
	onbodyload : [],
	
	
	onleavepage : [],

	
	toArray : function(o){
		var a=[];
		var len=o.length;
		for(var x=0;x<len;x++){
			a.push(o[x]);
		}
		return a;
	},
	
	
	typeOf : function(o){
		var type='';
		
		if(o === null){
			return 'null';
		} else if (o instanceof Function) { 
			type = 'function'; 
		} else if (o instanceof Array) {
			type = 'array';
		} else if(typeof o == 'number'){
			type = 'number';
			if(String(o).match(/\./)){
				type = 'float';
			}
		} else if(typeof o == 'string'){
			type = 'string';
		} else if(o === true || o === false){
			type='boolean';
		} else {
			type = (typeof o).toLowerCase();
		}
		
		if(typeof o =='object' ){
		
			if(typeof o.typeOf == 'function'){
				type = o.typeOf();
			} else if (o.nodeType){
				if (o.nodeType == 3) {
					type = 'textnode';
					
				} else if (o.nodeType == 1) {
					type = 'element';
				}
			} else if(typeof o.length !='undefined' && type !='array'){
				type = 'sb.nodeList';
			} 
		}
		
		return type;
	},
	
	
	uid : 0,
	
	
	uniqueID : function(){
		return 'uid_'+(sb.uid +=1);
	},
	
	
	
	unixTime : function(){
		return parseInt(String(new Date().getTime()).substring(0,10), 10);
	},
	
	
	functions : {},
	
	
	utils : {},
	
	
	widget : {},
	
	
	forms : {}
	
};



$ = function(selector, root) {
	
	root = root || document;
	
	//return items that are already objects
	if(typeof selector != 'string'){
		
		if(typeof selector == 'object' && selector !== null){
			if(Element.emulated === true && selector.nodeType && selector.nodeType == 1){
				
				var ep = Element.prototype;
				for(var prop in ep){
					if(ep.hasOwnProperty(prop)){
						selector[prop] = ep[prop];
					}
				}
			} else if (typeof selector.typeOf == 'function' && selector.typeOf() == 'sb.nodeList'){
				selector.getElementPrototypes();
			}
		}
		
		return selector;
	}
	
	var nodeList = new sb.nodeList();
	
	nodeList.setSelector(selector);
	
	if(document.querySelectorAll){
		
		nodeList.add(root.querySelectorAll(selector));
		
	} else {
		$.parseSelectors(nodeList, root);
	}
	
	if(nodeList.length() === 0 && nodeList.selector.match(/^\#[\w-]+$/) ){
		return null;
	} else if(nodeList.length() == 1 && (nodeList.selector.match(/^\#[\w-]+$/) || sb.nodeList.singleTags.some(function(v){return v === nodeList.selector;}))){
	
		return nodeList.nodes[0];
	} else {
		return nodeList;
	}
	
};


$.parseSelectors = function(nodes, within){
	
	within = within || document;
	var root = [within];

	var found = [],s=0;
	
	//split at comma
	var selectors = nodes.selector.split(",");
	
	var len = selectors.length;
	var inheriters = [];
	
	for(s=0;s<len;s++){
		
		inheriters = selectors[s].split(" ");
		root = [within];
		
		selectors[s].split(" ").forEach(function(selector,k,a){
	
			if(selector.indexOf(">")+1){
				
				root = $.getElementsByParent(selector);
				
				if(k+1 == a.length){
					nodes.add(root);
					
				}
				
				return true;
				
			} else if(selector.indexOf('[')+1){
				
				///look for attribute's by searching for sqaure brackets //
				root = $.getElementsByAttributes(root, selector);
			
				if(k+1 == a.length){
					nodes.add(root);
				}
				
				return true;
			} else if(selector.indexOf("~")+1){
				
				root = $.getElementsBySiblingCombinator(root, selector);
				
				if(k+1 == a.length){
					nodes.add(root);
					
				}
				
				return true;
		
			} else if(selector.indexOf("+")+1){
				
				root = $.getElementsByAdjacentSibling(root, selector);
				
				if(k+1 == a.length){
					nodes.add(root);
					
				}
				
				return true;
		
			} else if(selector.indexOf(":")+1){
				//look for pseudo selectors
				root = $.parsePseudoSelectors(root, selector);
				
				if(k+1 == a.length){
					nodes.add(root);
				}
				
				return true;
				
			}  else if((selector.indexOf("#") === 0 && selector.match(/^\#[\w-]+$/)) || selector.match(/\w+\#[\w-]+/)) {
				
				var element = $.getElementById(selector);
			
				if(element){
					root = (element instanceof Array) ? element : [element];
					
					if(k+1 == a.length){
						nodes.add(root);
						
					}
				}
				
				return true;
				
			}  else if (selector.indexOf(".") !== false){
				
				var period_pos = selector.indexOf(".");
				
				var left_bracket_pos = selector.indexOf("[");
				var right_bracket_pos = selector.indexOf("]");
				
				if(period_pos+1 && !(period_pos > left_bracket_pos && period_pos < right_bracket_pos)) {
					
					root = $.getElementsByClassName(selector, root[0]);
					
					if(k+1 == a.length){
						nodes.add(root);
					}
					
					return true;
				}
			}
		
			//Tag selectors - no class or id specified.
			root = $.getElementsByTagName(root, selector);
			
			if(k+1 == a.length){
				nodes.add(root);
			}
			
			return true;
		});
	
	}
	
	return nodes;
};


$.getElementById = function(selector){
	
	var parts = selector.split("#");
	var element = document.getElementById(parts[1]);
	return element;
};


$.getElementsByClassName = function(selector, root){

	var parts = selector.split('.');
	
	var nodes = root.getElementsByTagName(parts[0] || '*');
	var elements = [],className = parts[1], node, cur_class_name,len = nodes.length,x=0;
	var rg = RegExp("\\b"+className+"\\b");
	
	do{
		node = nodes[x];
		cur_class_name = node.className;
		if (cur_class_name.length && (cur_class_name == className || rg.test(cur_class_name))){
			
			elements.push(node);
        }
		x++;
	} while(x<len);
	
	return elements;
};


$.getElementsByTagName = function(root, tag) {
	root = (root instanceof Array) ? root : [root];

	var matches = [],len1 = root.length,len2,x=0,i=0,nodes,elements;

	for(x=0;x<len1;x++){
	
		nodes = root[x].getElementsByTagName(tag || '*');
		elements = [];
		len2 = nodes.length;
		
		for(i=0;i<len2;i++){
			elements.push(nodes[i]);
		}
		matches = matches.concat(elements);
	}
	
	return matches;
};


$.getElementsByAttributes = function(within, selector){
	var f = 1;
	var tag,attr,operator,value;
	
	if (selector.match(/^(?:(\w*|\*))\[(\w+)([=~\|\^\$\*]?)=?['"]?([^\]'"]*)['"]?\]$/)) {
		tag = RegExp.$1;
		attr = (typeof sb.nodeList.attrConvert == 'function') ? sb.nodeList.attrConvert(RegExp.$2) : RegExp.$2;
		
		operator = RegExp.$3;
		value = RegExp.$4 ||'';
	}
	
	var elements = $.getElementsByTagName(within, tag);
	
	within = elements.filter(function(el,k,a){
	
		el.attrVal = el.getAttribute(attr, 2);
		
		//if attribute is null
		if(!el.attrVal){
			return false;
		}
		
		switch(operator){
			case '=':
				if(el.attrVal != value){
					return false;
				}
				break;
				
			case '~':
			
				if(!el.attrVal.match(new RegExp('(^|\\s)'+value+'(\\s|$)'))){
					return false;
				}
				break;
				
			case '|':
			
				if(!el.attrVal.match(new RegExp(value+'-'))) {
					return false;
				}
				break;
				
			case '^':
				if(el.attrVal.indexOf(value) !== 0){
					return false;
				}
				break;
				
			case '$':
				if(el.attrVal.lastIndexOf(value)!=(el.attrVal.length-value.length)){
					return false;
				}
				break;
				
			case '*':
				if(!(el.attrVal.indexOf(value)+1)){
					return false;
				}
				break;
				
			default:
				if(!el.getAttribute(attr)){
					return false;
				}
		}
		
		return true;
		
	});
	
	return within;
	
};


$.getNextSibling = function(node){
	while((node = node.nextSibling) && node.nodeType != 1){}
	return node;
};


$.getPreviousSibling = function(node){
	while((node = node.previousSibling) && node.nodeType != 1){}
	return node;
};


$.getFirstChild = function(node){
	node = node.firstChild;
	while (node && node.nodeType && node.nodeType == 3) {
		node = $.getNextSibling(node);
	}
	return node;	
};


$.getLastChild = function(node){
	
	node = node.lastChild;
	while (node && node.nodeType && node.nodeType == 3) {
		node = $.getPreviousSibling(node);
	}
	return node;
};


$.getElementsByParent = function(selector){
	var tags = selector.split(">");

	var elements = $.getElementsByTagName([document.body], tags[1]);
	
	var rg = new RegExp(tags[0], 'i');
	var nodes = [];
	var len = elements.length;
	
	for(var n=0;n<len;n++){
		if(rg.test(elements[n].parentNode.nodeName)){
			elements[n].sbid = sb.uniqueID();
			nodes.push(elements[n]);
		}
	}
	
	return nodes;	
	
};


$.getElementsBySiblingCombinator = function(within, selector){
	var parts = selector.split("~");
			
	var nodeName = parts[0],siblingNodeName = parts[1],elements = [],x=0,nn;

	var siblings = $.getElementsByTagName(within, nodeName);
	var len = siblings.length;
	
	for(x=0;x<len;x++){
		var node = siblings[x];
		
		while((node = node.nextSibling)){
			nn = node.nodeName.toLowerCase();
			if(nn == nodeName){break;}
			if(node.nodeType == 1 && nn == siblingNodeName){
				node.sbid = sb.uniqueID();
				elements.push(node);
			}
		}
	}
	return elements;
	
};


$.getElementsByAdjacentSibling = function(within, selector){
	var parts = selector.split("+");
			
	var nodeName =parts[0];
	var adjacentNodeName = parts[1].toUpperCase();
	var elements = $.getElementsByTagName([document.body], nodeName);
	elements = (!elements.length) ? [elements] : elements;
	//put in the proper adajcent siblings
	var nodes = [], x=0,node,len = elements.length;
	for(x=0;x<len;x++){
		node = $.getNextSibling(elements[x]);
		if(node && node.nodeName == adjacentNodeName){
			nodes.push(node);
		}
	}
	
	return nodes;
			
};


$.parsePseudoSelectors = function(within, selector){

	var nth,notSelector,elements = [],parts = selector.split(":");
	
	selector =parts[0];
	var pseudo = parts[1];
	
	var nodes = $.getElementsByTagName(within, selector);
	var parentNode;
	
	nodes.forEach(function(node,k,a){
		
		switch(pseudo){
			
			case 'before':
		
				var bf = new sb.element({
					nodeName : 'span',
					innerHTML : 'ddd'
				}).appendToTop(node);
				elements.push(bf);
			
				break;
				
			case 'first-child':
				
				if(!$.getPreviousSibling(node)){
					elements.push(node);
				}
				break;
				
			case 'last-child':
				if(!$.getNextSibling(node)){
					elements.push(node);
				}
				break;
			
			case 'empty':
				if(node.innerHTML ===''){
					elements.push(node);
				}
				break;
				
			case 'only-child':
			
				if(!$.getPreviousSibling(node) && !$.getNextSibling(node)){
					elements.push(node);
				}
					
				break;
				
			default: 
				
			if(pseudo.indexOf('not')+1){
				notSelector = pseudo.match(/not\((.*?)\)/);
				
				if(node.nodeName.toLowerCase() != notSelector[1]){
					elements.push(node);
				}
			}
		}
		
		 
	});

	return elements;
};

sb.$ = $;


sb.browser ={
	
	
	ie6 : 0,
	
	
	getAgent : function(){
		
		var opera = new RegExp("opera/(\\d{1}.\\d{1})", "i");
		var safari = new RegExp("safari/(\\d{3})", "i");
		var firefox = new RegExp("firefox/(\\d{1}.\\d{1})", "i");
		var agent = window.navigator.userAgent;
		var str;
		
		if(window.opera && window.document.childNodes) {
			this.agent = 'op';
			str = agent.match(opera);
			this.version = str[1];
			
		} else if (document.all && !window.XMLHttpRequest && document.compatMode){
			this.agent = 'ie';
			this.version = 6;
			sb.browser.ie6 =1;
		}  else if (document.all && window.XMLHttpRequest && document.compatMode){
			this.agent = 'ie';
			this.version = 7;
	
		} else if(agent.match(firefox)){
			this.agent = 'ff';
			str = agent.match(firefox);
			this.version = str[1];
		} else if(agent.match(safari)){
			
			str = agent.match(safari);
			
			this.agent = 'sf';
			if(agent.match(/iphone/i)){
				this.agent += '_iphone';
			} else if(agent.match(/ipod/i)){
				this.agent += '_ipod';
			}
			
			if(str[1] < 400){
				this.version =1;
			} else if(str[1] < 500){
				this.version =2;
			} else if(str[1] < 600){
				this.version =3;
			}
			
		} else {
			this.agent='other';
		}
	
		return this.agent;
	},
	
	
	measure : function(){
		sb.browser.w=0; sb.browser.h =0;
		if( typeof window.innerWidth == 'number' ) {
		    sb.browser.w = window.innerWidth;
		    sb.browser.h = window.innerHeight;
		} else if( window.document.documentElement && ( window.document.documentElement.clientWidth || window.document.documentElement.clientHeight ) ) {
		    sb.browser.w = document.documentElement.clientWidth;
		    sb.browser.h = document.documentElement.clientHeight;
		}
		
		return [sb.browser.w, sb.browser.h];
	},
	
	
	init : function(){
	
		this.getAgent();
		this.measure();
	}
};

sb.browser.init();

sb.objects = {
		
	
	serialize : function(o){
		var str, arr, a=[];
	
		sb.objects.forEach.call(o, function(value, prop, object){
			
			if(sb.typeOf(value) == 'array'){
				
				value.forEach(function(v, k){
					a.push(prop+'[]='+encodeURIComponent(v));
				});
				
			} else if(typeof value =='object'){
				
				sb.objects.forEach.call(value, function(v2, k2, o2){
			
					if(typeof v2 == 'object' || sb.typeOf(v2) == 'array'){
						
						str = sb.objects.serialize(v2);
						arr = str.split("&");
						str ='';
						arr.forEach(function(v3, k3, a3){
							arr[k3]= v3.replace(/(.*?)=(.*?)/g, prop+"['"+k2+"']['$1']=$2");
							
						});
				
						a.push(arr.join("&"));
						
					} else {
						a.push(prop+"['"+k2+"']="+encodeURIComponent(v2));
					}
				});
			} else {
				a.push(prop+'='+encodeURIComponent(value));
			}
		});
			
		return a.join("&");
	},
	
	
	infuse : function(from, to){
		
		to = to || this;
		from = from || {};
		sb.objects.forEach.call(from, function(val,prop,o){
		
			try{ to[prop] = val;} catch(e){}
		});
		from = null;
		return to;
	},
	
	
	
	copy : function(o){
		var copy = {};
		
		sb.objects.forEach.call(o, function(val,prop,obj){
			copy[prop] = val;
		});
		
		return copy;
	},
	
	
	dump : function(o, pre){
			var prop,str ='';
			sb.objects.forEach.call(o, function(v,p,o){
				try{
					str+="\n\n"+p+' = '+v;
				} catch(e){
					str += "\n"+p+' = CANNOT PROCESS VALUE!';
				}
			});
			
			if(!pre){ return str;} else { return '<pre style="margin:5px;border:1px;padding:5px;">'+str+'</pre>';}
	
	},
	
	forEach : function(func){
		for(var prop in this){
			if(this.hasOwnProperty(prop) && !sb.objects[prop] || prop =='infuse'){
				func(this[prop], prop, this);
			}
		}
	}
};


//sb.nodeList 
sb.nodeList = function(params){
	
	for(var prop in params){
		this[prop] = params[prop];
	}
	
	//initialize internal arrays
	this.nodes = [];
	this.sb_ids = {};
	
	var nls= this;
	['forEach', 'map', 'filter', 'every', 'some', 'indexOf', 'lastIndexOf', 'inArray'].forEach(function(v,k,a){
		nls[v] = function(func){
			return nls.nodes[v](func);
		};
	});
	
};

sb.nodeList.prototype = {
	
	
	selector : '',
	
	
	getElementPrototypes : function(){
	
		if(Element.emulated){
			var x,prop,ep = Element.prototype,len = this.nodes.length;
		
			for(x=0;x<len;x++){
				for(prop in ep){
					this.nodes[x][prop] = ep[prop];
				}
			}
			
		}
	},
	
	
	empty : function(){
		this.nodes = [];
		
	},
	
	
	setSelector : function(selector){
		this.selector = sb.nodeList.cleanSelector(selector);
		
	},
	
	
	add : function(nodes){
		nodes = (nodes instanceof Array || (typeof NodeList !='undefined' && nodes instanceof NodeList)) ? nodes : [nodes];
		
		var len = nodes.length;
		
		var prop,x=0,node;
		
		var emulated = Element.emulated;
		
		var ep = Element.prototype;
		
		for(x=0;x<len;x++){
			node=nodes[x];
			
			if(!node.sb_id ){
				node.sb_id = sb.nodeList.sb_id++;
			}
			
			if(!this.sb_ids[node.sb_id]){
				
				if(emulated){
					
					for(prop in ep){
						node[prop] = ep[prop];
					}
				}
				this.nodes.push(node);
				this.sb_ids[node.sb_id] = true;
			}
		}
	},
	
	drop : function(el){
		
		var t = this;
		el = $(el);
		
		this.nodes = t.nodes.filter(function(v){
			if(sb.typeOf(el) == 'sb.element'){
				return v != el;
			} else {
				return !el.nodes.some(function(v1){return v===v1;});
			}
			
		});
		this.length = this.nodes.length;
		
		return this;
	},
	
	
	firePerNode : function(func){
		
		if(typeof func == 'function'){
			var args = [];
			var len = arguments.length;
			for(var x=1;x<len;x++){
				args.push(arguments[x]);
			}
			this.nodes.forEach(function(node){
				func.apply(node, args);
			});
		}
		
		return this;
	},
	
	
	length : function(){
		return this.nodes.length;
	},
	
	
	styles : function(styles){
		this.firePerNode(Element.prototype.styles, styles);
	},
	
	
	typeOf : function(){
		
		return 'sb.nodeList';
	}
	
};

sb.nodeList.cleanSelector = function(selector){
	
	selector = selector.replace(/^\s+/, '');
	selector = selector.replace(/\s+$/, '');
		
	//remove excess space after commas
	selector = selector.replace(/, /g, ',');
	selector = selector.replace(/\s*([>~\+])\s*/g, "$1");
	return selector;
};


sb.nodeList.sb_id = 0;


sb.nodeList.singleTags = ['html', 'body', 'base', 'head', 'title'];



sb.ajax = function(params){ 
	
	try{this.o=new window.XMLHttpRequest();}catch(e){
		try{this.o=new window.ActiveXObject("Microsoft.XMLHTTP");}catch(e3){
			throw('This browser does not support surebert');
		}
	}
	
	sb.objects.infuse(params, this);
	
	if(sb.typeOf(params.data) == 'object'){
		this.data = sb.objects.serialize(params.data);
	}
};


sb.ajax.log = function(){};


sb.ajax.defaultMethod = 'post';


sb.ajax.defaultFormat = 'text';


sb.ajax.defaultURL = '';

sb.ajax.prototype = {
	
	
	completed : 0,
	
	
	debug : this.debug || 0,
	
	
	data : this.data || '',
	
	
	format : this.format || '',
	
	
	async : this.async,
	
	
	local : this.local || 0,
	
	
	onreadystatechange : function() {
		var message = '';
		var js='';
		
		if (this.o.readyState != 4 || this.completed == 1) {return true; }
		
		//for backwards compatibility, remove soon
		if(typeof this.handler == 'function'){
			this.onResponse = this.handler;
		}
		
		this.completed =1;

		this.contentType = this.o.getResponseHeader("Content-Type");
		this.contentLength = this.o.getResponseHeader("Content-Length");
		
		if(this.contentLength > this.maxContentLength){
			
			//this.addToLog(7);
			if(typeof this.onContentLengthExceeded == 'function'){
				this.onContentLengthExceeded();
			}
			this.o.abort();
			return;
		}
		
		if(this.format === ''){
			if(this.contentType){
				if(this.contentType.match('application/json')){
					this.format = 'json';
				} else if (this.contentType.match('text/javascript')){
					this.format = 'javascript';
				} else if (this.contentType.match('text/xml')){
					this.format = 'xml';
				} else if(this.contentType.match('boolean/value')){
					this.format = 'boolean';
				}
			} else {
				this.format = sb.ajax.defaultFormat;
			}
		} 
		
		this.log(2, "\nHEADERS\nStatus: "+this.o.status+"\nStatus Text: "+this.o.statusText+"\n"+this.o.getAllResponseHeaders()+"\nRESPONSE: \n"+(this.o.responseText ||'PAGE WAS BLANK ;(')+"\n");
		
		var cont = true;
		
		if(typeof this.timer !='undefined'){
			window.clearInterval(this.timer);
		}
		
		cont = this.onHeaders.call(this.o, this.o.status, this.o.statusText);	
		
		if(cont === false || (this.o.status != 200 && this.local !==1)){
			return false;
		}
	
		switch(this.format){
			
			case 'head':
				if(typeof this.header ==='undefined'){
					this.response = this.o.getAllResponseHeaders();
				} else {
					this.response = this.o.getResponseHeader(this.header);
				
				}
				break;
			case 'xml':
			
				if(this.o.responseXML !== null){ 
					this.response = this.o.responseXML.documentElement;
				} else { 
					this.log(3);
				}
				break;
			
			case 'js':
				js =  this.o.responseText;
				break;
				
			case 'json':
				js = 'this.response='+this.o.responseText;
				break;
				
			case 'boolean':
				this.response = (this.o.responseText === 0) ? 0 : 1;
				break;
			
			default:
				this.response = this.o.responseText;
		}
	
		if(js !==''){
			try{
				 eval(js);
			}catch(e2){
				this.log(4);
			}
		}
		
		this.onResponse(this.response);
		
		if(typeof this.node !='undefined'){
			
			if(sb.$(this.node)){
				this.node = sb.$(this.node);
				if(typeof this.node.value !='undefined'){
					this.node.value = this.o.responseText;
				} else {
					this.node.innerHTML = this.o.responseText;
				}
			} else {
				this.addToLog(5);
			}
		}
		
		this.o.abort();
		return this; 
	},

	log : function(logId, message){
		if(this.debug ==1){
			
			var info = (message || '')+"\nSENT\nURL: ";
			if(this.method == 'get'){
				info += '<a href="'+this.url+'?'+this.data+'">'+this.url+'?'+this.data+'</a>';
			} else {
				info += this.url;
			}
			
			info += "\nMETHOD: "+this.method+"\nFORMAT: "+this.format+"\nASYNC: "+this.async+"\nDATA: "+this.data;
			
			sb.ajax.log(logId, info);
			if(typeof this.onLog == 'function'){
				
				this.onLog(logId, info);
			}
		}
	},
	
	
	timeout : 0,
	
	
	fetch : function(url) {
		this.completed =0;
		
		this.method = (typeof this.method !='undefined') ? this.method : sb.ajax.defaultMethod; 

		var t=this;
		url = url || t.url || sb.ajax.defaultURL;
		t.url =url;
	
		if(!t.o){
			return false;
		}
		
		if(typeof t.async =='undefined'){
			t.async=true;
		}
		
		t.log(1);
		
		t.o.onreadystatechange = function(){t.onreadystatechange();};
	
		if(sb.typeOf(t.data) == 'object'){
			t.data = sb.objects.serialize(t.data);
		}
	
		if(t.method=='get' && t.data !== undefined){
			url = url+'?'+t.data;
		}
		
		if(t.timeout){
			
			t.count = 0;
			
			t.timer = window.setInterval(function(){
				if(t.count >= t.timeout){
					t.abort();
					t.count = 0;
					
					if(typeof t.onTimeout == 'function'){
						t.onTimeout();
					}
					
					window.clearInterval(t.timer);
				} else {
					t.count++;
				}
			}, 1);
		}
		
		if(!url){
			throw('A sb.ajax instance has no url set? But is trying to send the following data: '+t.data);
		}
		
		t.o.open(t.method, url, t.async);
	
		if(t.method=='post'){
			try{
				t.o.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			}catch(e){}
		}
		
		try{t.o.send(t.data); }catch(e1){}
		
		if (!t.async ){ t.onreadystatechange();}
		
	},
	
	
	abort : function(){
		this.o.abort();
		
		if(typeof this.onmillisec !='undefined'){
			this.timer.reset();
		}
		
		this.onAbort();
		
	},
	
	
	onResponse : function(){},
	
	
	onTimeout : function(){},
	
	
	onHeaders : function(status, statusText){},
	
	
	onAbort : function(){}
};

sb.dom = {

	
	
	onReady : function(o){
		var found =0, timer, count=0;
		o.args = o.args || [];
		o.interval = o.interval || 10;
		
		o.tries = o.tries || 600;
		if(o.tries == -1){o.tries =99999999;}
		
		if(typeof o.onReady=='function'){
			
			timer = window.setInterval(function(){
				
				count +=1;
				
				if(count >= o.tries){
					window.clearTimeout(timer);
					
					if(typeof o.onTimeout=='function'){
						o.onTimeout(o.id);
					}
					return;
				}
				
				if(o.id == 'body' && document.body){
					window.clearTimeout(timer);
					found=1;
					o.id = document.body;
				} else if(o.id !='body' && sb.$(o.id)){
					
					window.clearTimeout(timer);
					found=1;
				}
				
				if(found == 1){
					o.onReady.apply(sb.$(o.id), o.args);
					
				}
				
			}, o.interval);
			
		} else {
			throw('sb.dom.onReady: You object argument must have a onReady property that runs when the dom element "'+o.id+'" is available');
		}
	}
	
};


Array.prototype.inArray = function(val){
	return this.some(function(v){return v===val;});
};


Array.prototype.remove = function(values){
	
	return this.filter(function(v){
		if(sb.typeOf(values) !='array'){
			return v != values;
		} else {
			return !values.inArray(v);
		}
	});
};


String.prototype.hex2rgb = function(asArray){
	var hex = this.replace(/(^\s+|\s+$)/).replace("#", "");
	var rgb = parseInt(hex, 16); 
	var r   = (rgb >> 16) & 0xFF;
	var g = (rgb >> 8) & 0xFF; 
	var b  = rgb & 0xFF;
	
	if(asArray){
		return [r,g,b];
	} else {
		return 'rgb('+r+', '+g+', '+b+')';
	}
};
	

String.prototype.toCamel = function(){
	return String(this).replace(/-\D/gi, function(m){
		return m.charAt(m.length - 1).toUpperCase();
	});
};

sb.styles = {
	
	
	numRules : 1,
	
	
	sheets : [],
	
	
	
	pxProps : ['fontSize', 'width', 'height', 'padding', 'border', 'margin', 'left', 'top']
	
};


sb.events = {
	
	
	add : function() {
		
	    if(window.addEventListener){
	   
	        return function(el, type, fn) {
	        	el = sb.$(el);
	        	var f = function(e) {
	        		
	        		var sb_target = e.target;
	        		var sb_related_target = e.relatedTarget;
	        		delete e.target;
	        		delete e.relatedTarget;
	        		e.__defineGetter__("target", function() { return sb.events.distillTarget(sb_target); });
	        		e.__defineGetter__("relatedTarget", function() { return sb.events.distillTarget(sb_related_target); });
	                fn.call(el, e);
	            };
	        	var evt = {el:el, type:type, fn:f, remove : sb.events.removeThis};
	            el.addEventListener(type, f, false);
	            return sb.events.record(evt);
	        };
	    } else if ( window.attachEvent){
	        return function(el, type, fn) {
	        	el = sb.$(el);
	        	var tar = false;
				
	            var f = function() {
	            	var e = window.event;
	            	var tar = null;
		            switch(e.type){
						case 'mouseout':
							tar = e.relatedTarget || e.toElement;
							break;
						
						case 'mouseover':
							tar = e.relatedTarget || e.fromElement;
							break;
					}
					
					if(tar){
	            		e.relatedTarget = sb.events.distillTarget(tar);
	            	} 
	            	
	            	if(e.srcElement){
	            		e.target = sb.events.distillTarget(e.srcElement);
	            	}
	            	
	            	e.preventDefault = function(){
	            		e.returnValue = false;
	            	};
	            	
	            	e.stopPropagation = function(){
	            		e.cancelBubble = true;
	            	};
	            	
	                fn.call(el, e);
	            };
	            var evt = {el:el, type:type, fn:f, remove : sb.events.removeThis};
	            el.attachEvent('on'+type, f);
	            return sb.events.record(evt);
	        };
	    }
	}(),
	
	
	removeThis : function(){
		sb.events.remove(this);
	},
	
	
	log : [],
	
	
	record : function(evt){
		sb.events.log.push(evt);
		return evt;
	},

		
	
	remove : function(evt){
	
		if (evt.el.removeEventListener){
			evt.el.removeEventListener( evt.type, evt.fn, false );
		} else if (evt.el.detachEvent){
			evt.el.detachEvent( "on"+evt.type, evt.fn );
		}
		
	},
	
	
	removeAll: function(){
		sb.events.log.forEach(function(evt){
			sb.events.remove(evt);
		});
		sb.events.log=[];
	},
	
	
	distillTarget : function(tar){
		if (tar && tar.nodeType && (tar.nodeType== 3 || tar.nodeName == 'EMBED')){
			tar = tar.parentNode;
		}
	
	   return $(tar);
	}
	
};


sb.element = function(o){
	var el,c;

	if(sb.typeOf(o) == 'sb.element'){
		return o;
	}
	
	if(typeof o == 'object' ){
		
		if(o.tag == 'input' && sb.dom.createNamedElement){
			
			el = new sb.dom.createNamedElement(o.type, o.name, o.checked);
			
		} else {
			el = document.createElement(o.tag);
		}
	}
	
	//copy properties from the sb.element prototype
	if(Element.emulated){
		sb.objects.infuse(Element.prototype, el);
		o = sb.objects.copy(o);
	}
	
	if(typeof o.addAttributes !='undefined'){
		el.styles(o.addAttributes);
		delete o.addAttributes;	
	}
	
	if(typeof o.styles !='undefined'){
		el.styles(o.styles);
		delete o.styles;	
	}
	
	if(typeof o.children !='undefined'){
		var len = o.children.length;
		for(c=0;c<len;c++){
			el.appendChild(new sb.element(o.children[c]));
		}
		delete o.children;
	}
	
	if(typeof o.events !='undefined'){
		sb.objects.forEach.call(o.events, function(func,event,obj){
			el.event(event, func);
		});
		
		delete o.events;
	}
	
	//copy additional props from o
	sb.objects.infuse(o, el);
	
	if(sb.browser.ie6){
		//remove attributes for ie's sake
		el.removeAttribute('tag');
	}
	
	return el;
};


if(typeof Element == 'undefined'){
		Element = function(){};
		Element.emulated = true;
		Element.prototype = {};
}


Element.prototype.$ = function(selector){
	return $(selector, this);
};
	

Element.prototype.addClassName = function(className){
	this.className += ' '+className;
	
	return this;
};


Element.prototype.append = function(el){return this.appendChild(sb.$(el));};


Element.prototype.appendTo = function(el){
	return sb.$(el).appendChild(this);
};

	
Element.prototype.appendToTop = function(el){
	el = sb.$(el);

	if(el.childNodes.length ===0){
		return this.appendTo(el);
	} else {
		return this.appendBefore(el.firstChild);
	}
};


Element.prototype.appendAfter = function(after){
	var a = $(after);
	
	if(a.nextSibling){
		while((a = a.nextSibling) && a.nodeType != 1){}
		var nxtSib = a;
	}

	if(nxtSib){
		return nxtSib.parentNode.insertBefore(this, nxtSib);
	} else {
		return this.appendTo(a.parentNode);
	}
	
};


Element.prototype.appendBefore = function(before){
	before = sb.$(before);
	return before.parentNode.insertBefore(this, before);
};


Element.prototype.getX = function(){
	var x = 0, el=this;
	while(el !== null){
		x += el.offsetLeft;
		el = el.offsetParent;
	}
	return x;
};


Element.prototype.getY = function(){
	var y = 0, el=this;
	while(el !== null){
		y += el.offsetTop;
		el = el.offsetParent;
	}
	return y;
};


Element.prototype.hasClassName = function(classname){
	
	return this.className.match("\\b"+classname+"\\b");
};


Element.prototype.remove = function(){
	if(typeof this.parentNode !='undefined'){
		this.parentNode.removeChild(this);
	}
	return this;
};


Element.prototype.removeClassName = function(className){
	this.className = this.className.replace(new RegExp("\b*"+className+"\b*"), "");
	return this;
};


Element.prototype.replace = function(node){
	node = sb.$(node);
	if(typeof node.parentNode !='undefined'){
		node.parentNode.replaceChild(this, node);
	}
	node = null;
	return this;
};


Element.prototype.event = function (evt, func){
	
	var event = sb.events.add(this, evt, func);
	
	//this.eventsAdded.push(event);
	return event;
	
};


Element.prototype.eventsAdded = [];


Element.prototype.events = function(events){
	for(var event in events){
		if(typeof events[event] =='function'){
			this.event(event, events[event]);
		}
	}
	
	return this;
};


Element.prototype.eventRemove = function (evt){
	sb.events.remove(evt);
	return this;
};


Element.prototype.eventsRemoveAll = function(){
	this.eventsAdded.forEach(function(evt){
		sb.events.remove(evt);
	});
	this.eventsAdded = [];
	return this;
};


Element.prototype.styles = function(params){
	
	for(var prop in params){
		if(params.hasOwnProperty(prop)){
			try{
			this.setStyle(prop, params[prop]);
			}catch(e){}
		}
	}
	
	return this;
};


Element.prototype.getStyle = function(prop){
	var val;
	
	if(prop.match(/^border$/)){
		prop = 'border-left-width';				
	} 
	
	if(prop.match(/^padding$/)){
		prop = 'padding-left';				
	}
	
	if(prop.match(/^margin$/)){
		prop = 'margin-left';		
	}
	
	if(prop.match(/^border-color$/)){
		prop = 'border-left-color';				
	}
	
	if (this.style[prop]) {
		val = this.style[prop];
		
	} else if (this.currentStyle) {
		
		prop = prop.toCamel();
		val = this.currentStyle[prop];
		
	} else if (document.defaultView && document.defaultView.getComputedStyle) {
			
		prop = prop.replace(/([A-Z])/g, "-$1");
		prop = prop.toLowerCase();
		
		val = document.defaultView.getComputedStyle(this,"").getPropertyValue(prop);
		
	} else {
		val=null;
	}
	
	if(prop == 'opacity' && val === undefined){
		val = 1;
	}
	
	if(val){
		if(typeof val == 'String'){
			
			val = val.toLowerCase();
			if(val == 'rgba(0, 0, 0, 0)'){val = 'transparent';}
		
			if(typeof sb.colors.html !='undefined'){
				if(sb.colors.html[val]){
					val = sb.colors.html[val].hex2rgb();
				}
			}
			
			if(val.match("^#")){
				val = val.hex2rgb();
			}
		
		}
		
		return val;
	} else {
		return null;
	}

};


Element.prototype.setStyle = function(prop, val){
	
		if(sb.styles.pxProps.inArray(prop) && val !=='' && !val.match(/em|cm|pt|px|%/)){
			val +='px';
		}
		
		if(prop == 'opacity' && typeof this.style.filter == 'string' && typeof this.style.zoom == 'string'){
			this.style.opacity = val;
			this.style.zoom = 1;
			this.style.filter = "alpha(opacity:"+val*100+")";
			
			
		} else {
		
			if(prop == 'cssFloat' && typeof this.style.styleFloat == 'string'){
				prop = 'styleFloat';
			}
			
			if(typeof this.style[prop] == 'string'){
				this.style[prop] = val;
			} else {
				throw("style["+prop+"] does not exist in this browser's style implemenation");
			}
		}
};

Element.prototype.typeOf = function(){
	return 'sb.element';
};

if(!Array.prototype.forEach){
	sb.include('js1_5');
}

if(sb.browser.ie6){
	sb.include('ie6');
} else {
	
	sb.ie6 = {
		pngFix: function(){},
		pngFixBg: function(el){}
	};
}

sb.dom.onReady({
	id : 'body',
	onReady : function(){
		sb.onbodyload.forEach(function(v){
			if(typeof v == 'function'){
				v();
			}
		});
	},
	tries : 600,
	ontimeout : function(){
		if(typeof sb.onbodynotready =='function'){
			sb.onbodynotready();
		}
	}
});

sb.events.add(window, 'resize', sb.browser.measure);
sb.events.add(window, 'unload', function(e){
	sb.onleavepage.forEach(function(v){
		if(typeof(v) =='function'){v(e);}
	});
	sb.events.removeAll();
});
sb.swf = function(params){
	if(typeof params == 'object'){
		sb.objects.infuse(params, this);
	} 
	this.width = this.width || '400px';
	this.height = this.height || '300px';
	this.bgColor = this.bgColor || '#FFFFFF';
	this.version = this.version || 5;
	this.allowFullScreen = this.allowFullScreen || 'true';
	this.alt = this.alt || '';
	this.src = this.src || '';
	this.wmode = this.wmode || '';
	if(typeof this.id =='undefined'){
		this.id = 'sb_swf_'+sb.swf.instanceId;
		sb.swf.instanceId++;
	}
};


sb.swf.prototype = {
	
		
	getInterface : function(){
		var movieName = this.id;
		if (navigator.appName.indexOf("Microsoft") != -1) {
            return window[movieName];
        } else {
        	return document.getElementById(movieName);
        }
	},
	
	
	toHTML : function(){
		var html='';
		
		if(this.version > sb.swf.version){
			return this.alt;
		}
		
		if(sb.swf.format=='embed'){
			
			html = '<embed type="application/x-shockwave-flash" src="'+this.src+'"  id="'+this.id+'" name="'+this.id+'" wmode="'+this.wmode+'" allowScriptAccess="always" allowFullScreen="'+this.allowFullScreen+'" bgcolor="'+this.bgColor+'" ';
				
			if(typeof this.flashvars =='object'){
				
				html +='FlashVars="'+sb.objects.serialize(this.flashvars)+'" ';
			
			}
			
			html +=' width="'+this.width+'" height="'+this.height+'"  />';
		
		} else if(sb.swf.format=='object'){
				
				html = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="'+this.width+'" height="'+this.height+'" id="'+this.id+'" ><param name="movie" value="'+this.src+'" /><param name="bgcolor" value="'+this.bgColor+'" /><param name="wmode" value="'+this.wmode+'" /><param name="allowFullScreen" value="'+this.allowFullScreen+'" /><param name="allowScriptAccess" value="always" />';
				if(typeof this.flashvars =='object'){
					html +='<param name="FlashVars" value="'+sb.objects.serialize(this.flashvars)+'">';
				}
				html +='</object>';
				
		}
		return html;
		
	},
	
	
	embed : function(el){
		el = $(el);
		el.innerHTML = this.toHTML();
		return el;
	}
};

sb.swf.infuse = sb.objects.infuse;

sb.swf.infuse({
	
	version : 4,
	
	
	swfs : [],

	
	instanceId : 0,
	
	
	check : function(){
		var version, description;
		try{
			version = new RegExp("\\d{1}\.\\d{0,5}", "i");
			if(window.navigator.plugins["Shockwave Flash"]){
				description = window.navigator.plugins["Shockwave Flash"].description;
				if(description.match(version)){
					sb.swf.version = description.match(version);
				}
				
			}
		} catch(e){sb.swf.version=0;}
		return sb.swf.version;
	},
	
	
	testIe : function(){
		try{
			
			if(new window.ActiveXObject("ShockwaveFlash.ShockwaveFlash." + sb.swf.version)){
				return false;
			}
		} catch(e){return true;}
			
	},
	
	
	ieCheck : function(){	
		try{
			//THERE MUST BE A BETTER SOLUTION
			while(!sb.swf.testIe()){
				sb.swf.version++;
			}
			sb.swf.version--;
			return sb.swf.version;
		} catch(e){
			return true;
		}
	},
	
	
	cleanup : function() {
		try{
		sb.$('object').forEach(function(obj){
			obj.style.display='none';
			for(var prop in obj){
				if(typeof obj == 'function'){obj[prop] = function(){};}
			}
		});
		}catch(e){}
	},
	
	
	unload : function() {
		__flash_unloadHandler = function(){};
		__flash_savedUnloadHandler = function(){};
		window.attachEvent( "onunload", sb.swf.cleanup );
		
	},
	
	
	detect : function(){
		for(var x=0;x<window.navigator.plugins.length;x++){
		//	sb.objects.alert(navigator.plugins[x]);
		}
		if (window.navigator.plugins && window.navigator.plugins.length){
			sb.swf.format = 'embed';
			return sb.swf.check();
		} else if(sb.browser.agent =='ie'){
			sb.swf.format = 'object';
			return sb.swf.ieCheck();
		} 
	}
	
});

sb.swf.detect();

if(sb.browser.ie6){
	
	//fix for bad adobe code in IE
	var __flash__removeCallback = function(instance, name){
		if(typeof instance != 'null'){
			instance[name] = null;
		}
	};

	//cleanup flash players for IE
	window.attachEvent( "onbeforeunload", sb.swf.unload);
}
sb.include('swf');
sb.flashGate = new sb.swf({
	src : sb.base+"/FlashGate.swf",
	//src : '${swf}.swf?d='+Math.random(),
	width : 1,
	height : 1,
	bgColor : '#FF0000',
	id : 'Flashgate',
	wmode: 'transparent',
	flashvars : {
		debug : true
	}
});

sb.flashGate.debug = 0;

sb.flashGateContainer = new sb.element({
	tag : 'x',
	styles : {
		display : 'block',
		position : 'absolute',
		left : '-200px',
		top : '-200px'
	}
});

var sb_onFlashGateLoaded = [];

sb.dom.onReady({
	id : 'body',
	onReady : function(){
		sb.flashGateContainer.appendToTop('body');
		sb.flashGate.embed(sb.flashGateContainer);
		sb_onFlashGateLoaded.forEach(function(v){
			if(typeof v == 'function'){
				v();
			}
		})
	},
	tries : 600,
	ontimeout : function(){
		if(sb.flashGate.debug){
			throw('Cannot append flashGate to browser');
		}
	}
});


sb_onFlashGateLoad = function(){

	if(sb_onFlashGateLoaded && sb_onFlashGateLoaded.forEach ){
		sb_onFlashGateLoaded.forEach(function(v){
			if(typeof v == 'function'){
				v();
			}
		});
	}
	
};sb.include('flashGate');

sb.sound = function(params){
	if(!params.url){
		throw('You must pass a url to the sb.sound');
	}
	
	for(var prop in params){
		this[prop] = params[prop];
	}
	
	this.id = sb.flashGate.getInterface().sound_create(this.url, this.debug);
	sb.sound.sounds[this.id] = this;
};


sb.sound.sounds = [];


sb.sound.stopAll = function(url){
	url = url || '';
	sb.flashGate.getInterface().sounds_stop_all(url);
};



sb.sound.setGlobalVolume = function(volume){
	sb.flashGate.getInterface().sounds_set_global_volume(volume);
};


sb.sound.muteAll = function(){
	sb.flashGate.getInterface().sounds_mute_all();
};


sb.sound.muted = 0;


sb.sound.prototype = {

	duration : -1,
	
	url : '',
	
	
	id : 0,
	
	
	play : function(position, loops){
		if(!sb.sound.muted){
			position = position || 0;
			loops = loops || 0;
			return sb.flashGate.getInterface().sound_play(this.id, position, loops);
		}
	},
	
	
	stop : function(){
		return sb.flashGate.getInterface().sound_stop(this.id);
	},
	
	
	getPosition : function(){
		return sb.flashGate.getInterface().sound_get_position(this.id);
	},
	
	
	setPositionPercent : function(percent){
		return sb.flashGate.getInterface().sound_set_position_percent(this.id, percent);
	},

	
	getPositionPercent : function(){
		return sb.flashGate.getInterface().sound_get_position_percent(this.id);
	},
	
	
	setPosition : function(position){
		return sb.flashGate.getInterface().sound_set_position(this.id, position);
	},
	
	
	getVolume : function(volume){
		return sb.flashGate.getInterface().sound_get_volume(this.id);
	},
	
	
	setVolume : function(volume){
		sb.flashGate.getInterface().sound_set_volume(this.id, volume);
	},
	
	
	getPan : function(){
		return sb.flashGate.getInterface().sound_get_pan(this.id);
	},
	
	
	setPan : function(pan){
		sb.flashGate.getInterface().sound_set_pan(this.id, pan);
	},
	
	
	mute : function(){
		this.setVolume(0);
	},
	//tags.album, tags.year, tags.artist, tags.songName, tags.comment, tags.track, tags.genre
	onID3 : function(){},
	//song.sizeK, song.bytesLoaded, song.bytesTotal
	onLoad : function(){},
	//message
	onError : function(){},
	//song.position, song.length, song.percent
	onProgress : function(data){}
};