(function($){$.Chain={version:'0.2',tag:['{','}'],services:{},service:function(name,proto)
{this.services[name]=proto;$.fn[name]=function(options)
{if(!this.length)
{return this;}
var instance=this.data('chain-'+name);var args=Array.prototype.slice.call(arguments,1);if(!instance)
{if(options=='destroy')
{return this;}
instance=$.extend({element:this},$.Chain.services[name]);this.data('chain-'+name,instance);if(instance.init)
{instance.init();}}
var result;if(typeof options=='string'&&instance['$'+options])
{result=instance['$'+options].apply(instance,args);}
else if(instance['handler'])
{result=instance['handler'].apply(instance,[options].concat(args));}
else
{result=this;}
if(options=='destroy')
{this.removeData('chain-'+name);}
return result;};},extend:function(name,proto)
{if(this.services[name])
{this.services[name]=$.extend(this.services[name],proto);}},jobject:function(obj)
{return obj&&obj.init==$.fn.init;},jidentic:function(j1,j2)
{if(!j1||!j2||j1.length!=j2.length)
{return false;}
var a1=j1.get();var a2=j2.get();for(var i=0;i<a1.length;i++)
{if(a1[i]!=a2[i])
{return false;}}
return true;},parse:function()
{var $this={};$this.closure=['function($data, $el){'
+'var $text = [];\n'
+'$text.print = function(text)'
+'{this.push((typeof text == "number") ? text : ((typeof text != "undefined") ? text : ""));};\n'
+'with($data){\n','}\n'
+'return $text.join("");'
+'}'];$this.textPrint=function(text)
{return'$text.print("'
+text.split('\\').join('\\\\').split("'").join("\\'").split('"').join('\\"')
+'");';};$this.scriptPrint=function(text)
{return'$text.print('+text+');';};$this.parser=function(text){var tag=$.Chain.tag;var opener,closer,closer2=null,result=[];while(text){opener=text.indexOf(tag[0]);closer=opener+text.substring(opener).indexOf(tag[1]);if(opener!=-1)
{if(text[opener-1]=='\\')
{closer2=opener+tag[0].length+text.substring(opener+tag[0].length).indexOf(tag[0]);if(closer2!=opener+tag[0].length-1&&text[closer2-1]=='\\')
{closer2=closer2-1;}
else if(closer2==opener+tag[0].length-1)
{closer2=text.length;}
result.push($this.textPrint(text.substring(0,opener-1)));result.push($this.textPrint(text.substring(opener,closer2)));}
else
{closer2=null;if(closer==opener-1)
{closer=text.length;}
result.push($this.textPrint(text.substring(0,opener)));result.push($this.scriptPrint(text.substring(opener+tag[0].length,closer)));}
text=text.substring((closer2===null)?closer+tag[1].length:closer2);}
else if(text)
{result.push($this.textPrint(text));text='';}}
return result.join('\n');};return function($text)
{var $fn=function(){};try
{eval('$fn = '+$this.closure[0]+$this.parser($text)+$this.closure[1]);}
catch(e)
{throw"Parsing Error";}
return $fn;};}()};})(jQuery);(function($){$.Chain.service('update',{handler:function(opt)
{if(typeof opt=='function')
{return this.bind(opt);}
else
{return this.trigger(opt);}},bind:function(fn)
{return this.element.bind('update',fn);},trigger:function(opt)
{this.element.items('update');this.element.item('update');this.element.triggerHandler('preupdate',this.element.item());if(opt=='hard')
{this.element.items(true).each(function(){$(this).update();});}
this.element.triggerHandler('update',this.element.item());return this.element;}});})(jQuery);(function($){$.Chain.service('chain',{init:function()
{this.anchor=this.element;this.template=this.anchor.html();this.tplNumber=0;this.builder=this.createBuilder();this.plugins={};this.isActive=false;this.destroyers=[];this.element.addClass('chain-element');},handler:function(obj,bool)
{this.element.items('backup');this.element.item('backup');if(typeof obj=='object')
{this.handleUpdater(obj);}
else if(typeof obj=='function')
{this.handleBuilder(obj,bool);}
this.anchor.empty();this.isActive=true;this.element.update();return this.element;},handleUpdater:function(rules)
{var builder=rules.builder;delete rules.builder;this.options=rules.options||{};delete rules.options;if(rules.anchor)
{this.setAnchor(rules.anchor);}
delete rules.anchor;var override=rules.override;delete rules.override;for(var i in rules)
{if(typeof rules[i]=='string')
{rules[i]=$.Chain.parse(rules[i]);}
else if(typeof rules[i]=='object')
{for(var j in rules[i])
{if(typeof rules[i][j]=='string')
{rules[i][j]=$.Chain.parse(rules[i][j]);}}}}
var fn=function(event,data)
{var el,val;var self=$(this);for(var i in rules)
{if(i=='self')
{el=self;}
else
{el=$(i,self);}
if(typeof rules[i]=='function')
{val=rules[i].apply(self,[data,el]);if(typeof val=='string')
{el.not(':input').html(val).end().filter(':input').val(val);}}
else if(typeof rules[i]=='object')
{for(var j in rules[i])
{if(typeof rules[i][j]=='function')
{val=rules[i][j].apply(self,[data,el]);if(typeof val=='string')
{if(j=='content')
{el.html(val);}
else if(j=='text')
{el.text(val);}
else if(j=='value')
{el.val(val);}
else if(j=='class'||j=='className')
{el.addClass(val);}
else
{el.attr(j,val);}}}}}}};var defBuilder=this.defaultBuilder;this.builder=function(root)
{if(builder)
{builder.apply(this,[root]);}
if(!override)
{defBuilder.apply(this);}
this.update(fn);return false;};},handleBuilder:function(fn,bool)
{if(bool)
{this.builder=fn;}
else
{this.builder=this.createBuilder(fn);}},defaultBuilder:function(builder,root)
{var res=builder?(builder.apply(this,[root])!==false):true;if(res)
{this.bind('update',function(event,data){var self=$(this);for(var i in data)
{if(typeof data[i]!='object'&&typeof data[i]!='function')
{self.find('> .'+i+', *:not(.chain-element) .'+i).each(function(){var match=$(this);if(match.filter(':input').length)
{match.val(data[i]);}
else if(match.filter('img').length)
{match.attr('src',data[i]);}
else
{match.html(data[i]);}});}}});}},createBuilder:function(builder)
{var defBuilder=this.defaultBuilder;return function(root){defBuilder.apply(this,[builder,root]);return false;};},setAnchor:function(anchor)
{this.anchor.html(this.template);this.anchor=anchor==this.element?anchor:this.element.find(anchor).eq(0);this.template=this.anchor.html();this.anchor.empty();},$anchor:function(anchor)
{if(anchor)
{this.element.items('backup');this.element.item('backup');this.setAnchor(anchor);this.element.update();return this.element;}
else
{return this.anchor;}},$template:function(arg)
{if(!arguments.length)
{return $('<div>').html(this.template).children().eq(this.tplNumber);}
if(arg=='raw')
{return this.template;}
if(typeof arg=='number')
{this.tplNumber=arg;}
else
{var tpl=$('<div>').html(this.template).children();var node=tpl.filter(arg).eq(0);if(node.length)
{this.tplNumber=tpl.index(node);}
else
{return this.element;}}
this.element.items('backup');this.element.item('backup');this.element.update();return this.element;},$builder:function(builder)
{if(builder)
{return this.handler(builder);}
else
{return this.builder;}},$active:function()
{return this.isActive;},$options:function(opt,val)
{this.options=this.options||{};if(arguments.length==2)
{this.options[opt]=val;return this.element;}
else
{return this.options[opt];}},$plugin:function(name,fn)
{if(fn===null)
{delete this.plugins[name];}
else if(typeof fn=='function')
{this.plugins[name]=fn;}
else if(name&&!fn)
{return this.plugins[name];}
else
{return this.plugins;}
if(typeof fn=='function')
{this.element.items(true).each(function(){var self=$(this);fn.call(self,self.item('root'));});}
this.element.update();return this.element;},$clone:function()
{var id=this.element.attr('id');this.element.attr('id','');var clone=this.element.clone().empty().html(this.template);this.element.attr('id',id);return clone;},$destroy:function(nofollow)
{this.element.removeClass('chain-element');if(!nofollow)
{this.element.items('backup');this.element.item('backup');this.element.find('.chain-element').each(function(){$(this).chain('destroy',true);});}
this.element.triggerHandler('destroy');this.isActive=false;this.anchor.html(this.template);return this.element;}});})(jQuery);(function($){$.Chain.service('item',{init:function()
{this.isActive=false;this.isBuilt=false;this.root=this.element;this.data=false;this.datafn=this.dataHandler;},handler:function(obj)
{if(typeof obj=='object')
{return this.handleObject(obj);}
else if(typeof obj=='function')
{return this.handleFunction(obj);}
else
{return this.handleDefault();}},handleObject:function(obj)
{this.setData(obj);this.isActive=true;this.update();return this.element;},handleFunction:function(fn)
{this.datafn=fn;return this.element;},handleDefault:function()
{if(this.isActive)
{return this.getData();}
else
{return false;}},getData:function()
{this.data=this.datafn.call(this.element,this.data);return this.data;},setData:function(obj)
{var data;if($.Chain.jobject(obj)&&obj.item())
{data=$.extend({},obj.item());}
else if($.Chain.jobject(obj))
{data={};}
else
{data=obj;}
this.data=this.datafn.call(this.element,this.data||data,data);if(this.linkElement&&this.linkElement[0]!=obj[0])
{var el=this.linkFunction();if($.Chain.jobject(el)&&el.length&&el.item())
{el.item(this.data);}}},dataHandler:function(oldval,newval)
{if(arguments.length==2)
{return $.extend(oldval,newval);}
else
{return oldval;}},update:function()
{return this.element.update();},build:function()
{var fix=this.element.chain('template','raw').replace(/jQuery\d+\=\"null\"/gi,"");this.element.chain('anchor').html(fix);if(!$.Chain.jidentic(this.root,this.element))
{var plugins=this.root.chain('plugin');for(var i in plugins)
{plugins[i].apply(this.element,[this.root]);}}
this.element.chain('builder').apply(this.element,[this.root]);this.isBuilt=true;},$update:function()
{if(this.element.chain('active')&&this.isActive&&!this.isBuilt&&this.getData())
{this.build();}
return this.element;},$replace:function(obj)
{this.data={};this.setData(obj);this.isActive=true;this.update();return this.element;},$remove:function(noupdate)
{this.element.chain('destroy');this.element.remove();this.element.item('link',null);this.element.item('destroy');if(!$.Chain.jidentic(this.root,this.element)&&!noupdate)
{this.root.update();}},$active:function()
{return this.isActive;},$root:function(root)
{if(arguments.length)
{this.root=root;this.update();return this.element;}
else
{return this.root;}},$backup:function()
{this.isBuilt=false;return this.element;},$link:function(element,collection)
{if(this.linkElement)
{this.linkElement.unbind('update',this.linkUpdater);this.linkElement=null;}
element=$(element);if(element.length)
{var self=this;this.isActive=true;this.linkElement=element;this.linkFunction=function()
{if(typeof collection=='function')
{try{return collection.call(self.element,self.linkElement);}catch(e){return $().eq(-1);}}
else if(typeof collection=='string')
{return self.linkElement.items('collection',collection);}
else
{return $().eq(-1);}};this.linkUpdater=function()
{var res=self.linkFunction();if(res&&res.length)
{self.element.item(res);}};this.linkElement.bind('update',this.linkUpdater);this.linkUpdater();}
return this.element;},$destroy:function()
{return this.element;}});})(jQuery);(function($){$.Chain.service('items',{collections:{all:function()
{return this.element.chain('anchor').children('.chain-item');},visible:function()
{return this.element.chain('anchor').children('.chain-item:visible');},hidden:function()
{return this.element.chain('anchor').children('.chain-item:hidden');},self:function()
{return this.element;}},init:function()
{this.isActive=false;this.pushBuffer=[];this.shiftBuffer=[];this.collections=$.extend({},this.collections);},handler:function(obj)
{if(obj instanceof Array)
{return this.handleArray(obj);}
else if(!this.isActive)
{return $().eq(-1);}
else if($.Chain.jobject(obj))
{return this.handleElement(obj);}
else if(typeof obj=='object')
{return this.handleObject(obj);}
else if(typeof obj=='number')
{return this.handleNumber(obj);}
else if(obj===true)
{return this.handleTrue();}
else
{return this.handleDefault();}},handleObject:function(obj)
{return this.collection('all').filter(function(){return $(this).item()==obj;});},handleElement:function(obj)
{if(!$.Chain.jidentic(obj,obj.item('root'))&&$.Chain.jidentic(this.element,obj.item('root')))
{return obj;}
else
{return $().eq(-1);}},handleArray:function(array)
{return this.$merge(array);},handleNumber:function(number)
{if(number==-1)
{return this.collection('visible').filter(':last');}
else
{return this.collection('visible').eq(number);}},handleTrue:function()
{return this.collection('all');},handleDefault:function()
{return this.collection('visible');},update:function()
{this.element.update();},empty:function()
{var all=this.collection('all');setTimeout(function(){all.each(function(){$(this).item('remove',true);});},1);this.element.chain('anchor').empty();},collection:function(col,fn)
{if(arguments.length>1)
{if(typeof fn=='function')
{this.collections[col]=fn;}
return this.element;}
else
{if(this.collections[col])
{return this.collections[col].apply(this);}
else
{return $().eq(-1);}}},$update:function()
{if(!this.element.chain('active')||!this.isActive)
{return this.element;}
var self=this;var builder=this.element.chain('builder');var template=this.element.chain('template');var push;var iterator=function(){var clone=template.clone()[push?'appendTo':'prependTo'](self.element.chain('anchor')).addClass('chain-item').item('root',self.element);if(self.linkElement&&$.Chain.jobject(this)&&this.item())
{clone.item('link',this,'self');}
else
{clone.item(this);}
clone.chain(builder,true);};push=false;$.each(this.shiftBuffer,iterator);push=true;$.each(this.pushBuffer,iterator);this.shiftBuffer=[];this.pushBuffer=[];return this.element;},$add:function()
{if(this.linkElement)
{return this.element;}
var cmd;var args=Array.prototype.slice.call(arguments);if(typeof args[0]=='string')
{cmd=args.shift();}
var buffer=(cmd=='shift')?'shiftBuffer':'pushBuffer';this.isActive=true;this[buffer]=this[buffer].concat(args);this.update();return this.element;},$merge:function(cmd,items)
{if(this.linkElement)
{return this.element;}
if(typeof cmd!='string')
{items=cmd;}
var buffer=(cmd=='shift')?'shiftBuffer':'pushBuffer';this.isActive=true;if($.Chain.jobject(items))
{this[buffer]=this[buffer].concat(items.map(function(){return $(this);}).get());}
else if(items instanceof Array)
{this[buffer]=this[buffer].concat(items);}
this.update();return this.element;},$replace:function(cmd,items)
{if(this.linkElement&&arguments.callee.caller!=this.linkUpdater)
{return this.element;}
if(typeof cmd!='string')
{items=cmd;}
var buffer=(cmd=='shift')?'shiftBuffer':'pushBuffer';this.isActive=true;this.empty();if($.Chain.jobject(items))
{this[buffer]=items.map(function(){return $(this);}).get();}
else if(items instanceof Array)
{this[buffer]=items;}
this.update();return this.element;},$remove:function()
{if(this.linkElement)
{return this.element;}
for(var i=0;i<arguments.length;i++)
{this.handler(arguments[i]).item('remove',true);}
this.update();return this.element;},$reorder:function(item1,item2)
{if(item2)
{this.handler(item1).before(this.handler(item2));}
else
{this.handler(item1).appendTo(this.element.chain('anchor'));}
this.update();return this.element;},$empty:function()
{if(this.linkElement)
{return this.element;}
this.empty();this.shiftBuffer=[];this.pushBuffer=[];this.update();return this.element;},$data:function(x)
{return this.handler(x).map(function(){return $(this).item();}).get();},$link:function(element,collection)
{if(this.linkElement)
{this.linkElement.unbind('update',this.linkUpdater);this.linkElement=null;}
element=$(element);if(element.length)
{var self=this;this.linkElement=element;this.linkFunction=function()
{if(typeof collection=='function')
{try{return collection.call(self.element,self.linkElement);}catch(e){return $().eq(-1);}}
else if(typeof collection=='string')
{return self.linkElement.items('collection',collection);}
else
{return $().eq(-1);}};this.linkUpdater=function()
{self.$replace(self.linkFunction());};this.linkElement.bind('update',this.linkUpdater);this.linkUpdater();}
return this.element;},$index:function(item)
{return this.collection('all').index(this.handler(item));},$collection:function()
{return this.collection.apply(this,Array.prototype.slice.call(arguments));},$active:function()
{return this.isActive;},$backup:function()
{if(!this.element.chain('active')||!this.isActive)
{return this.element;}
var buffer=[];this.collection('all').each(function(){var item=$(this).item();if(item)
{buffer.push(item);}});this.pushBuffer=buffer.concat(this.pushBuffer);this.empty();return this.element;},$destroy:function()
{this.empty();return this.element;}});$.Chain.extend('items',{doFilter:function()
{var props=this.searchProperties;var text=this.searchText;if(text)
{if(typeof text=='string')
{text=text.toLowerCase();}
var items=this.element.items(true).filter(function(){var data=$(this).item();if(props)
{for(var i=0;i<props.length;i++)
{if(typeof data[props[i]]=='string'&&!!(typeof text=='string'?data[props[i]].toLowerCase():data[props[i]]).match(text))
{return true;}}}
else
{for(var prop in data)
{if(typeof data[prop]=='string'&&!!(typeof text=='string'?data[prop].toLowerCase():data[prop]).match(text))
{return true;}}}});this.element.items(true).not(items).hide();items.show();}
else
{this.element.items(true).show();this.element.unbind('preupdate',this.searchBinding);this.searchBinding=null;}},$filter:function(text,properties)
{if(!arguments.length)
{return this.update();}
this.searchText=text;if(typeof properties=='string')
{this.searchProperties=[properties];}
else if(properties instanceof Array)
{this.searchProperties=properties;}
else
{this.searchProperties=null;}
if(!this.searchBinding)
{var self=this;this.searchBinding=function(event,item){self.doFilter();};this.element.bind('preupdate',this.searchBinding);}
return this.update();}});$.Chain.extend('items',{doSort:function()
{var name=this.sortName;var opt=this.sortOpt;var sorter={'number':function(a,b){return parseFloat(($(a).item()[name]+'').match(/\d+/gi)[0])
-parseFloat(($(b).item()[name]+'').match(/\d+/gi)[0]);},'default':function(a,b){return $(a).item()[name]>$(b).item()[name]?1:-1;}};if(name)
{var sortfn=opt.fn||sorter[opt.type]||sorter['default'];var array=this.element.items(true).get().sort(sortfn);array=opt.desc?array.reverse():array;for(var i=0;i<array.length;i++)
{this.element.chain('anchor').append(array[i]);}
opt.desc=opt.toggle?!opt.desc:opt.desc;}
else
{this.element.unbind('preupdate',this.sortBinding);this.sortBinding=null;}},$sort:function(name,opt)
{if(!name&&name!==null&&name!==false)
{return this.update();}
if(this.sortName!=name)
{this.sortOpt=$.extend({desc:false,type:'default',toggle:false},opt);}
else
{$.extend(this.sortOpt,opt);}
this.sortName=name;if(!this.sortBinding)
{var self=this;this.sortBinding=function(event,item){self.doSort();};this.element.bind('preupdate',this.sortBinding);}
return this.update();}});})(jQuery);
