/* base-collection 1.1 */
/* Библиотека общего назначения */

//Основные функции
//Начало файла upgrade-standart.js
if(!Math.sgn) Math.sgn=function(x){return (x==0) ? 0 : ((x>0) ? 1 : -1);};
if(!Math.part) Math.part=function(x){return x-Math.floor(x);};
RegExp.prototype.superexec=function(text){
	var m,ret;
	if(this.global){
		ret=[];
		while((m=this.exec(text))!=null) ret.push(m);
	}
	else ret=this.exec(text);
	return ret;
};
String.prototype.ltrim = function(){return this.replace(/^\s+/, '');};
String.prototype.rtrim = function(){return this.replace(/\s+$/, '');};
String.prototype.trim = function(){return this.replace(/^\s+/, '').replace(/\s+$/, '');};
String.prototype.intrim=function(){return this.replace(/(\S)(\s)\s+(\S)/,'$1$2$3');};
String.prototype.supermatch=function(regexp){return regexp.superexec(this);};
String.prototype.superreplace=function(regexp,replacement){
	var ret=this, ret1;
	do{
		ret1=ret;
		ret=ret1.replace(regexp,replacement);
	}while(ret!=ret1);
	return ret;
};
String.prototype.padded=function(mask,right){
	if(right!==false) right=true;
	var pos=mask.length-this.length;
	if(pos<0) return this.valueOf();
	else if(right) return mask.substr(0,pos)+this;
	else return this+mask.substr(this.length);
};
String.prototype.reverse=function(){return this.split('').reverse().join('');};
String.prototype.toArray=function(){return this.split('');};
String.prototype.plug$=function(array,length){
	if(!length)length=2;
	return this.replace(new RegExp('\\$(\\d{1,'+length+'}|\\$)','g'),function(str,index){
		if(index=='$') return str;
		else if(+index in array) return array[+index];
		else return str;
	});
};
String.prototype.multiple=function(len){
	var ret='';
	for(;len>0;len--)ret+=this;
	return ret;
}
if(!Array.prototype.filter) Array.prototype.filter=function(callback,thisobject){
	var ret=[];
	var context=thisobject || window;
	for(var j=0;j<this.length;j++) if(callback.call(context,this[j], j, this)) ret.push(this[j]);
	return ret;
};
if(!Array.prototype.some) Array.prototype.some=function(callback,thisobject){
	var context=thisobject || window;
	for(var j=0;j<this.length;j++) if(callback.call(context,this[j], j, this)) return true;
	return false;
};
if(!Array.prototype.every) Array.prototype.every=function(callback,thisobject){
	var context=thisobject || window;
	for(var j=0;j<this.length;j++) if(!callback.call(context,this[j], j, this)) return false;
	return true;
};
if(!Array.prototype.forEach) Array.prototype.forEach=function(callback,thisobject){
	var context=thisobject || window;
	for(var j=0;j<this.length;j++) callback.call(context,this[j], j, this);
};
if(!Array.prototype.map) Array.prototype.map=function(callback,thisobject){
	var ret=[];
	var context=thisobject || window;
	for(var j=0;j<this.length;j++) ret.push(callback.call(context,this[j], j, this));
	return ret;
};
if (!Array.prototype.indexOf) Array.prototype.indexOf = function(elt, from){
    var len = this.length;
    from = Number(from) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
	if(from < 0) from += len;
    for (; from < len; from++){
		if(from in this && this[from] === elt) return from;
	}
	return -1;
};
if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(elt, from){
    var len = this.length;
    from = Number(from);
    if (isNaN(from)){
      from = len - 1;
    }
    else{
      from = (from < 0) ? Math.ceil(from) : Math.floor(from);
      if (from < 0) from += len;
      else if (from >= len) from = len - 1;
    }
    for (; from > -1; from--) if (from in this && this[from] === elt) return from;
	return -1;
};
Array.from=function(source){
	if(source.toArray) source=source.toArray();
	return Array.prototype.slice.call(source,0);
};
Array.prototype.clone=function(){return [].concat(this);};
Array.prototype.recursiveClone=function(){
	var r=[];
	for(var j=0;j<this.length;j++){
		if(this[j].recursiveClone) r[j]=this[j].recursiveClone();
		else if(this[j].clone) r[j]=this[j].clone();
		else r[j]=this[j];
	}
	return r;
};
Array.prototype.sortNum=function(){this.sort(function(a,b){return a-b;});};
Array.prototype.swap=function(a,b){var m=this[a];this[a]=this[b];this[b]=m;};
Array.prototype.random=function(){
	for(l=this.length-1;l>0;l--) this.swap(l,Math.round(l*Math.random()));
};
Array.prototype.antiObject=function(){
	var r={};
	for(var j=0;j<this.length;j++){
		r[this[j]]=j;
	}
	return r;
};
Array.prototype.recursiveToString=function(){
	var s=[];
	for(var j=0;j<this.length;j++){
		if(this[j] && this[j].recursiveToString) s[j]='['+this[j].recursiveToString()+']';
		else if(this[j] && this[j].toString) s[j]=this[j].toString();
		else s[j]=this[j];
	}
	return s.join(',');
};
Array.prototype.splitStep=function(step){
	var ret=[];
	var len=this.length-step;
	for(var j=0;j<len;j+=step) ret.push(this.slice(j,j+step));
	ret.push(this.slice(j));
	return ret;
};
Array.prototype.concatMembers=function(){
	var ret=[];
	for(var j=0;j<this.length;j++) ret=ret.concat(this[j]);
	return ret;
};
Array.prototype.transponer=function(){
	var ret=[],j,k,n=this[0].length,m=this.length;
	for(j=0;j<n;j++){
		ret[j]=[];
		for(k=0;k<m;k++) ret[j][k]=this[k][j];
	}
	return ret;
};
Array.multimetric=function me(){
	switch(arguments.length){
		case 0: return [];
		case 1: return Array(arguments[0]);
		default:
			var ret=Array(arguments[0]);
			var arg=Array.from(arguments);
			arg.shift();
			for(var i=0;i<ret.length;i++){ret[i]=me.apply(this,arg);}
			return ret;
	}
}
Array.prototype.item=function(){
	var index=Array.from(arguments).toString().split(',').map(parseInt);
	var p=this;
	for(var j=0;j<index.length;j++) p=p[index[j]];
	return p;
};
Array.prototype.multimap=function(callback,thisobject){
	var ret=[],n=this[0].length;
	var context=thisobject || window;
	for(var j=0;j<this.length;j++){
		ret.push(callback.apply(context,
			(this[j].length<n ? this[j].concat(Array(n-this[j].length)) : this[j]).concat([j, this])
		));
	}
	return ret;
};
Function.prototype.localName=function(){
	return this.toString().match(/^\s*function(?:\s+([a-z_$][a-z0-9_$]*))?s*\(/i)[1];
};
Function.prototype.isSystem=function(){
	return (/^\s*function(?:\s+(?:[A-Za-z_$][A-Za-z0-9_$]*))?\(\) \{\s*\[native code\]\s*\}\s*$/).test(this.toString());
};
//Конец файла upgrade-standart.js
//Начало файла upgrade-string.js
/* upgrade-string 1.2*/
String.prototype.template$=function(array,length){
	length= length || 2;
	var pat=new RegExp('(\\$|\\?|!)(\\d{1,'+length+'})(?:\\x28((?:[^\\x29]|\\\\\\x29)*)\\x29)?|\\$(\\$|\\?|!)','g');
	return this.replace(
		pat,
		function(str,command,index,content,ecran){
			if(ecran && ecran!=''){return ecran;}
			if(!(index in array)){ return str;}
			var t='',m=array[+index]||'';
			switch(command){
				case '$': t=m; break
				case '?': if(m!='')t=content.template$(array,length); break;
				case '!': if(m=='')t=content.template$(array,length);
			}
			return t;
		}
	);
};
String.prototype.templateCompile=function StringTemplate(array,length){
	lenght=length||2;
	var altpos=0;
	var lex=[]
	this.replace(
		new RegExp('(\\$|\\?|!)(\\d{1,'+length+'})(?:\\x28((?:[^\\x29]|\\\\\\x29)*)\\x29)?|\\$(\\$|\\?|!)','g'),
		function(str,command,index,content,ecran,pos,sourse){
			if(altpos!=pos) lex.push(sourse.substring(altpos,pos));
			if(str.length>0) lex.push(str);
			altpos=pos+str.length;
		}
	);
	lex.push(this.substring(altpos));
	return lex.toString();
}
RegExp.escape = function(str) {
	return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
//Конец файла upgrade-string.js
//Начало файла upgrade-math.js
Math.sgn=function(x){return (x==0) ? 0 : ((x>0) ? 1 : -1);};
Math.sec=function(x){return 1/this.cos(x);};
Math.csc=function(x){return 1/this.sin(x);};
Math.ctan=function(x){return 1/this.tan(x);};
Math.asec=function(x){return this.acos(1/x);};
Math.acsc=function(x){return this.asin(1/x);};
Math.actan=function(x){return this.atan(1/x);};
Math.sinh=function(x){return (this.exp(x)-this.exp(-x))/2;};
Math.cosh=function(x){return (this.exp(x)+this.exp(-x))/2;};
Math.tanh=function(x){return (this.exp(x)-this.exp(-x))/(this.exp(x)+this.exp(-x));};
Math.ctanh=function(x){return (this.exp(x)+this.exp(-x))/(this.exp(x)-this.exp(-x));};
Math.sech=function(x){return 2/(this.exp(x)+this.exp(-x));};
Math.csch=function(x){return 2/(this.exp(x)-this.exp(-x));};
Math.asinh=function(x){return this.log(x+this.sqrt(x*x+1));};
Math.acosh=function(x){return this.log(x+this.sqrt(x*x-1));;};
Math.atanh=function(x){return this.log((1+x)/(1-x))/2;};
Math.actanh=function(x){return this.log((1+x)/(x-1))/2;};
Math.asech=function(x){return this.log((1+this.sqrt(1-x*x))/x);};
Math.acsch=function(x){return this.log((1+this.sgn(x)*this.sqrt(1+x*x))/x);};
Math.NOD=function(a,b){
	while(a!=b){
		if(a>b)a%=b;
		else if(b>a)b%=a;
	}
	return b;
};
Math.NOK=function(a,b){return a*b/this.NOD(a,b);};
//Конец файла upgrade-math.js
//Начало файла trivial.js
function monopoldisplay(obj){
	if(!obj.nodeType) obj=document.getElementById(obj);
	var p=obj.parentNode.childNodes;
	for(var i=0;i<p.length;i++){
		if(!!p[i].tagName){
			p[i].style.display=p[i]==obj ? (obj.style.display=='none' ? '' : 'none') : 'none';
		}
	}
}
function switchdisplay(obj){
	if(!obj.nodeType) obj=document.getElementById(obj);
	obj.style.display=(obj.style.display=='none' ? '' : 'none');
}
//Конец файла trivial.js

//Операции над нодами
//Начало файла node-shell.js
function nodeShell(node){
	if(typeof(node)=='string')node=document.getElementById(node);
	this.base=node;
}
nodeShell.VISUAL_ELEMENT=1;
nodeShell.NOTVISUAL_ELEMENT=2;
nodeShell.TEXT=4;
nodeShell.SPACE_TEXT=8;
nodeShell.test=function(node){
	node=node||this.base;
	if(node.nodeType==1){
		switch(node.tagName.toLowerCase()){
			case '!':
			case '!doctype':
			case 'script':
			case 'link':
			case 'meta':
			case 'basefont':
			case 'bgsound':
			case 'style':
			case 'base':
				return nodeShell.NOTVISUAL_ELEMENT; break;
			default: return nodeShell.VISUAL_ELEMENT; break;
		}
	}
	else if(node.nodeType==3){
		if((/\S/).test(node.nodeValue)) return nodeShell.TEXT;
		else return nodeShell.SPACE_TEXT;
	}
};
nodeShell.createTestFunction=function(tag){
	var test;
	if(typeof(tag)=='string'||tag instanceof String){
		tag=tag.toLowerCase();
		test=function(node){return node.tagName && node.tagName.toLowerCase()==tag;};
	}
	else if(typeof(tag)=='number'||tag instanceof Number){
		tag=Math.floor(tag);
		test=function(node){return !!(nodeShell.test(node) & tag);};
	}
	else if(tag instanceof Function) test=tag;
	else if(tag.test && tag.test instanceof Function) test=function(node){return tag.test(node);};
	else{
		tag=15;
		test=function(node){return !!(nodeShell.test(node) & tag);};
	}
	return test;
};
nodeShell.prototype={
	constructor:nodeShell,
	parent:function(){
		if(this.base.parent) return new nodeShell(this.base.parent);
		else return null;
	},
	firstChild:function(){
		if(this.base.firstChild) return new nodeShell(this.base.firstChild);
		else return null;
	},
	lastChild:function(){
		if(this.base.lastChild) return new nodeShell(this.base.lastChild);
		else return null;
	},
	getChild:function(index){
		var o;
		if(o=this.base.childNodes[index]) return new nodeShell(o);
		else return null;
	},
	childNodesLength:function(){return this.base.childNodes.length;},
	next:function(){
		if(this.base.nextSibling) return new nodeShell(this.base.nextSibling);
		else return null;
	},
	previous:function(){
		if(this.base.previousSibling) return new nodeShell(this.base.previousSibling);
		else return null;
	},
	runPath:function(path){
		var b=this.base;
		t=path.split(/\/|\\/);
		for(var i=0;i<t.length;i++){
			switch(t[i]){
				case '++': b=b.nextSibling; break;
				case '--': b=b.previousSibling; break;
				case '..': b=b.parentNode; break;
				case '&': b=b.lastChild; break;
				default: if((/\d+/).test(t[i])){
					b=b.childNodes[Number(t[i])];
				}
			}
			if(!b) return null;
		}
		return new nodeShell(b);
	},
	goNextTo:function(tag,count){
		count=count||1;
		var test=nodeShell.createTestFunction(tag);
		var p=this.base.nextSibling;
		for(var i=0;!!p && (i<count);i++){
			if(i)p=p.nextSibling;
			while(p && !test(p))p=p.nextSibling;
		}
		if(p) return new nodeShell(p);
		else return null;
	},
	goPrevTo:function(tag,count){
		count=count||1;
		var test=nodeShell.createTestFunction(tag);
		var p=this.base.previousSibling;
		for(var i=0;!!p && (i<count);i++){
			if(i)p=p.previousSibling;
			while(p && !test(p))p=p.previousSibling;
		}
		if(p) return new nodeShell(p);
		else return null;
	},
	goChildBeginTo:function(tag,count){
		count=count||1;
		var test=nodeShell.createTestFunction(tag);
		var p=this.base.firstChild;
		for(var i=0;!!p && (i<count);i++){
			if(i)p=p.nextSibling;
			while(p && !test(p))p=p.nextSibling;
		}
		if(p) return new nodeShell(p);
		else return null;
	},
	goChildEndTo:function(tag,count){
		count=count||1;
		var test=nodeShell.createTestFunction(tag);
		var p=this.base.lastChild;
		for(var i=0;!!p && (i<count);i++){
			if(i)p=p.previousSibling;
			while(p && !test(p))p=p.previousSibling;
		}
		if(p) return new nodeShell(p);
		else return null;
	},
	append:function(nodes,inversion){
		if(nodes instanceof Array){
			var j;
			if(inversion) for(j=nodes.length-1;j>=0;j--){
				this.base.appendChild(nodes[j]);
			}
			else for(j=0;j<nodes.length;j++){
				this.base.appendChild(nodes[j]);
			}
		}
		else this.base.appendChild(nodes);
	},
	preppend:function(nodes,inversion){
		var first=this.firstChild();
		if(first){
			first.before(nodes,inversion);
		}
		else this.append(nodes,inversion);
	},
	before:function(nodes,inversion){
		var parent=this.base.parentNode;
		if(nodes instanceof Array){
			var j;
			if(inversion) for(j=nodes.length-1;j>=0;j--){
				parent.insertBefore(nodes[j],this.base);
			}
			else for(j=0;j<nodes.length;j++){
				parent.insertBefore(nodes[j],this.base);
			}
		}
		else parent.insertBefore(nodes,this.base);
	},
	after:function(nodes,inversion){
		var next=this.next();
		if(next){
			next.before(nodes,inversion);
		}
		else this.parent().append(nodes,inversion);
	}
};//Конец файла node-shell.js
//Начало файла node-by-array.js
function СreatorNodeByArray(doc){
	var F=function(a1,a2){
		if(typeof(a1)=='string'&&a2) return createNodeByArray.v1(doc,a1,a2);
		else return createNodeByArray(doc,a1);
	};
	F.document=doc;
	F.superclass=СreatorNodeByArray;
	return F;
}
function createNodesByArray(doc,config){
	var t=[];
	for(var j=0;j<config.length;j++){
		t[j]=createNodeByArray(doc,config[j]);
	}
	return t;
}
createNodesByArray.d=function(config){
	return createNodesByArray(document,config);
}
function createNodeByArray(doc,config,callback,callback_before){
	var stk;
	return function me(config,stk){
		var t;
		var j,k;
		if(config instanceof Array){
			if(config[0].nodeType) t=config[0];
			else t=doc.createElement(config[0]);
			stk.push(t);
			if(callback_before){callback_before(t,stk,config);}
			if(config.length>1)for(j=2;j<config.length;j++){
				t.appendChild(me(config[j],stk));
			}
			if(config[1]) if(config[1] instanceof Object) for(j in config[1]){
				if(j == 'style') for(k in config[1][j]) t.style[k]=config[1][j][k];
				else t[j]=config[1][j];
			}
			stk.pop();
		}
		else if(config.nodeType) t=config;
		else t=doc.createTextNode(config.toString());
		if(t.oncreate){t.oncreate(stk);t.oncreate=undefined;}
		if(callback){callback(t,stk);}
		return t;
	}(config, []);
}
createNodeByArray.d=function(config){
	return createNodeByArray(document,config);
}
createNodeByArray.v1=function(doc,name,config){
	var r=createNodeByArray(doc,config);
	if(name)r.oncreate=new Function('stk','stk[0].'+name+'=this;this.container=stk[0];');
	return r;
}
createNodeByArray.v1.d=function(name,config){
	return createNodeByArray.v1(document,name,config);
}//Конец файла node-by-array.js
//Начало файла config-makers.js
function multiconfig(tester,configurator,concat,data){
	if(arguments.length>4) data=Array.prototype.slice.call(arguments,3);
	var ret=collectByDirective(tester,data).map(configurator);
	if(concat)ret=ret.concatMembers();
	return ret;
}
function collectByDirective(tester,data){
	var ret=[],p;
	if(arguments.length>2) data=Array.prototype.slice.call(arguments,1);
	if(typeof(data[0])=='string'||data[0] instanceof String) data=[data];
	var i,j;
	for(i=0;i<data.length;i++){
		if(tester(data[i][0])){
			if(typeof(data[i][1])=='string'||data[i][1] instanceof String) data[i]=[data[i][0],data[i].slice(1)];
			ret=ret.concat(data[i].slice(1));
		}
	}
	return ret;
}//Конец файла config-makers.js

//Специальные функции
//Начало файла asynchron.js
function incapsulateInterval(exec){
	var f=setInterval(function(){if(exec())crearInterval(f);},13);
}
function multiInterval(timeout,exec){
	var i=0;
	if(!(exec instanceof Array)) exec=[exec];
	var f=setInterval(
		function(){
			if((exec[i])()) if(++i>=exec.length) clearInterval(f);
		},
		timeout
	);
}
//Конец файла asynchron.js
//Начало файла handlers.js
function handlerID(){
	return handlerID.next++;
}
handlerID.next=1;
function addEvent(element,type,handler){
	if(!handler.$$guid) handler.$$guid=handlerID();
	if(!element.events) element.events={};
	var handlers=element.events[type];
	if(!handlers){
		handlers=element.events[type]={};
		if(element['on'+type]) handlers[0]=element['on'+type];
	}
	handlers[handler.$$guid]=handler;
	element['on'+type]=function handleEvent(event){
		event=event||fixIEEvent(window.event);
		var returnValue=true;
		var handlers=this.events[event.type];
		for(var j in handlers) if(handlers[j].call(this,event)===false) returnValue=false;
		return returnValue;
	}
}
function removeEvent(element,type,handler){
	if(handler.$$guid) handler=handler.$$guid;
	if(element.events && elements.events[type]) delete elements.events[type][handler];
}
function fixIEEvent(event){
	event.preventDefault=function(){this.returnValue=false;};
	event.stopPropagation=function(){this.cancelBubble=true;};
	return event;
}
function domReady(handler){
	function isDOMReady(){
		if(domReady.done) return;
		if(document && document.getElementsByTagName && document.getElementById && document.body){
			clearInterval(domReady.timer);
			for(var j=0;j<domReady.handlers.length;j++) (domReady.handlers[j])();
			domReady.handlers=null;
			domReady.done=true;
		}
	}
	if(domReady.done) return handler();
	if(domReady.timer) domReady.handlers.push(handler);
	else{
		addEvent(window,'load',isDOMReady);
		domReady.handlers=[handler];
		domReady.timer=setInterval(isDOMReady,13);
	}
}
function FunctionArrayCaller(){
	var funs={};
	this.add=function(f){
		if(!f.$$guid) f.$$guid=handlerID();
		funs[f.$$guid]=f;
	};
	this.remove=function(f){if(f.$$guid) f=f.$$guid; delete funs[f];};
	this.run=function(){for(var j in funs)(funs[j])();};
}//Конец файла handlers.js

