text: /*  js-model JavaScript library, version 0.9.1
   *  (c) 2010 Ben Pickles
   *
   *  Released under MIT license.
   */
  var Model=function(a,c,b){c=c||{};b=b||{};var d=function(e){this.attributes=e||{};this.changes={};this.errors=new Model.Errors(this);this.uid=[a,Model.UID.generate()].join("-")},i=c.persistence;delete c.persistence;jQuery.extend(d,Model.Callbacks,Model.ClassMethods,c,{_name:a,collection:[],chain:function(e){return jQuery.extend({},this,{collection:e})}});if(i)d.persistence=i(d);jQuery.extend(d.prototype,Model.Callbacks,Model.InstanceMethods,b);return d};
  Model.Callbacks={bind:function(a,c){this.callbacks=this.callbacks||{};this.callbacks[a]=this.callbacks[a]||[];this.callbacks[a].push(c);return this},trigger:function(a,c){this.callbacks=this.callbacks||{};if(a=this.callbacks[a])for(var b=0;b<a.length;b++)a[b].apply(this,c||[]);return this},unbind:function(a,c){this.callbacks=this.callbacks||{};if(c)for(var b=this.callbacks[a]||[],d=0;d<b.length;d++)b[d]===c&&this.callbacks[a].splice(d,1);else delete this.callbacks[a];return this}};
  Model.ClassMethods={add:function(){for(var a=[],c=this.uids(),b=0;b<arguments.length;b++){var d=arguments[b];if(jQuery.inArray(d,this.collection)===-1&&!(d.id()&&this.find(d.id()))&&jQuery.inArray(d.uid,c)===-1){this.collection.push(d);a.push(d)}}a.length>0&&this.trigger("add",a);return this},all:function(){return this.collection},count:function(){return this.collection.length},detect:function(a){for(var c=this.all(),b,d=0,i=c.length;d<i;d++){b=c[d];if(a.call(b,d))return b}},each:function(a){for(var c=
  this.all(),b=0,d=c.length;b<d;b++)a.call(c[b],b);return this},find:function(a){return this.detect(function(){return this.id()==a})},first:function(){return this.all()[0]},load:function(a){if(this.persistence){var c=this;this.persistence.read(function(b){for(var d=0,i=b.length;d<i;d++)c.add(b[d]);a&&a(b)})}return this},last:function(){var a=this.all();return a[a.length-1]},pluck:function(a){for(var c=this.all(),b=[],d=0,i=c.length;d<i;d++)b.push(c[d].attr(a));return b},remove:function(a){for(var c,
  b=0,d=this.collection.length;b<d;b++)if(this.collection[b]===a){c=b;break}if(c!=undefined){this.collection.splice(c,1);this.trigger("remove");return true}else return false},reverse:function(){return this.chain(this.all().reverse())},select:function(a){for(var c=this.all(),b=[],d,i=0,e=c.length;i<e;i++){d=c[i];a.call(d,i)&&b.push(d)}return this.chain(b)},sort:function(a){return this.chain(this.all().slice().sort(a))},sortBy:function(a){var c=jQuery.isFunction(a),b=function(d){return a.call(d)};return this.sort(function(d,
  i){d=c?b(d):d.attr(a);i=c?b(i):i.attr(a);return d<i?-1:d>i?1:0})},uids:function(){for(var a=this.all(),c=[],b=0,d=a.length;b<d;b++)c.push(a[b].uid);return c}};Model.Errors=function(a){this.errors={};this.model=a};
  Model.Errors.prototype={add:function(a,c){this.errors[a]||(this.errors[a]=[]);this.errors[a].push(c);return this},all:function(){return this.errors},clear:function(){this.errors={};return this},each:function(a){for(var c in this.errors)for(var b=0;b<this.errors[c].length;b++)a.call(this,c,this.errors[c][b]);return this},on:function(a){return this.errors[a]||[]},size:function(){var a=0;this.each(function(){a++});return a}};
  Model.InstanceMethods={attr:function(a,c){if(arguments.length===0)return jQuery.extend({},this.attributes,this.changes);else if(arguments.length===2){if(this.attributes[a]===c)delete this.changes[a];else this.changes[a]=c;return this}else if(typeof a==="object"){for(var b in a)this.attr(b,a[b]);return this}else return a in this.changes?this.changes[a]:this.attributes[a]},callPersistMethod:function(a,c){var b=this,d=function(){if(a==="create")b.constructor.add(b);else a==="destroy"&&b.constructor.remove(b)},
  i=function(e){if(e){b.merge(b.changes).reset();d();b.trigger(a)}var g;if(c)g=c.apply(b,arguments);return g};this.constructor.persistence?this.constructor.persistence[a](this,i):i.call(this,true)},destroy:function(a){this.callPersistMethod("destroy",a);return this},id:function(){return this.attributes.id},merge:function(a){jQuery.extend(this.attributes,a);return this},newRecord:function(){return this.id()===undefined},reset:function(){this.errors.clear();this.changes={};return this},save:function(a){if(this.valid())this.callPersistMethod(this.newRecord()?
  "create":"update",a);else a&&a(false);return this},valid:function(){this.errors.clear();this.validate();return this.errors.size()===0},validate:function(){return this}};
  Model.localStorage=function(){if(!window.localStorage)return function(){return{create:function(a,c){c(true)},destroy:function(a,c){c(true)},read:function(a){a([])},update:function(a,c){c(true)}}};return function(a){var c=[a._name,"collection"].join("-"),b=function(){var f=localStorage[c];return f?JSON.parse(f):[]},d=function(f){localStorage.setItem(c,JSON.stringify(f))},i=function(f){var h=b();if(jQuery.inArray(f,h)===-1){h.push(f);d(h)}},e=function(f){var h=b();f=jQuery.inArray(f,h);if(f>-1){h.splice(f,
  1);d(h)}},g=function(f){var h=f.uid;f=JSON.stringify(f.attr());localStorage.setItem(h,f);i(h)};return{create:function(f,h){g(f);h(true)},destroy:function(f,h){localStorage.removeItem(f.uid);e(f.uid);h(true)},read:function(f){if(!f)return false;for(var h=b(),j=[],k,l,m=0,n=h.length;m<n;m++){l=h[m];k=JSON.parse(localStorage[l]);k=new a(k);k.uid=l;j.push(k)}f(j)},update:function(f,h){g(f);h(true)}}}};Model.Log=function(){window.console&&window.console.log.apply(window.console,arguments)};
  Model.REST=function(a,c){var b=/:([\w\d]+)/g,d=function(){for(var e=[],g;(g=b.exec(a))!==null;)e.push(g[1]);return e}(),i=jQuery.extend({path:function(e){var g=a;$.each(d,function(f,h){g=g.replace(":"+h,e.attributes[h])});return g},create:function(e,g){return this.xhr("POST",this.create_path(e),e,g)},create_path:function(e){return this.path(e)},destroy:function(e,g){return this.xhr("DELETE",this.destroy_path(e),e,g)},destroy_path:function(e){return this.update_path(e)},params:function(e){var g;if(e){var f=
  e.attr();delete f.id;g={};g[e.constructor._name.toLowerCase()]=f}else g=null;if(jQuery.ajaxSettings.data)g=jQuery.extend({},jQuery.ajaxSettings.data,g);return JSON.stringify(g)},read:function(e){var g=this.klass;return this.xhr("GET",this.read_path(),null,function(f,h,j){j=jQuery.makeArray(j);f=[];h=0;for(var k=j.length;h<k;h++)f.push(new g(j[h]));e(f)})},read_path:function(){return a},update:function(e,g){return this.xhr("PUT",this.update_path(e),e,g)},update_path:function(e){return[this.path(e),
  e.id()].join("/")},xhr:function(e,g,f,h){var j=this,k=jQuery.inArray(e,["DELETE","GET"])>-1?undefined:this.params(f);return jQuery.ajax({type:e,url:g,contentType:"application/json",dataType:"json",data:k,dataFilter:function(l){return/\S/.test(l)?l:undefined},complete:function(l,m){j.xhrComplete(l,m,f,h)}})},xhrComplete:function(e,g,f,h){var j=Model.REST["handle"+e.status];j&&j.call(this,e,g,f);g=g==="success";j=Model.REST.parseResponseData(e);g&&f&&j&&f.attr(j);h&&h.call(f,g,e,j)}},c);return function(e){i.klass=
  e;return i}};Model.RestPersistence=Model.REST;Model.REST.handle422=function(a,c,b){if(a=Model.REST.parseResponseData(a)){b.errors.clear();for(var d in a)for(c=0;c<a[d].length;c++)b.errors.add(d,a[d][c])}};Model.REST.parseResponseData=function(a){try{return/\S/.test(a.responseText)?jQuery.parseJSON(a.responseText):undefined}catch(c){Model.Log(c)}};Model.UID={counter:0,generate:function(){return[(new Date).valueOf(),this.counter++].join("-")},reset:function(){this.counter=0;return this}};
  Model.VERSION="0.9.1";
  