diff options
| author | Misko Hevery | 2010-01-09 15:02:43 -0800 | 
|---|---|---|
| committer | Misko Hevery | 2010-01-09 15:02:43 -0800 | 
| commit | 9b9a0dadcce82ae42ac09ad396d647739af20a06 (patch) | |
| tree | 854d162ac442509d12b17d7ed5123d7d43850f1e | |
| parent | 88eca572fdc7f68a7f384b612052c49de00df433 (diff) | |
| download | angular.js-9b9a0dadcce82ae42ac09ad396d647739af20a06.tar.bz2 | |
removed nglr namespace
45 files changed, 5514 insertions, 1911 deletions
@@ -2,9 +2,11 @@ include FileUtils  desc 'Compile JavaScript'  task :compile do -  compiled = %x(java -jar lib/shrinksafe/shrinksafe.jar \ -      lib/webtoolkit/webtoolkit.base64.js \ +  concat = %x(cat \        lib/underscore/underscore.js \ +      src/angular.prefix \ +      lib/webtoolkit/webtoolkit.base64.js \ +      lib/swfobject.js/swfobject.js \        src/Loader.js \        src/API.js \        src/Binder.js \ @@ -19,35 +21,16 @@ task :compile do        src/Users.js \        src/Validators.js \        src/Widgets.js \ -      src/angular-bootstrap.js \ +      src/angular.suffix \      )    f = File.new("angular.js", 'w') -  f.write(compiled) +  f.write(concat)    f.close -end -desc 'Compile JavaScript with Google Closure Compiler' -task :compileclosure do -#        --compilation_level ADVANCED_OPTIMIZATIONS \    %x(java -jar lib/compiler-closure/compiler.jar \ -        --js lib/webtoolkit/webtoolkit.base64.js \ -        --js lib/underscore/underscore.js \ -        --js src/Loader.js \ -        --js src/API.js \ -        --js src/Binder.js \ -        --js src/ControlBar.js \ -        --js src/DataStore.js \ -        --js src/Filters.js \ -        --js src/JSON.js \ -        --js src/Model.js \ -        --js src/Parser.js \ -        --js src/Scope.js \ -        --js src/Server.js \ -        --js src/Users.js \ -        --js src/Validators.js \ -        --js src/Widgets.js \ -        --js src/angular-bootstrap.js \ -        --js_output_file angular.js) +        --compilation_level ADVANCED_OPTIMIZATIONS \ +        --js angular.js \ +        --js_output_file angular-minified.js)  end  namespace :server do @@ -3,4 +3,4 @@    - angular.defaults = {}    - var scope = angular.compile(element, options);  * angular.js is not self boot straping by default. -* +* Remove SWFObject diff --git a/angular-minified.js b/angular-minified.js new file mode 100644 index 00000000..a9faa563 --- /dev/null +++ b/angular-minified.js @@ -0,0 +1,122 @@ +function u(){return function(s){return s}}function x(){return function(){}}function y(s){return function(v){this[s]=v}}function z(s){return function(){return s}} +(function(){var s=this,v=s.Ma;function w(f){this.$=f}var a=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=s.Ma=function(f){return new w(f)};if(typeof exports!=="undefined")exports.Ma=b;var c=Array.prototype.slice,d=Array.prototype.unshift,e=Object.prototype.toString,g=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;b.Ce="0.5.1";b.b=function(f,h,j){try{if(f.forEach)f.forEach(h,j);else if(b.q(f)||b.Lb(f))for(var k=0,m=f.length;k<m;k++)h.call(j,f[k],k,f);else{var q= +b.ia(f);m=q.length;for(k=0;k<m;k++)h.call(j,f[q[k]],q[k],f)}}catch(t){if(t!=a)throw t;}return f};b.map=function(f,h,j){if(f&&b.K(f.map))return f.map(h,j);var k=[];b.b(f,function(m,q,t){k.push(h.call(j,m,q,t))});return k};b.reduce=function(f,h,j,k){if(f&&b.K(f.reduce))return f.reduce(b.B(j,k),h);b.b(f,function(m,q,t){h=j.call(k,h,m,q,t)});return h};b.reduceRight=function(f,h,j,k){if(f&&b.K(f.reduceRight))return f.reduceRight(b.B(j,k),h);var m=b.ua(b.A(f)).reverse();b.b(m,function(q,t){h=j.call(k,h, +q,t,f)});return h};b.xb=function(f,h,j){var k;b.b(f,function(m,q,t){if(h.call(j,m,q,t)){k=m;b.qa()}});return k};b.select=function(f,h,j){if(f&&b.K(f.filter))return f.filter(h,j);var k=[];b.b(f,function(m,q,t){h.call(j,m,q,t)&&k.push(m)});return k};b.Pf=function(f,h,j){var k=[];b.b(f,function(m,q,t){!h.call(j,m,q,t)&&k.push(m)});return k};b.all=function(f,h,j){h=h||b.ga;if(f&&b.K(f.every))return f.every(h,j);var k=true;b.b(f,function(m,q,t){(k=k&&h.call(j,m,q,t))||b.qa()});return k};b.Hc=function(f, +h,j){h=h||b.ga;if(f&&b.K(f.some))return f.some(h,j);var k=false;b.b(f,function(m,q,t){if(k=h.call(j,m,q,t))b.qa()});return k};b.ya=function(f,h){if(b.q(f))return b.indexOf(f,h)!=-1;var j=false;b.b(f,function(k){if(j=k===h)b.qa()});return j};b.rf=function(f,h){var j=b.L(arguments,2);return b.map(f,function(k){return(h?k[h]:k).apply(k,j)})};b.bb=function(f,h){return b.map(f,function(j){return j[h]})};b.max=function(f,h,j){if(!h&&b.q(f))return Math.max.apply(Math,f);var k={ca:-Infinity};b.b(f,function(m, +q,t){q=h?h.call(j,m,q,t):m;q>=k.ca&&(k={value:m,ca:q})});return k.value};b.min=function(f,h,j){if(!h&&b.q(f))return Math.min.apply(Math,f);var k={ca:Infinity};b.b(f,function(m,q,t){q=h?h.call(j,m,q,t):m;q<k.ca&&(k={value:m,ca:q})});return k.value};b.$d=function(f,h,j){return b.bb(b.map(f,function(k,m,q){return{value:k,vb:h.call(j,k,m,q)}}).sort(function(k,m){k=k.vb;m=m.vb;return k<m?-1:k>m?1:0}),"value")};b.Sf=function(f,h,j){j=j||b.ga;for(var k=0,m=f.length;k<m;){var q=k+m>>1;j(f[q])<j(h)?(k=q+1): +(m=q)}return k};b.A=function(f){if(!f)return[];if(f.A)return f.A();if(b.q(f))return f;if(b.Lb(f))return c.call(f);return b.map(f,u())};b.size=function(f){return b.A(f).length};b.gd=function(f,h,j){return h&&!j?c.call(f,0,h):f[0]};b.L=function(f,h,j){return c.call(f,b.H(h)||j?1:h)};b.wd=function(f){return f[f.length-1]};b.compact=function(f){return b.select(f,function(h){return!!h})};b.hd=function(f){return b.reduce(f,[],function(h,j){if(b.q(j))return h.concat(b.hd(j));h.push(j);return h})};b.dg=function(f){var h= +b.L(arguments);return b.select(f,function(j){return!b.ya(h,j)})};b.fe=function(f,h){return b.reduce(f,[],function(j,k,m){if(0==m||(h===true?b.wd(j)!=k:!b.ya(j,k)))j.push(k);return j})};b.qf=function(f){var h=b.L(arguments);return b.select(b.fe(f),function(j){return b.all(h,function(k){return b.indexOf(k,j)>=0})})};b.gg=function(){for(var f=b.A(arguments),h=b.max(b.bb(f,"length")),j=new Array(h),k=0;k<h;k++)j[k]=b.bb(f,String(k));return j};b.indexOf=function(f,h){if(f.indexOf)return f.indexOf(h);for(var j= +0,k=f.length;j<k;j++)if(f[j]===h)return j;return-1};b.lastIndexOf=function(f,h){if(f.lastIndexOf)return f.lastIndexOf(h);for(var j=f.length;j--;)if(f[j]===h)return j;return-1};b.Rd=function(f,h,j){var k=b.A(arguments),m=k.length<=1;f=m?0:k[0];h=m?k[0]:k[1];j=k[2]||1;k=Math.ceil((h-f)/j);if(k<=0)return[];k=new Array(k);m=f;for(var q=0;;m+=j){if((j>0?m-h:h-m)>=0)return k;k[q++]=m}};b.B=function(f,h){var j=b.L(arguments,2);return function(){return f.apply(h||s,j.concat(b.A(arguments)))}};b.Ne=function(f){var h= +b.L(arguments);if(h.length==0)h=b.Ua(f);b.b(h,function(j){f[j]=b.B(f[j],f)});return f};b.Ta=function(f,h){var j=b.L(arguments,2);return setTimeout(function(){return f.apply(f,j)},h)};b.defer=function(f){return b.Ta.apply(b,[f,1].concat(b.L(arguments)))};b.fg=function(f,h){return function(){var j=[f].concat(b.A(arguments));return h.apply(h,j)}};b.Ze=function(){var f=b.A(arguments);return function(){for(var h=b.A(arguments),j=f.length-1;j>=0;j--)h=[f[j].apply(this,h)];return h[0]}};b.ia=function(f){if(b.q(f))return b.Rd(0, +f.length);var h=[];for(var j in f)g.call(f,j)&&h.push(j);return h};b.gb=function(f){return b.map(f,b.ga)};b.Ua=function(f){return b.select(b.ia(f),function(h){return b.K(f[h])}).sort()};b.extend=function(f,h){for(var j in h)f[j]=h[j];return f};b.ua=function(f){if(b.q(f))return f.slice(0);return b.extend({},f)};b.isEqual=function(f,h){if(f===h)return true;var j=typeof f;if(j!=typeof h)return false;if(f==h)return true;if(!f&&h||f&&!h)return false;if(f.isEqual)return f.isEqual(h);if(b.pd(f)&&b.pd(h))return f.getTime()=== +h.getTime();if(b.Mb(f)&&b.Mb(h))return true;if(b.rd(f)&&b.rd(h))return f.source===h.source&&f.global===h.global&&f.ignoreCase===h.ignoreCase&&f.multiline===h.multiline;if(j!=="object")return false;if(f.length&&f.length!==h.length)return false;j=b.ia(f);var k=b.ia(h);if(j.length!=k.length)return false;for(var m in f)if(!b.isEqual(f[m],h[m]))return false;return true};b.tf=function(f){return b.ia(f).length==0};b.sf=function(f){return!!(f&&f.nodeType==1)};b.Lb=function(f){return f&&b.ha(f.length)&&!b.q(f)&& +!i.call(f,"length")};b.Mb=function(f){return b.ha(f)&&isNaN(f)};b.uf=function(f){return f===null};b.H=function(f){return typeof f=="undefined"};for(var l=["Array","Date","Function","Number","RegExp","String"],n=0,o=l.length;n<o;n++)(function(){var f="[object "+l[n]+"]";b["is"+l[n]]=function(h){return e.call(h)==f}})();b.Df=function(){s.Ma=v;return this};b.ga=u();b.qa=function(){throw a;};var p=0;b.$f=function(f){var h=p++;return f?f+h:h};b.V=function(f,h){f=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+ +f.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return h?f(h):f};b.forEach=b.b;b.kf=b.of=b.reduce;b.lf=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.Hc;b.Ib=b.gd;b.Wf=b.L;b.Af=b.Ua;function r(f,h){return h?b(f).rb():f}b.b(b.Ua(b),function(f){var h=b[f];w.prototype[f]=function(){d.call(arguments,this.$);return r(h.apply(b, +arguments),this.Na)}});b.b(["pop","push","reverse","shift","sort","splice","unshift"],function(f){var h=Array.prototype[f];w.prototype[f]=function(){h.apply(this.$,arguments);return r(this.$,this.Na)}});b.b(["concat","join","slice"],function(f){var h=Array.prototype[f];w.prototype[f]=function(){return r(h.apply(this.$,arguments),this.Na)}});w.prototype.rb=function(){this.Na=true;return this};w.prototype.value=function(){return this.$}})(); +(function(s,v){var w={I:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",wa:function(a){var b="",c,d,e,g,i,l,n=0;for(a=w.Cc(a);n<a.length;){c=a.charCodeAt(n++);d=a.charCodeAt(n++);e=a.charCodeAt(n++);g=c>>2;c=(c&3)<<4|d>>4;i=(d&15)<<2|e>>6;l=e&63;if(isNaN(d))i=l=64;else if(isNaN(e))l=64;b=b+this.I.charAt(g)+this.I.charAt(c)+this.I.charAt(i)+this.I.charAt(l)}return b},ef:function(a){var b="",c,d,e,g,i,l=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");l<a.length;){c=this.I.indexOf(a.charAt(l++)); +d=this.I.indexOf(a.charAt(l++));g=this.I.indexOf(a.charAt(l++));i=this.I.indexOf(a.charAt(l++));c=c<<2|d>>4;d=(d&15)<<4|g>>2;e=(g&3)<<6|i;b+=String.fromCharCode(c);if(g!=64)b+=String.fromCharCode(d);if(i!=64)b+=String.fromCharCode(e)}return b=w.Bc(b)},Cc:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);if(d<128)b+=String.fromCharCode(d);else{if(d>127&&d<2048)b+=String.fromCharCode(d>>6|192);else{b+=String.fromCharCode(d>>12|224);b+=String.fromCharCode(d>> +6&63|128)}b+=String.fromCharCode(d&63|128)}}return b},Bc:function(a){for(var b="",c=0,d=c1=c2=0;c<a.length;){d=a.charCodeAt(c);if(d<128){b+=String.fromCharCode(d);c++}else if(d>191&&d<224){c2=a.charCodeAt(c+1);b+=String.fromCharCode((d&31)<<6|c2&63);c+=2}else{c2=a.charCodeAt(c+1);c3=a.charCodeAt(c+2);b+=String.fromCharCode((d&15)<<12|(c2&63)<<6|c3&63);c+=3}}return b}};if(typeof v.getAttribute=="undefined")v.getAttribute=x();if(typeof Node=="undefined")Node={ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3, +CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12};if(_.H(s.Cf))nglr={};if(_.H(s.Fe))angular={};if(_.H(angular.j))angular.j={};if(_.H(angular.filter))angular.filter={};if(_.H(s.console))s.console={log:x(),error:x()};if(_.H(alert))alert=function(){console.log(arguments);s.alert.apply(s,arguments)};consoleLog=function(a,b){var c=v.createElement("div");c.className=a; +for(var d=a="",e=0;e<b.length;e++){var g=b[e];a+=d+(typeof g=="string"?g:toJson(g));d=" "}c.appendChild(v.createTextNode(a));consoleNode.appendChild(c)};isNode=function(a){return a&&a.tagName&&a.nodeName&&a.ownerDocument&&a.removeAttribute};isLeafNode=function(a){switch(a.nodeName){case "OPTION":case "PRE":case "TITLE":return true;default:return false}};noop=x();setHtml=function(a,b){if(isLeafNode(a))if(msie)a.innerText=b;else a.textContent=b;else a.innerHTML=b};escapeHtml=function(a){if(!a||!a.replace)return a; +return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")};escapeAttr=function(a){if(!a||!a.replace)return a;return a.replace(/</g,"<").replace(/>/g,">").replace(/\"/g,""")};bind=function(a,b){if(!a)throw"Missing this";if(!_.K(b))throw"Missing function";return function(){return b.apply(a,arguments)}};shiftBind=function(a,b){return function(){for(var c=[this],d=0;d<arguments.length;d++)c.push(arguments[d]);return b.apply(a,c)}};outerHTML=function(a){var b=v.createElement("div"); +b.appendChild(a);var c=b.innerHTML;b.removeChild(a);return c};trim=function(a){return a.replace(/^ */,"").replace(/ *$/,"")};toBoolean=function(a){var b=(""+a).toLowerCase();if(b=="f"||b=="0"||b=="false"||b=="no")a=false;return!!a};merge=function(a,b){for(var c in a){var d=b[c],e=typeof d;if(e=="undefined")b[c]=fromJson(toJson(a[c]));else e=="object"&&d.constructor!=array&&c.substring(0,1)!="$"&&merge(a[c],d)}};Loader=function(a,b,c){this.document=jQuery(a);this.Ib=jQuery(b);this.o=c;this.location= +s.location};Loader.prototype.load=function(){this.Rc();this.Qb("/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css");this.Qb("/stylesheets/css");console.log("Server: "+this.o.M);msie=jQuery.Oe.Bf;this.Qc();this.Pc();this.Mc()};Loader.prototype.Qc=function(){console.log("Loader.configureJQueryPlugins()");jQuery.c.removeNode=function(){var a=this.h(0);a.parentNode.removeChild(a)};jQuery.c.scope=function(){for(var a=this;a&&a.h(0);){var b=a.data("scope");if(b)return b;a=a.parent()}return null};jQuery.c.$e= +function(){return this.data("controller")||NullController.nd}};Loader.prototype.ee=function(){return""+(new Date).getTime()};Loader.prototype.Pc=function(){var a=this.o;if(!a.T){var b=a.M.match(/https?:\/\/([\w]*)/);a.T=b?b[1]:"$MEMORY"}};Loader.prototype.Mc=function(){function a(){i.Bb(function(p){!p&&c.find("[ng-auth=eager]").length&&i.Ca()})}console.log("Loader.bindHtml()");var b=new UrlWatcher(this.location),c=this.document,d=new WidgetFactory(this.o.M,this.o.T),e=new Binder(c[0],d,b,this.o); +d.Nd=shiftBind(e,e.i);d=new ControlBar(c.find("body"),this.o.M);var g=this.o.T=="$MEMORY"?new FrameServer(this.window):new Server(this.o.M,jQuery.Fb);g=new VisualServer(g,new Status(jQuery(c.body)),function(){e.d()});var i=new Users(g,d),l="/data/"+this.o.T,n=new DataStore(function(p,r){g.la("POST",l,p,r)},i,e.anchor);e.lc.push(function(){n.Db()});var o=new Scope({pe:e.anchor,qe:e,re:this.o,se:s.console,te:n,pa:function(p){n.Wd(o.F,p,e.anchor)},ze:s,xe:this.ee,ye:i},"ROOT");jQuery.b(["get","set", +"eval","addWatchListener","updateView"],function(p,r){angular[r]=bind(o,o[r])});c.data("scope",o);console.log("$binder.entity()");e.da(o);console.log("$binder.compile()");e.compile();console.log("ControlBar.bind()");d.B();console.log("$users.fetchCurrentUser()");a();console.log("PopUp.bind()");(new PopUp(c)).B();console.log("$binder.parseAnchor()");e.Zb();console.log("$binder.executeInit()");e.dd();console.log("$binder.updateView()");e.d();b.Ob=bind(e,e.Pd,b);b.Ef=function(){alert("update")};b.watch(); +c.find("body").cb();console.log("ready()")};Loader.prototype.Rc=function(){var a=s.location.href+"#";a=a.split("#")[1];var b={Xc:null};a=a.split("&");for(var c=0;c<a.length;c++){var d=(a[c]+"=").split("=");b[d[0]]=d[1]}if(b.Xc=="console"){consoleNode=v.createElement("div");consoleNode.id="ng-console";v.getElementsByTagName("body")[0].appendChild(consoleNode);console.log=function(){consoleLog("ng-console-info",arguments)};console.error=function(){consoleLog("ng-console-error",arguments)}}};Loader.prototype.Qb= +function(a){var b=v.createElement("link");b.rel="stylesheet";b.type="text/css";a.match(/^http:/)||(a=this.o.M+a);b.href=a;this.Ib[0].appendChild(b)};UrlWatcher=function(a){this.location=a;this.Ta=25;this.setTimeout=function(b,c){s.setTimeout(b,c)};this.Ob=u();this.ea=a.href};UrlWatcher.prototype.watch=function(){var a=this;function b(){if(a.ea!==a.location.href){var c=a.location.hash.match(/^#\$iframe_notify=(.*)$/);if(c){a.ea.match(/#/)||(a.ea+="#");a.location.href=a.ea;c="_iframe_notify_"+c[1]; +var d=nglr[c];delete nglr[c];try{(d||noop)()}catch(e){alert(e)}}else{a.Ob(a.location.href);a.ea=a.location.href}}a.setTimeout(b,a.Ta)}b()};UrlWatcher.prototype.Zd=function(a){var b=s.location.href;b.match(/#/)||(b+="#");if(b!=a)s.location.href=a;self.ff=a};UrlWatcher.prototype.Gb=function(){return s.location.href};angular.compile=function(a,b){b=b||{};(new Loader(a,jQuery("head"),_({M:""}).extend(b))).load();return jQuery(a).scope()};angular.Y={de:function(a){var b=typeof a;switch(b){case "object":if(a=== +null)return"null";if(a instanceof Array)return"array";if(a instanceof Date)return"date";if(a.nodeType==1)return"element"}return b}};angular.La={};angular.xc={};angular.Ka={md:function(a,b,c){var d=_.indexOf(a,b);if(c)d==-1&&a.push(b);else a.splice(d,1);return a},Vf:function(a,b){b=angular.X.compile(b);for(var c=0,d=0;d<a.length;d++){var e=1*b(a[d]);isNaN(e)||(c+=e)}return c},remove:function(a,b){var c=_.indexOf(a,b);c>=0&&a.splice(c,1);return b},find:function(a,b,c){if(b){var d=angular.X.compile(b); +_.xb(a,function(e){if(d(e)){c=e;return true}});return c}},gf:function(a,b){return angular.Ka.find(a,function(c){return c.N==b},null)},filter:function(a,b){var c=[];c.Nc=function(o){for(var p=0;p<c.length;p++)if(!c[p](o))return false;return true};var d=Scope.fa;function e(o,p){if(p.charAt(0)==="!")return!e(o,p.substr(1));switch(typeof o){case "boolean":case "number":case "string":return(""+o).toLowerCase().indexOf(p)>-1;case "object":for(var r in o)if(r.charAt(0)!=="$"&&e(o[r],p))return true;return false; +case "array":for(r=0;r<o.length;r++)if(e(o[r],p))return true;return false;default:return false}}switch(typeof b){case "boolean":case "number":case "string":b={oe:b};case "object":for(var g in b)g=="$"?function(){var o=(""+b[g]).toLowerCase();o&&c.push(function(p){return e(p,o)})}():function(){var o=g,p=(""+b[g]).toLowerCase();p&&c.push(function(r){return e(d(r,o),p)})}();break;case "function":c.push(b);break;default:return a}for(var i=[],l=0;l<a.length;l++){var n=a[l];c.Nc(n)&&i.push(n)}return i}, +add:function(a,b){a.push(_.H(b)?{}:b);return a},af:function(a,b){if(!b)return a.length;var c=angular.X.compile(b);return _.reduce(a,0,function(d,e){return d+(c(e)?1:0)})},Ff:function(a,b,c){function d(g,i){return toBoolean(i)?function(l,n){return g(n,l)}:g}function e(g,i){var l=typeof g,n=typeof i;if(l==n){if(l=="string")g=g.toLowerCase();if(l=="string")i=i.toLowerCase();if(g===i)return 0;return g<i?-1:1}else return l<n?-1:1}b=_.q(b)?b:[b];b=_.map(b,function(g){var i=false;if(typeof g=="string"&& +(g.charAt(0)=="+"||g.charAt(0)=="-")){i=g.charAt(0)=="-";g=g.substring(1)}var l=g?angular.X.compile(g):_.ga;return d(function(n,o){return e(l(n),l(o))},i)});return _.ua(a).sort(d(function(g,i){for(var l=0;l<b.length;l++){var n=b[l](g,i);if(n!=0)return n}return 0},c))},Hf:function(a,b){var c=false,d=-1;_.xb(a,function(e,g){if(e==b){c=true;d=g;return true}if((e.charAt(0)=="+"||e.charAt(0)=="-")&&e.substring(1)==b){c=e.charAt(0)=="+";d=g;return true}});d>=0&&a.splice(d,1);a.unshift((c?"-":"+")+b);return a}, +Gf:function(a,b,c,d){c=c||"ng-ascend";d=d||"ng-descend";a=a[0]||"";var e=true;if(a.charAt(0)=="-"){a=a.substring(1);e=false}else if(a.charAt(0)=="+")a=a.substring(1);return a==b?e?c:d:""},zf:function(a,b,c){var d=a[b];if(!d){d={};a[b]=d}merge(c,d);return a}};angular.O={quote:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v")+'"'},cc:function(a){a=angular.O.quote(a);for(var b=[], +c=0;c<a.length;c++){var d=a.charCodeAt(c);if(d<128)b.push(a.charAt(c));else{d="000"+d.toString(16);b.push("\\u"+d.substring(d.length-4))}}return b.join("")},be:function(a){var b;if(typeof a=="string"&&(b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/))){a=new Date(0);a.setUTCFullYear(b[1],b[2]-1,b[3]);a.setUTCHours(b[4],b[5],b[6],0);return a}return a}};angular.tc={toString:function(a){function b(c){return c<10?"0"+c:c}return a.getUTCFullYear()+"-"+b(a.getUTCMonth()+1)+"-"+b(a.getUTCDate())+ +"T"+b(a.getUTCHours())+":"+b(a.getUTCMinutes())+":"+b(a.getUTCSeconds())+"Z"}};angular.X={compile:function(a){if(_.K(a))return a;else if(a){var b=new Scope;return function(c){b.F=c;return b.eval(a)}}else return u()}};(function(){function a(b,c,d){_.extend(b,c);_.b(d||[],function(e){b[e]=_[e]})}a(angular.Y,{},["extend","clone","isEqual","isElement","isArray","isFunction","isUndefined"]);a(angular.La,angular.Y,["each","map","reduce","reduceRight","detect","select","reject","all","any","include","invoke", +"pluck","max","min","sortBy","sortedIndex","toArray","size"]);a(angular.Ka,angular.La,["first","last","compact","flatten","without","uniq","intersect","zip","indexOf","lastIndexOf"]);a(angular.xc,angular.La,["keys","values"]);a(angular.O,angular.Y);a(angular.X,angular.Y,["bind","bindAll","delay","defer","wrap","compose"])})();Binder=function(a,b,c,d){this.Q=a;this.fb=c;this.anchor={};this.me=b;this.o=d||{};this.lc=[]};Binder.Ea=function(a){for(var b=[],c=0,d;(d=a.indexOf("{{",c))>-1;){c<d&&b.push(a.substr(c, +d-c));c=d;d=a.indexOf("}}",d);d=d<0?a.length:d+2;b.push(a.substr(c,d-c));c=d}c!=a.length&&b.push(a.substr(c,a.length-c));return b.length===0?[a]:b};Binder.ld=function(a){a=Binder.Ea(a);return a.length>1||Binder.ba(a[0])!==null};Binder.ba=function(a){return(a=a.replace(/\n/gm," ").match(/^\{\{(.*)\}\}$/))?a[1]:null};Binder.prototype.Qd=function(a){var b={};a.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(c,d,e){if(d)b[decodeURIComponent(d)]=decodeURIComponent(e)});return b};Binder.prototype.Zb=function(a){var b= +this;a=a||this.fb.Gb();var c=a.indexOf("#");if(!(c<0)){a=this.Qd(a.substring(c+1));jQuery.b(b.anchor,function(d){delete b.anchor[d]});jQuery.b(a,function(d,e){b.anchor[d]=e})}};Binder.prototype.Pd=function(a){console.log("URL change detected",a);this.Zb(a);this.d()};Binder.prototype.ge=function(){var a=this.fb.Gb(),b=a.indexOf("#");if(b>-1)a=a.substring(0,b);a+="#";b="";for(var c in this.anchor){var d=this.anchor[c];if(typeof d==="undefined"||d===null)delete this.anchor[c];else{a+=b+encodeURIComponent(c); +if(d!==true)a+="="+encodeURIComponent(d);b="&"}}this.fb.Zd(a);return a};Binder.prototype.d=function(){(new Date).getTime();var a=jQuery(this.Q).scope();a.s("$invalidWidgets",[]);a.d();(new Date).getTime();this.ge();_.b(this.lc,function(b){b()})};Binder.prototype.va=function(a){var b=jQuery(this.Q),c=b.find(a);if(b.od(a))c=c.Ee();return c};Binder.prototype.dd=function(){this.va("[ng-init]").b(function(){var a=jQuery(this),b=a.scope();try{b.eval(a.g("ng-init"))}catch(c){alert("EVAL ERROR:\n"+a.g("ng-init")+ +"\n"+toJson(c,true))}})};Binder.prototype.da=function(a){this.va("[ng-entity]").g("ng-watch",function(){try{var b=jQuery(this);return a.da(b.g("ng-entity"))+(b.g("ng-watch")||"")}catch(c){alert(c)}})};Binder.prototype.compile=function(){var a=jQuery(this.Q),b=this;if(this.o.He){var c=this.va(":submit").Yb("[ng-action]");c.g("ng-action","$save()");c.Yb(":disabled").Yb("ng-bind-attr").g("ng-bind-attr",'{disabled:"{{$invalidWidgets}}"}')}this.ac(this.Q)(this.Q,a.scope(),"");this.va("a[ng-action]").xd("click", +function(){var d=jQuery(this);try{d.scope().eval(d.g("ng-action"));d.fc("ng-error");d.gc("ng-exception")}catch(e){d.Oa("ng-exception");d.g("ng-error",toJson(e,true))}b.d();return false})};Binder.prototype.ce=function(a,b,c){b=b.concat();var d=b.pop(),e=Binder.Ea(a.nodeValue);if(e.length>1||Binder.ba(e[0])){var g=a.parentNode;if(isLeafNode(g)){g.setAttribute("ng-bind-template",a.nodeValue);c.push({path:b,c:function(p){return new BindUpdater(p,p.getAttribute("ng-bind-template"))}})}else for(var i=0;i< +e.length;i++){var l=e[i],n=Binder.ba(l),o;if(n){o=v.createElement("span");jQuery(o).g("ng-bind",n);i===0&&c.push({path:b.concat(d+i),c:Binder.prototype.Xb})}else if(msie&&l.charAt(0)==" "){o=v.createElement("span");o.innerHTML=" "+l.substring(1)}else o=v.createTextNode(l);g.insertBefore(o,a)}g.removeChild(a)}};Binder.prototype.ac=function(a){var b=[];this.bc(a,[],b);return function(c,d,e){for(var g=b.length,i=0;i<g;i++){for(var l=b[i],n=c,o=l.path,p=0;p<o.length;p++)n=n.childNodes[o[p]];try{d.Fc(l.c(n, +d,e))}catch(r){alert(r)}}}};Binder.prototype.bc=function(a,b,c){var d=a.nodeType;if(d==Node.TEXT_NODE)this.ce(a,b,c);else if(!(d!=Node.ELEMENT_NODE&&d!=Node.DOCUMENT_NODE))if(a.getAttribute){d=a.getAttribute("ng-non-bindable");if(!(d||d==="")){if(d=a.attributes){var e=a.getAttribute("ng-bind-attr");a.removeAttribute("ng-bind-attr");e=e?fromJson(e):{};for(var g=d.length,i=0;i<g;i++){var l=d[i],n=l.name;l=msie&&n=="href"?decodeURI(a.getAttribute(n,2)):l.value;if(Binder.ld(l))e[n]=l}d=toJson(e);d.length> +2&&a.setAttribute("ng-bind-attr",d)}a.getAttribute||console.log(a);var o=a.getAttribute("ng-repeat");if(o){a.removeAttribute("ng-repeat");var p=this.ac(a);d=v.createComment("ng-repeat: "+o);e=a.parentNode;e.insertBefore(d,a);e.removeChild(a);var r=function(h,j,k){var m=jQuery(a).ua();m.Sa("display","");m.g("ng-repeat-index",""+k);m.data("scope",h);p(m[0],h,j+k+":");return m};c.push({path:b,c:function(h,j,k){return new RepeaterUpdater(jQuery(h),o,r,k)}})}else{a.getAttribute("ng-eval")&&c.push({path:b, +c:this.Hd});a.getAttribute("ng-bind")&&c.push({path:b,c:this.Xb});a.getAttribute("ng-bind-attr")&&c.push({path:b,c:this.Dd});a.getAttribute("ng-hide")&&c.push({path:b,c:this.Id});a.getAttribute("ng-show")&&c.push({path:b,c:this.Jd});a.getAttribute("ng-class")&&c.push({path:b,c:this.Ed});a.getAttribute("ng-class-odd")&&c.push({path:b,c:this.Gd});a.getAttribute("ng-class-even")&&c.push({path:b,c:this.Fd});a.getAttribute("ng-style")&&c.push({path:b,c:this.Kd});a.getAttribute("ng-watch")&&c.push({path:b, +c:this.Ld});d=a.nodeName;if(d=="INPUT"||d=="TEXTAREA"||d=="SELECT"||d=="BUTTON"){var f=this;c.push({path:b,c:function(h,j,k){h.name=k+h.name.split(":").pop();return f.me.Sc(jQuery(h),j)}})}if(d=="OPTION")if(!jQuery("<select/>").append(jQuery(a).ua()).w().match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi))a.value=a.text;d=a.childNodes;for(e=0;e<d.length;e++)this.bc(d[e],b.concat(e),c)}}}};Binder.prototype.Hd=function(a){return new EvalUpdater(a,a.getAttribute("ng-eval"))};Binder.prototype.Xb= +function(a){return new BindUpdater(a,"{{"+a.getAttribute("ng-bind")+"}}")};Binder.prototype.Dd=function(a){return new BindAttrUpdater(a,fromJson(a.getAttribute("ng-bind-attr")))};Binder.prototype.Id=function(a){return new HideUpdater(a,a.getAttribute("ng-hide"))};Binder.prototype.Jd=function(a){return new ShowUpdater(a,a.getAttribute("ng-show"))};Binder.prototype.Ed=function(a){return new ClassUpdater(a,a.getAttribute("ng-class"))};Binder.prototype.Fd=function(a){return new ClassEvenUpdater(a,a.getAttribute("ng-class-even"))}; +Binder.prototype.Gd=function(a){return new ClassOddUpdater(a,a.getAttribute("ng-class-odd"))};Binder.prototype.Kd=function(a){return new StyleUpdater(a,a.getAttribute("ng-style"))};Binder.prototype.Ld=function(a,b){b.watch(a.getAttribute("ng-watch"))};ControlBar=function(a,b){this.document=a;this.Ia=b;this.window=s;this.S=[]};ControlBar.prototype.B=x();ControlBar.Ae='<div><div class="ui-widget-overlay"></div><div id="ng-login" ng-non-bindable="true"><div class="ng-login-container"></div></div></div>'; +ControlBar.prototype.Ca=function(a){this.S.push(a);this.S.length==1&&this.zb("/user_session/new.mini?return_url="+encodeURIComponent(this.mc()))};ControlBar.prototype.Vb=function(a){this.S.push(a);this.S.length==1&&this.zb("/user_session/do_destroy.mini")};ControlBar.prototype.mc=function(){return this.window.location.href.split("#")[0]};ControlBar.prototype.zb=function(a){var b=this,c=(new Date).getTime(),d=this.mc();d+="#$iframe_notify="+c;var e=jQuery('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+ +d+'" src="'+this.Ia+a+'" width="500" height="330"/></div>');this.document.append(e);e.yb({height:363,width:500,Qf:false,Ad:true,title:'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>'});nglr["_iframe_notify_"+c]=function(){e.yb("destroy");e.remove();jQuery.b(b.S,function(g,i){i()});b.S=[]}};ControlBar.vc='<div ng-non-bindable="true" title="Permission Error:">Sorry, you do not have permission for this!</div>';ControlBar.prototype.Za=function(){if(!this.Eb){this.Eb= +jQuery(ControlBar.vc);this.Eb.yb({Me:true,height:70,Ad:true})}};DataStore=function(a,b,c){this.$b=a;this.nc=b;this.P={na:[]};this.anchor=c;this.ra=[]};DataStore.prototype.sa=function(a){if(a.constructor!=Model)throw"Parameter must be an instance of Entity! "+toJson(a);var b=a.oa+"/"+a.N,c=this.P[b];if(c)Model.Ra(a,c);else c=this.P[b]=a;return c};DataStore.prototype.load=function(a,b,c,d){if(b&&b!=="*"){var e=this;this.R(["GET",a.oa+"/"+b],function(g){a.W(g);a.kb();g=a.ma(a);e.sa(g);(c||noop)(a)}, +d)}return a};DataStore.prototype.Wa=function(a,b,c){var d=this,e=[],g=0;jQuery.b(b,function(i,l){e.push(d.load(a(),l,function(){g++;if(g==b.length)(c||noop)(e)}))});return e};DataStore.prototype.Rb=function(a,b,c){return this.load(a,b,c,function(d){if(d.Ja==404){a.N=b;(c||noop)(a)}else throw d;})};DataStore.prototype.yd=function(a,b){var c=this,d=[];d.ib=function(e){return e.oa==a.title};this.P.na.push(d);this.R(["GET",a.title],function(e){for(var g=0;g<e.length;g++){var i=a();i.W(e[g]);d.push(c.sa(i))}(b|| +noop)(d)});return d};DataStore.prototype.save=function(a,b){var c=this,d={};a.lb(d);this.R(["POST","",d],function(e){a.W(e);var g=c.sa(a);_.b(c.P.na,function(i){i.ib(a)&&angular.Ka.md(i,g,true)});if(a.jb)c.anchor[a.jb]=a.N;b&&b(a)})};DataStore.prototype.remove=function(a,b){var c=this,d={};a.lb(d);this.R(["DELETE","",d],function(e){delete c.P[a.oa+"/"+a.N];_.b(c.P.na,function(g){for(var i=0;i<g.length;i++)g[i].N==a.N&&g.splice(i,1)});(b||noop)(e)})};DataStore.prototype.R=function(a,b,c){a.pc=b;a.rc= +c||function(d){throw d;};this.ra.push(a)};DataStore.prototype.Db=function(){function a(d,e){console.log("RESPONSE["+d+"]: ",e);if(e.Ja==401)b.nc.Ca(function(){b.$b(c,a)});else if(e.Ja)alert(toJson(e));else for(var g=0;g<e.length;g++){var i=e[g],l=c[g];if(d=i.Ja)d==403?b.nc.Za():l.rc(i);else l.pc(i)}}if(this.ra.length!==0){var b=this,c=this.ra;this.ra=[];console.log("REQUEST:",c);this.$b(c,a)}};DataStore.prototype.Wd=function(a,b){function c(){d--;d===0&&b&&b()}var d=1;for(var e in a){var g=a[e];if(g&& +g.pa==Model.prototype.pa){d++;g.pa(c)}}c()};DataStore.prototype.ja=function(a,b,c,d){var e=this,g=[];g.ib=z(false);this.P.na.push(g);this.R(["GET",a.title+"/"+b+"="+c],function(i){for(var l=0;l<i.length;l++){var n=(new a).W(i[l]);g.push(e.sa(n))}d&&d(g)});return g};DataStore.Z=x();DataStore.Z.all=function(){return[]};DataStore.Z.ja=function(){return[]};DataStore.Z.load=function(){return{}};DataStore.Z.title=undefined;DataStore.prototype.da=function(a,b){if(!a)return DataStore.Z;var c=this;function d(e){return new Model(d, +e)}d.title=a;d.qc=true;d.wb=this;d.Yc=b||{};d.load=function(e,g){return c.load(d(),e,g)};d.Wa=function(e,g){return c.Wa(d,e,g)};d.Rb=function(e,g){return c.Rb(d(),e,g)};d.all=function(e){return c.yd(d,e)};d.ja=function(e,g,i){return c.ja(d,e,g,i)};d.Nf=function(e){c.R(["GET",a+"/$properties"],e)};return d};DataStore.prototype.join=function(a){function b(){throw"Joined entities can not be instantiated into a document.";}var c=_(a).rb().map(function(d,e){return e}).$d(function(d){var e=[];do{if(_(e).ya(d))throw"Infinite loop in join: "+ +e.join(" -> ");e.push(d);if(!a[d])throw _("Named entity '<%=name%>' is undefined.").V({name:d});d=a[d].Da?a[d].Da.substring(0,a[d].Da.indexOf(".")):undefined}while(d);return e.length}).value();if(_(c).select(function(d){return a[d].Da}).length!=c.length-1)throw"Exactly one entity needs to be primary.";b.ja=function(d,e){var g=[],i=d?d.substring(0,d.indexOf(".")):undefined;if(i!=c[0])throw _("Named entity '<%=name%>' is not a primary entity.").V({name:i});var l=1;a[i].join.ja(d.substring(d.indexOf(".")+ +1),e,function(n){var o=c[l++],p=a[o],r=p.Da,f={};_(n).b(function(h){var j={};g.push(j);j[i]=h;h=Scope.fa(j,r);f[h]=h});p.join.Wa(_.A(f),function(h){var j={};_(h).b(function(k){j[k.N]=k});_(g).b(function(k){var m=Scope.fa(k,r);k[o]=j[m]})})});return g};return b};angular.filter.m=function(a){if(a)for(var b in a)this[b]=a[b]};angular.filter.m.h=function(a,b){b=b||"text";switch(typeof a){case "string":return b=="text"?a:undefined;case "object":if(a&&typeof a[b]!=="undefined")return a[b];return;default:return a}}; +angular.filter.bf=function(a){jQuery(this.element).eb("ng-format-negative",a<0);return"$"+angular.filter.$a.apply(this,[a,2])};angular.filter.$a=function(a,b){if(isNaN(a)||!isFinite(a))return"";b=typeof b=="undefined"?2:b;var c=a<0;a=Math.abs(a);var d=Math.pow(10,b);a=""+Math.round(a*d);var e=a.substring(0,a.length-b);e=e||"0";d=a.substring(a.length-b);a=c?"-":"";for(c=0;c<e.length;c++){if((e.length-c)%3===0&&c!==0)a+=",";a+=e.charAt(c)}if(b>0){for(c=d.length;c<b;c++)d+="0";a+="."+d.substring(0,b)}return a}; +angular.filter.Vc=x();angular.filter.td=function(a){jQuery(this.element).Oa("ng-monospace");return toJson(a,true)};angular.filter.jc=function(a,b){a=trim(a);for(var c=a.replace(/ /g,""),d=angular.filter.jc.wc,e=0;e<d.length;e++)for(var g=d[e],i=0;i<g.ka.length;i++)if(g.ka[i].test(c)){b=g.name+": "+a;g=g.url+a;return new angular.filter.m({text:b,url:g,w:'<a href="'+escapeAttr(g)+'">'+b+"</a>",Xf:a})}return a?b||new angular.filter.m({text:a+" is not recognized"}):null};angular.filter.jc.wc=[{name:"UPS", +url:"http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",ka:[/^1Z[0-9A-Z]{16}$/i]},{name:"FedEx",url:"http://www.fedex.com/Tracking?tracknumbers=",ka:[/^96\d{10}?$/i,/^96\d{17}?$/i,/^96\d{20}?$/i,/^\d{15}$/i,/^\d{12}$/i]},{name:"USPS",url:"http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",ka:[/^(91\d{20})$/i,/^(91\d{18})$/i]}];angular.filter.link=function(a,b){b= +b||angular.filter.m.h(a);var c=angular.filter.m.h(a,"url")||angular.filter.m.h(a);if(c){if(angular.j.$c(c)===null)c="mailto:"+c;a='<a href="'+escapeHtml(c)+'">'+b+"</a>";return new angular.filter.m({text:b,url:c,w:a})}return a};angular.filter.Pa=function(a){if(a===null)return"";for(var b=0;a>1E3;){a/=1024;b++}a=""+a;var c=a.indexOf(".");if(c>-1&&c+2<a.length)a=a.substring(0,c+2);return a+" "+angular.filter.Pa.yc[b]};angular.filter.Pa.yc=["bytes","KB","MB","GB","TB","PB"];angular.filter.nf=function(a, +b,c){if(a&&a.url){var d="";if(b)d=' style="max-width: '+b+"px; max-height: "+(c||b)+'px;"';return new angular.filter.m({url:a.url,text:a.url,w:'<img src="'+a.url+'"'+d+"/>"})}return null};angular.filter.xf=function(a){return(a=angular.filter.m.h(a))?(""+a).toLowerCase():a};angular.filter.cg=function(a){return(a=angular.filter.m.h(a))?(""+a).toUpperCase():a};angular.filter.wf=function(a){a=angular.filter.m.h(a);if(a===""||!a)return 1;return a.split(/\n|\f/).length};angular.filter["if"]=function(a, +b){return b?a:undefined};angular.filter.ag=function(a,b){return b?undefined:a};angular.filter.k=function(a,b,c,d){b=b||{};var e=angular.filter.k;a={Oc:a,Qe:e.tb(b,"color"),We:e.title(b),Se:e.tb(b,"label"),Re:e.gb(b),Te:"bg,s,FFFFFF00"};if(_.q(b.ne)){a.Ye="x";a.Xe="0:|"+b.ne.join("|")}return angular.filter.k.wa(a,c,d)};angular.filter.k.gb=function(a){var b=[];_.b(a.Yd||[],function(c){var d=[];_.b(c.gb||[],function(e){d.push(e)});b.push(d.join(","))});a=b.join("|");return a===""?null:"t:"+a};angular.filter.k.title= +function(a){var b=[];a=a.title||[];_.b(_.q(a)?a:[a],function(c){b.push(encodeURIComponent(c))});return b.join("|")};angular.filter.k.tb=function(a,b){var c=[],d=0;_.b(a.Yd||[],function(e){var g=[];e=e[b]||[];_.b(_.q(e)?e:[e],function(i){g.push(encodeURIComponent(i));d++});c.push(g.join("|"))});return d?c.join(","):null};angular.filter.k.wa=function(a,b,c){b=b||200;c=c||b;var d="http://chart.apis.google.com/chart?",e=[];a.Ve=b+"x"+c;for(var g in a){var i=a[g];i&&e.push(g+"="+i)}e.sort();d+=e.join("&"); +return new angular.filter.m({url:d,text:i,w:'<img width="'+b+'" height="'+c+'" src="'+d+'"/>'})};angular.filter.Of=function(a,b,c){return angular.filter.k.wa({Oc:"qr",Ue:encodeURIComponent(a)},b,c)};angular.filter.Pe={Kf:function(a,b,c){return angular.filter.k("p",a,b,c)},Lf:function(a,b,c){return angular.filter.k("p3",a,b,c)},Mf:function(a,b,c){return angular.filter.k("pc",a,b,c)},Je:function(a,b,c){return angular.filter.k("bhs",a,b,c)},Ie:function(a,b,c){return angular.filter.k("bhg",a,b,c)},Le:function(a, +b,c){return angular.filter.k("bvs",a,b,c)},Ke:function(a,b,c){return angular.filter.k("bvg",a,b,c)},vf:function(a,b,c){return angular.filter.k("lc",a,b,c)},Tf:function(a,b,c){return angular.filter.k("ls",a,b,c)},Rf:function(a,b,c){return angular.filter.k("s",a,b,c)}};angular.filter.w=function(a){return new angular.filter.m({w:a})};array=[].constructor;toJson=function(a,b){var c=[];toJsonArray(c,a,b?"\n  ":null);return c.join("")};toPrettyJson=function(a){return toJson(a,true)};fromJson=function(a){try{var b= +new Parser(a,true),c=b.Ga();b.aa();return c()}catch(d){console.error("fromJson error: ",a,d);throw d;}};toJsonArray=function(a,b,c){var d=typeof b;if(b===null)a.push("null");else if(d!=="function")if(d==="boolean")a.push(""+b);else if(d==="number")isNaN(b)?a.push("null"):a.push(""+b);else if(d==="string")return a.push(angular.O.cc(b));else if(d==="object")if(b instanceof Array){a.push("[");var e=b.length;d=false;for(var g=0;g<e;g++){var i=b[g];d&&a.push(",");typeof i=="function"||typeof i=="undefined"? +a.push("null"):toJsonArray(a,i,c);d=true}a.push("]")}else if(b instanceof Date)a.push(angular.O.cc(angular.tc.toString(b)));else{a.push("{");c&&a.push(c);d=false;g=c?c+"  ":false;i=[];for(var l in b)l.indexOf("$$")!==0&&i.push(l);i.sort();for(l=0;l<i.length;l++){var n=i[l];try{e=b[n];if(typeof e!="function"){if(d){a.push(",");c&&a.push(c)}a.push(angular.O.quote(n));a.push(":");toJsonArray(a,e,g);d=true}}catch(o){}}a.push("}")}};Model=function(a,b){this.ma=a;this.W(b||{});this.oa=a.title;this.kb()}; +Model.Ra=function(a,b){if(!(a===b||!a||!b)){var c=function(e,g,i){return i.substring(0,2)!=="$$"&&typeof e[i]!=="function"&&typeof g[i]!=="function"};for(var d in b)c(a,b,d)&&delete b[d];for(d in a)if(c(a,b,d))b[d]=a[d]}};Model.prototype.kb=function(){merge(this.ma.Yc,this);return this};Model.prototype.pa=function(a){this.ma.wb.save(this,a===true?undefined:a);a===true&&this.ma.wb.Db();return this};Model.prototype.W=function(a){Model.Ra(a,this);return this};Model.prototype.lb=function(a){Model.Ra(this, +a);return this};Lexer=function(a,b){this.text=a;this.Wc=b?20:-1;this.l=[];this.index=0};Lexer.mb={"null":z(null),"true":z(true),"false":z(false),"+":function(a,b,c){return(b||0)+(c||0)},"-":function(a,b,c){return(b||0)-(c||0)},"*":function(a,b,c){return b*c},"/":function(a,b,c){return b/c},"%":function(a,b,c){return b%c},"^":function(a,b,c){return b^c},"=":function(a,b,c){return a.scope.s(b,c)},"==":function(a,b,c){return b==c},"!=":function(a,b,c){return b!=c},"<":function(a,b,c){return b<c},">":function(a, +b,c){return b>c},"<=":function(a,b,c){return b<=c},">=":function(a,b,c){return b>=c},"&&":function(a,b,c){return b&&c},"||":function(a,b,c){return b||c},"&":function(a,b,c){return b&c},"|":function(a,b,c){return c(a,b)},"!":function(a,b){return!b}};Lexer.prototype.U=function(){return this.index+1<this.text.length?this.text.charAt(this.index+1):false};Lexer.prototype.parse=function(){for(var a=this.l,b=Lexer.mb,c=true;this.index<this.text.length;){var d=this.text.charAt(this.index);if(d=='"'||d=="'"){this.Ud(d); +c=true}else if(d=="("||d=="["){a.push({index:this.index,text:d});this.index++}else if(d=="{"){c=this.U();if(c==":"||c=="("){a.push({index:this.index,text:d+c});this.index++}else a.push({index:this.index,text:d});this.index++;c=true}else if(d==")"||d=="]"||d=="}"){a.push({index:this.index,text:d});this.index++;c=false}else if(d==":"||d=="."||d==","||d==";"){a.push({index:this.index,text:d});this.index++;c=true}else if(c&&d=="/"){this.Td();c=false}else if(this.ha(d)){this.Sd();c=false}else if(this.Aa(d)){this.dc(); +c=false}else if(this.sd(d))this.index++;else{c=d+this.U();var e=b[d],g=b[c];if(g){a.push({index:this.index,text:c,c:g});this.index+=2}else if(e){a.push({index:this.index,text:d,c:e});this.index+=1}else throw"Lexer Error: Unexpected next character ["+this.text.substring(this.index)+"] in expression '"+this.text+"' at column '"+(this.index+1)+"'.";c=true}}return a};Lexer.prototype.ha=function(a){return"0"<=a&&a<="9"};Lexer.prototype.sd=function(a){return a==" "||a=="\r"||a=="\t"||a=="\n"||a=="\u000b"}; +Lexer.prototype.Aa=function(a){return"a"<=a&&a<="z"||"A"<=a&&a<="Z"||"_"==a||a=="$"};Lexer.prototype.Sd=function(){for(var a="",b=this.index;this.index<this.text.length;){var c=this.text.charAt(this.index);if(c=="."||this.ha(c))a+=c;else break;this.index++}a=1*a;this.l.push({index:b,text:a,c:function(){return a}})};Lexer.prototype.dc=function(){for(var a="",b=this.index;this.index<this.text.length;){var c=this.text.charAt(this.index);if(c=="."||this.Aa(c)||this.ha(c))a+=c;else break;this.index++}c= +Lexer.mb[a];if(!c){c=function(d){return d.scope.h(a)};c.za=a}this.l.push({index:b,text:a,c:c})};Lexer.uc={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'};Lexer.prototype.Ud=function(a){var b=this.index,c=this.Wc;this.index++;for(var d="",e=false;this.index<this.text.length;){var g=this.text.charAt(this.index);if(e){if(g=="u"){g=this.text.substring(this.index+1,this.index+5);this.index+=4;d+=String.fromCharCode(parseInt(g,16))}else{e=Lexer.uc[g];d+=e?e:g}e=false}else if(g=="\\")e=true; +else if(g==a){this.index++;this.l.push({index:b,text:d,c:function(){return d.length==c?angular.O.be(d):d}});return}else d+=g;this.index++}throw"Lexer Error: Unterminated quote ["+this.text.substring(b)+"] starting at column '"+(b+1)+"' in expression '"+this.text+"'.";};Lexer.prototype.Td=function(){var a=this.index;this.index++;for(var b="",c=false;this.index<this.text.length;){var d=this.text.charAt(this.index);if(c){b+=d;c=false}else if(d==="\\"){b+=d;c=true}else if(d==="/"){this.index++;c="";if(this.Aa(this.text.charAt(this.index))){this.dc(); +c=this.l.pop().text}var e=new RegExp(b,c);this.l.push({index:a,text:b,hf:c,c:function(){return e}});return}else b+=d;this.index++}throw"Lexer Error: Unterminated RegExp ["+this.text.substring(a)+"] starting at column '"+(a+1)+"' in expression '"+this.text+"'.";};Parser=function(a,b){this.text=a;this.l=(new Lexer(a,b)).parse();this.index=0};Parser.zc=z(0);Parser.prototype.error=function(a,b){throw"Token '"+b.text+"' is "+a+" at column='"+(b.index+1)+"' of expression '"+this.text+"' starting at '"+ +this.text.substring(b.index)+"'.";};Parser.prototype.Fa=function(){if(this.l.length===0)throw"Unexpected end of expression: "+this.text;return this.l[0]};Parser.prototype.U=function(a,b,c,d){var e=this.l;if(e.length>0){e=e[0];var g=e.text;if(g==a||g==b||g==c||g==d||!a&&!b&&!c&&!d)return e}return false};Parser.prototype.a=function(a,b,c,d){if(a=this.U(a,b,c,d)){this.l.shift();return this.cf=a}return false};Parser.prototype.p=function(a){if(!this.a(a)){var b=this.U();throw"Expecting '"+a+"' at column '"+ +(b.index+1)+"' in '"+this.text+"' got '"+this.text.substring(b.index)+"'.";}};Parser.prototype.Ac=function(a,b){var c=b.apply(this);return function(d){return a(d,c(d))}};Parser.prototype.G=function(a,b,c){var d=c.apply(this);return function(e){return b(e,a(e),d(e))}};Parser.prototype.Hb=function(){return this.l.length>0};Parser.prototype.aa=function(){if(this.l.length!==0)throw"Did not understand '"+this.text.substring(this.l[0].index)+"' while evaluating '"+this.text+"'.";};Parser.prototype.db=function(){for(var a= +[];;){this.l.length>0&&!this.U("}",")",";","]")&&a.push(this.Cb());if(!this.a(";"))return function(b){for(var c,d=0;d<a.length;d++){var e=a[d];if(e)c=e(b)}return c}}};Parser.prototype.Cb=function(){for(var a=this.C(),b;;)if(b=this.a("|"))a=this.G(a,b.c,this.filter);else return a};Parser.prototype.filter=function(){return this.ob(angular.filter)};Parser.prototype.j=function(){return this.ob(angular.j)};Parser.prototype.ob=function(a){for(var b=this.kd(a),c=[];;)if(this.a(":"))c.push(this.C());else{var d= +function(e,g){g=[g];for(var i=0;i<c.length;i++)g.push(c[i](e));return b.apply(e,g)};return function(){return d}}};Parser.prototype.C=function(){return this.ae()};Parser.prototype.ae=function(){if(this.a("throw")){var a=this.qb();return function(b){throw a(b);}}else return this.qb()};Parser.prototype.qb=function(){var a=this.Ub(),b;if(b=this.a("=")){if(!a.za)throw"Left hand side '"+this.text.substring(0,b.index)+"' of assignment '"+this.text.substring(b.index)+"' is not assignable.";return this.G(function(){return a.za}, +b.c,this.Ub)}else return a};Parser.prototype.Ub=function(){for(var a=this.Tb(),b;;)if(b=this.a("||"))a=this.G(a,b.c,this.Tb);else return a};Parser.prototype.Tb=function(){for(var a=this.Wb(),b;;)if(b=this.a("&&"))a=this.G(a,b.c,this.Wb);else return a};Parser.prototype.Wb=function(){var a;return(a=this.a("!"))?this.Ac(a.c,this.Ab):this.Ab()};Parser.prototype.Ab=function(){for(var a=this.ec(),b;;)if(b=this.a("==","!="))a=this.G(a,b.c,this.ec);else return a};Parser.prototype.ec=function(){for(var a= +this.pb(),b;;)if(b=this.a("<",">","<=",">="))a=this.G(a,b.c,this.pb);else return a};Parser.prototype.pb=function(){for(var a=this.Ya(),b;b=this.a("+","-");)a=this.G(a,b.c,this.Ya);return a};Parser.prototype.Ya=function(){for(var a=this.kc(),b;b=this.a("*","/","%");)a=this.G(a,b.c,this.kc);return a};Parser.prototype.kc=function(){var a;return this.a("+")?this.Ga():(a=this.a("-"))?this.G(Parser.zc,a.c,this.Ya):this.Ga()};Parser.prototype.kd=function(a){var b=this.a(),c=b.text.split(".");a=a;for(var d, +e=0;e<c.length;e++){d=c[e];if(a)a=a[d]}if(typeof a!="function")throw"Function '"+b.text+"' at column '"+(b.index+1)+"' in '"+this.text+"' is not defined.";return a};Parser.prototype.Ga=function(){var a;if(this.a("(")){a=this.Cb();this.p(")");a=a}else if(this.a("["))a=this.Ic();else if(this.a("{"))a=this.object();else if(this.a("{:"))a=this.sb(false);else if(this.a("{("))a=this.sb(true);else{var b=this.a();(a=b.c)||this.error("not a primary expression",b)}for(;b=this.a("(","[",".");)if(b.text==="(")a= +this.jd(a);else if(b.text==="[")a=this.Md(a);else if(b.text===".")a=this.ed(a);else throw"IMPOSSIBLE";return a};Parser.prototype.sb=function(a){var b=[];if(a){if(!this.a(")")){for(b.push(this.a().text);this.a(",");)b.push(this.a().text);this.p(")")}this.p(":")}var c=this.db();this.p("}");return function(d){return function(e){var g=new Scope(d.scope.F);g.s("$",e);for(var i=0;i<b.length;i++)g.s(b[i],arguments[i]);return c({scope:g})}}};Parser.prototype.ed=function(a){var b=this.a().text;function c(d){return Scope.fa(a(d), +b)}c.za=b;return c};Parser.prototype.Md=function(a){var b=this.C();this.p("]");if(this.a("=")){var c=this.C();return function(d){return a(d)[b(d)]=c(d)}}else return function(d){var e=a(d);d=b(d);return e?e[d]:undefined}};Parser.prototype.jd=function(a){var b=[];if(this.Fa().text!=")"){do b.push(this.C());while(this.a(","))}this.p(")");return function(c){for(var d=[],e=0;e<b.length;e++)d.push(b[e](c));e=a(c);if(typeof e==="function")return e.apply(c,d);else throw"Expression '"+a.za+"' is not a function."; +}};Parser.prototype.Ic=function(){var a=[];if(this.Fa().text!="]"){do a.push(this.C());while(this.a(","))}this.p("]");return function(b){for(var c=[],d=0;d<a.length;d++)c.push(a[d](b));return c}};Parser.prototype.object=function(){var a=[];if(this.Fa().text!="}"){do{var b=this.a().text;this.p(":");var c=this.C();a.push({ud:b,value:c})}while(this.a(","))}this.p("}");return function(d){for(var e={},g=0;g<a.length;g++){var i=a[g],l=i.value(d);e[i.ud]=l}return e}};Parser.prototype.cd=function(){for(var a= +[];this.Hb();){a.push(this.bd());this.a(";")||this.aa()}return function(b){for(var c="",d=0;d<a.length;d++)c+=a[d](b);return c}};Parser.prototype.bd=function(){var a=this.a().text,b,c;if(this.a("=")){b=a;a=this.a().text}if(this.a(":"))c=this.Ga()(null);return function(d){var e=d.scope.h("$datastore").da(a,c);d.scope.s(a,e);if(b){e=e();e.jb=b;d.scope.s(b,e);return"$anchor."+b+":{"+b+"="+a+".load($anchor."+b+");"+b+".$$anchor="+angular.O.quote(b)+";};"}else return""}};Parser.prototype.watch=function(){for(var a= +[];this.Hb();){a.push(this.le());this.a(";")||this.aa()}this.aa();return function(b){for(var c=0;c<a.length;c++){var d=a[c](b);b.Dc(d.name,d.c)}}};Parser.prototype.le=function(){var a=this.a().text;this.p(":");var b;if(this.Fa().text=="{"){this.p("{");b=this.db();this.p("}")}else b=this.C();return function(){return{name:a,c:b}}};Scope=function(a,b){this.oc=[];this.hb={};this.name=b;a=a||{};function c(){}c.prototype=a;this.F=new c;this.F.ve=a;if(b=="ROOT")this.F.we=this.F};Scope.xa={};Scope.prototype.d= +function(){var a=this;this.fd();_.b(this.oc,function(b){a.u(b,"",{},function(){this.d(a)})})};Scope.prototype.Fc=function(a){a&&this.oc.push(a)};Scope.prototype.qd=function(a){for(var b=0;b<a.length;b++){var c=a.charAt(b);if(c!="."&&!Lexer.prototype.Aa(c))return false}return true};Scope.fa=function(a,b){if(!b)return a;for(var c=b.split("."),d,e=a,g=c.length,i=0;i<g;i++){d=c[i];if(!d.match(/^[\$\w][\$\w\d]*$/))throw"Expression '"+b+"' is not a valid expression for accesing variables.";if(a){e=a;a= +a[d]}if(_.H(a)&&d.charAt(0)=="$"){var l=angular.Y.de(e);if(d=(l=angular[l.charAt(0).toUpperCase()+l.substring(1)])?l[[d.substring(1)]]:undefined)return a=_.B(d,e,e)}}if(typeof a==="function"&&!a.qc)return bind(e,a);return a};Scope.prototype.h=function(a){return Scope.fa(this.F,a)};Scope.prototype.s=function(a,b){a=a.split(".");for(var c=this.F,d=0;a.length>1;d++){var e=a.shift(),g=c[e];if(!g){g={};c[e]=g}c=g}return c[a.shift()]=b};Scope.prototype.z=function(a,b){this.eval(a+"="+toJson(b))};Scope.prototype.eval= +function(a,b){var c=Scope.xa[a];if(!c){var d=new Parser(a);c=d.db();d.aa();Scope.xa[a]=c}b=b||{};b.scope=this;return c(b)};Scope.prototype.u=function(a,b,c,d,e){try{var g=this.eval(b,c);if(a.J){a.J=false;jQuery(a.view).gc("ng-exception").fc("ng-error")}d&&d.apply(a,[g]);return true}catch(i){console.error("Eval Widget Error:",i);b=toJson(i,true);a.J=true;jQuery(a.view).Oa("ng-exception").g("ng-error",b);e&&e.apply(a,[i,b]);return false}};Scope.prototype.je=function(a,b){var c=Scope.xa[a];if(!c){c= +(new Parser(a)).j();Scope.xa[a]=c}a={scope:this};return c(a)(a,b)};Scope.prototype.da=function(a){return(new Parser(a)).cd()({scope:this})};Scope.prototype.zd=function(a){this.F.ue.push(a)};Scope.prototype.watch=function(a){var b=this;(new Parser(a)).watch()({scope:this,Dc:function(c,d){b.Ec(c,function(e,g){try{return d({scope:b},e,g)}catch(i){alert(i)}})}})};Scope.prototype.Ec=function(a,b){var c=this.hb[a];if(!c){c={Pb:[],C:a};this.hb[a]=c}c.Pb.push(b)};Scope.prototype.fd=function(){var a=this, +b=false;jQuery.b(this.hb,function(c,d){var e=a.eval(d.C);if(e!==d.e){jQuery.b(d.Pb,function(g,i){i(e,d.e);b=true});d.e=e}});return b};Server=function(a,b){this.url=a;this.Bd=0;this.Fb=b;this.ie="_"+(""+Math.random()).substr(2)+"_";this.Xa=1800};Server.prototype.Kc=function(a){return w.wa(a)};Server.prototype.la=function(a,b,c,d){var e=this.ie+this.Bd++;nglr[e]=function(l){delete nglr[e];d(200,l)};a={Yf:b,yf:a,If:c};a=this.Kc(toJson(a));b=Math.ceil(a.length/this.Xa);c=this.url+"/$/"+e+"/"+b+"/";for(var g= +0;g<b;g++){var i=a.substr(g*this.Xa,this.Xa);this.Fb(c+(g+1)+"?h="+i,noop)}};FrameServer=y("frame");FrameServer.Be="$DATASET:";FrameServer.prototype={la:x()};VisualServer=function(a,b,c){this.Zc=a;this.update=c;this.status=b};VisualServer.prototype={la:function(a,b,c,d){var e=this;this.status.Lc(c);this.Zc.la(a,b,c,function(){e.status.ad();try{d.apply(this,arguments)}catch(g){alert(toJson(g))}e.update()})}};Users=function(a,b){this.M=a;this.Qa=b};Users.prototype={Bb:function(a){var b=this;this.M.la("GET", +"/account.json",{},function(c,d){b.Uc=d.he;a(d.he)})},Vb:function(a){var b=this;this.Qa.Vb(function(){delete b.Uc;(a||noop)()})},Ca:function(a){var b=this;this.Qa.Ca(function(){b.Bb(function(){(a||noop)()})})},Za:function(){this.Qa.Za()}};angular.j.ka=function(a,b,c){return a.match(b)?null:c||"Value does not match expected format "+b+"."};angular.j.$a=function(a,b,c){var d=1*a;if(d==a){if(typeof b!="undefined"&&d<b)return"Value can not be less than "+b+".";if(typeof b!="undefined"&&d>c)return"Value can not be greater than "+ +c+".";return null}else return"Value is not a number."};angular.j.pf=function(a,b,c){b=angular.j.$a(a,b,c);if(b===null&&a!=Math.round(a))return"Value is not a whole number.";return b};angular.j.Vc=function(a){if(a.match(/^\d\d?\/\d\d?\/\d\d\d\d$/))return null;return"Value is not a date. (Expecting format: 12/31/2009)."};angular.j.Uf=function(a){if(a.match(/^\d\d\d-\d\d-\d\d\d\d$/))return null;return"SSN needs to be in 999-99-9999 format."};angular.j.$c=function(a){if(a.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/))return null; +return"Email needs to be in username@host.com format."};angular.j.Jf=function(a){if(a.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/))return null;if(a.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/))return null;return"Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly."};angular.j.url=function(a){if(a.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/))return null;return"URL needs to be in http://server[:port]/path format."}; +angular.j.td=function(a){try{fromJson(a);return null}catch(b){return b.toString()}};WidgetFactory=function(a,b){this.Cd=0;this.Ia=a;this.T=b;this.ub=swfobject.ub;this.Nd=x()};WidgetFactory.prototype.Sc=function(a,b){var c,d=a.g("type").toLowerCase(),e=a.g("name");if(e)e=e.split(":").pop();var g="change",i=true;if(d=="button"||d=="submit"||d=="reset"||d=="image"){c=new ButtonController(a[0],e);g="click";i=false}else if(d=="text"||d=="textarea"||d=="hidden"||d=="password"){c=new TextController(a[0], +e);g="keyup change"}else if(d=="checkbox"){c=new CheckboxController(a[0],e);g="click"}else if(d=="radio"){c=new RadioController(a[0],e);g="click"}else if(d=="select-one")c=new SelectController(a[0],e);else if(d=="select-multiple")c=new MultiSelectController(a[0],e);else if(d=="file")c=this.Tc(a,e);else throw"Unknown type: "+d;a.data("controller",c);var l=b.h("$binder");jQuery(c.view,":input").B(g,function(){if(c.i(b)){var n=jQuery(c.view).g("ng-action")||"";b.u(c,n)&&l.d(b)}return i});return c};WidgetFactory.prototype.Tc= +function(a){var b="__uploadWidget_"+this.Cd++,c=FileController.V(b);a.Gc(c);b=this.ub({data:this.Ia+"/admin/ServerAPI.swf",width:"95",height:"20",align:"top",eg:"transparent"},{jf:"uploadWidgetId="+b,De:"always"},b);a.remove();a=new FileController(c,a[0].name,b,this.Ia+"/data/"+this.T);jQuery(b).data("controller",a);return a};FileController=function(a,b,c,d){this.view=a;this.bg=c;this.hc=b;this.Ge=d+"/_attachments";this.value=null;this.e=undefined};FileController.dispatchEvent=function(a,b,c){a=v.getElementById(a); +a=jQuery(a).data("controller");FileController.prototype["_on_"+b].apply(a,c)};FileController.V=function(a){return jQuery('<span class="ng-upload-widget"><input type="checkbox" ng-non-bindable="true"/><object id="'+a+'" /><a></a><span/></span>')};FileController.prototype.i=function(a){var b=this.view.find("input").g("checked")?this.value:null;if(this.e===b)return false;else{a.s(this.hc,b);return true}};FileController.prototype.d=function(a){if((a=a.h(this.hc))&&this.value!==a){this.value=a;this.view.find("a").g("href", +this.value.url).text(this.value.text);this.view.find("span").text(angular.filter.Pa(this.value.size))}this.view.find("input").g("checked",!!a)};NullController=y("view");NullController.prototype.i=z(true);NullController.prototype.d=x();NullController.nd=new NullController;ButtonController=y("view");ButtonController.prototype.i=z(true);ButtonController.prototype.d=x();TextController=function(a,b){this.view=a;this.exp=b;this.j=a.getAttribute("ng-validate");this.Vd=typeof a.attributes["ng-required"]!= +"undefined";this.Nb=null;this.e=undefined;this.D=a.value;a.getAttribute("ng-widget")==="datepicker"&&jQuery(a).df()};TextController.prototype.i=function(a){var b=this.view.value;if(this.e===b)return false;else{a.z(this.exp,b);this.e=b;return true}};TextController.prototype.d=function(a){var b=this.view,c=a.h(this.exp);if(typeof c==="undefined"){c=this.D;a.z(this.exp,c)}c=c?c:"";if(this.e!=c)this.e=b.value=c;var d=false;b.removeAttribute("ng-error");if(this.Vd)d=!(c&&c.length>0);var e=d?"Required Value": +null;if(!d&&this.j&&c){e=a.je(this.j,c);d=!!e}if(this.Nb!==e){this.Nb=d;if(e!==null){b.setAttribute("ng-error",e);a.zd(this)}jQuery(b).eb("ng-validation-error",d)}};CheckboxController=function(a,b){this.view=a;this.exp=b;this.e=undefined;this.D=a.checked?a.value:""};CheckboxController.prototype.i=function(a){var b=this.view;b=b.checked?b.value:"";if(this.e===b)return false;else{a.z(this.exp,b);this.e=b;return true}};CheckboxController.prototype.d=function(a){var b=this.view,c=a.eval(this.exp);if(typeof c=== +"undefined"){c=this.D;a.z(this.exp,c)}b.checked=b.value==""+c};SelectController=function(a,b){this.view=a;this.exp=b;this.e=undefined;this.D=a.value};SelectController.prototype.i=function(a){if(this.view.selectedIndex<0)a.z(this.exp,null);else{var b=this.view.value;if(this.e===b)return false;else{a.z(this.exp,b);this.e=b;return true}}};SelectController.prototype.d=function(a){var b=this.view,c=a.h(this.exp);if(typeof c==="undefined"){c=this.D;a.z(this.exp,c)}if(c!==this.e){b.value=c?c:"";this.e=c}}; +MultiSelectController=function(a,b){this.view=a;this.exp=b;this.e=undefined;this.D=this.selected()};MultiSelectController.prototype.selected=function(){for(var a=[],b=this.view.options,c=0;c<b.length;c++){var d=b[c];d.selected&&a.push(d.value)}return a};MultiSelectController.prototype.i=function(a){var b=this.selected();if(this.e===b)return false;else{a.z(this.exp,b);this.e=b;return true}};MultiSelectController.prototype.d=function(a){var b=this.view,c=a.h(this.exp);if(typeof c==="undefined"){c=this.D; +a.z(this.exp,c)}if(c!==this.e){a=b.options;for(b=0;b<a.length;b++){var d=a[b];d.selected=_.ya(c,d.value)}this.e=c}};RadioController=function(a,b){this.view=a;this.exp=b;this.e=this.Va=undefined;this.Kb=a.value;this.D=a.checked?a.value:null};RadioController.prototype.i=function(a){var b=this.view;if(this.Va)return false;else{b.checked=true;this.e=a.z(this.exp,this.Kb);return this.Va=true}};RadioController.prototype.d=function(a){var b=this.view,c=a.h(this.exp);if(this.D&&typeof c==="undefined"){c= +this.D;a.z(this.exp,c)}if(this.e!=c){this.Va=b.checked=this.Kb==""+c;this.e=c}};BindUpdater=function(a,b){this.view=a;this.exp=Binder.Ea(b);this.J=false;this.Xd={element:a}};BindUpdater.ic=function(a){var b=escapeHtml;switch(typeof a){case "string":case "boolean":case "number":return b(a);case "function":return BindUpdater.ic(a());case "object":if(isNode(a))return outerHTML(a);else if(a instanceof angular.filter.m){switch(typeof a.w){case "string":case "number":return a.w;case "function":return a.w(); +case "object":if(isNode(a.w))return outerHTML(a.w);default:break}switch(typeof a.text){case "string":case "number":return b(a.text);case "function":return b(a.text());default:break}}if(a===null)return"";return b(toJson(a,true));default:return""}};BindUpdater.prototype.i=x();BindUpdater.prototype.d=function(a){for(var b=[],c=this.exp,d=c.length,e=0;e<d;e++){var g=c[e],i=Binder.ba(g);if(i){a.u(this,i,this.Xd,function(l){b.push(BindUpdater.ic(l))},function(l,n){setHtml(this.view,n)});if(this.J)return}else b.push(escapeHtml(g))}setHtml(this.view, +b.join(""))};BindAttrUpdater=function(a,b){this.view=a;this.Jc=b};BindAttrUpdater.prototype.i=x();BindAttrUpdater.prototype.d=function(a){var b=jQuery(this.view),c=this.Jc;if(this.J){this.J=false;b.gc("ng-exception").fc("ng-error")}var d=b.od("img");for(var e in c){for(var g=Binder.Ea(c[e]),i=[],l=0;l<g.length;l++){var n=Binder.ba(g[l]);if(n)try{var o=a.eval(n,{element:b[0],attrName:e});if(o&&(o.constructor!==array||o.length!==0))i.push(o)}catch(p){this.J=true;console.error("BindAttrUpdater",p);n= +toJson(p,true);i.push("["+n+"]");b.Oa("ng-exception").g("ng-error",n)}else i.push(g[l])}g=i.length?i.join(""):null;if(d&&e=="src"&&!g)g=a.h("config.server")+"/images/blank.gif";b.g(e,g)}};EvalUpdater=function(a,b){this.view=a;this.exp=b;this.J=false};EvalUpdater.prototype.i=x();EvalUpdater.prototype.d=function(a){a.u(this,this.exp)};HideUpdater=function(a,b){this.view=a;this.exp=b};HideUpdater.prototype.i=x();HideUpdater.prototype.d=function(a){a.u(this,this.exp,{},function(b){var c=jQuery(this.view); +toBoolean(b)?c.Jb():c.cb()})};ShowUpdater=function(a,b){this.view=a;this.exp=b};ShowUpdater.prototype.i=x();ShowUpdater.prototype.d=function(a){a.u(this,this.exp,{},function(b){var c=jQuery(this.view);toBoolean(b)?c.cb():c.Jb()})};ClassUpdater=function(a,b){this.view=a;this.exp=b};ClassUpdater.prototype.i=x();ClassUpdater.prototype.d=function(a){a.u(this,this.exp,{},function(b){if(b!==null&&b!==undefined)this.view.className=b})};ClassEvenUpdater=function(a,b){this.view=a;this.exp=b};ClassEvenUpdater.prototype.i= +x();ClassEvenUpdater.prototype.d=function(a){a.u(this,this.exp,{},function(b){var c=a.h("$index");jQuery(this.view).eb(b,c%2===1)})};ClassOddUpdater=function(a,b){this.view=a;this.exp=b};ClassOddUpdater.prototype.i=x();ClassOddUpdater.prototype.d=function(a){a.u(this,this.exp,{},function(b){var c=a.h("$index");jQuery(this.view).eb(b,c%2===0)})};StyleUpdater=function(a,b){this.view=a;this.exp=b};StyleUpdater.prototype.i=x();StyleUpdater.prototype.d=function(a){a.u(this,this.exp,{},function(b){jQuery(this.view).g("style", +"").Sa(b)})};RepeaterUpdater=function(a,b,c,d){this.view=a;this.V=c;this.prefix=d;this.ta=[];a=b.match(/^\s*(.+)\s+in\s+(.*)\s*$/);if(!a)throw"Expected ng-repeat in form of 'item in collection' but got '"+b+"'.";b=a[1];this.Ba=a[2];a=b.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);if(!a)throw"'item' in 'item in collection' should be identifier or (key, value) but get '"+b+"'.";this.ke=a[3]||a[1];this.vd=a[2]};RepeaterUpdater.prototype.i=x();RepeaterUpdater.prototype.d=function(a){a.u(this,this.Ba, +{},function(b){var c=this;if(!b){b=[];a.qd(this.Ba)&&a.s(this.Ba,b)}var d=b.length,e=this.ta.length,g=this.view,i=0,l=null,n=this.vd,o=this.ke,p=0;jQuery.b(b,function(r,f){if(p<e){l=c.ta[p];l.scope.s(o,f)}else{var h=new Scope(a.F,c.prefix+o+" in "+c.Ba+"["+p+"]");h.s("$index",p);n&&h.s(n,r);h.s(o,f);l={scope:h,element:c.V(h,c.prefix,p)};g.Gc(l.element);c.ta.push(l)}g=l.element;r=(new Date).getTime();l.scope.d();i+=(new Date).getTime()-r;p++});for(b=e;b>d;--b)this.ta.pop().element.removeNode();if(l&& +l.element[0].nodeName==="OPTION")if(d=jQuery(l.element[0].parentNode).data("controller")){d.e=undefined;d.d(a)}})};PopUp=y("Q");PopUp.nb="mouseleave mouseout click dblclick keypress keyup";PopUp.prototype.B=function(){this.Q.find(".ng-validation-error,.ng-exception").xd("mouseover",PopUp.Od)};PopUp.Od=function(){PopUp.ab();var a=jQuery(this);a.B(PopUp.nb,PopUp.ab);var b=a.position(),c=v.documentElement,d=(self.innerWidth||c&&c.clientWidth||v.body.clientWidth)-b.left;c=a.mf("ng-exception")?"EXCEPTION:": +"Validation error...";a=a.g("ng-error");d=d>375?"left":"right";c=jQuery("<div id='ng-callout' style='width:300px'><div class='ng-arrow-"+d+"'/><div class='ng-title'>"+c+"</div><div class='ng-content'>"+a+"</div></div>");jQuery("body").append(c);if(d==="left")a=b.left+this.offsetWidth+11;else{a=b.left-315;c.find(".ng-arrow-right").Sa({left:301})}c.Sa({left:a+"px",top:b.top-3+"px"});return true};PopUp.ab=function(){jQuery("#ng-callout").Zf(PopUp.nb,PopUp.ab).remove();return true};Status=function(a){this.Sb= +a.append(Status.sc).find("#ng-loading");this.Ha=0};Status.sc='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>';Status.prototype.Lc=function(){this.Ha===0&&this.Sb.cb();this.Ha++};Status.prototype.ad=function(){this.Ha--;this.Ha===0&&this.Sb.Jb("fold")}})(window,document); @@ -1,164 +1,4568 @@ -var a,Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=",encode:function(b){var c="",d,f,e,h,j,l,n=0;for(b=Base64._utf8_encode(b);n<b.length;){d=b.charCodeAt(n++);f=b.charCodeAt(n++);e=b.charCodeAt(n++);h=d>>2;d=(d&3)<<4|f>>4;j=(f&15)<<2|e>>6;l=e&63;if(isNaN(f))j=l=64;else if(isNaN(e))l=64;c=c+this._keyStr.charAt(h)+this._keyStr.charAt(d)+this._keyStr.charAt(j)+this._keyStr.charAt(l)}return c},decode:function(b){var c="",d,f,e,h,j,l=0;for(b=b.replace(/[^A-Za-z0-9\+\/\=]/g, -"");l<b.length;){d=this._keyStr.indexOf(b.charAt(l++));f=this._keyStr.indexOf(b.charAt(l++));h=this._keyStr.indexOf(b.charAt(l++));j=this._keyStr.indexOf(b.charAt(l++));d=d<<2|f>>4;f=(f&15)<<4|h>>2;e=(h&3)<<6|j;c+=String.fromCharCode(d);if(h!=64)c+=String.fromCharCode(f);if(j!=64)c+=String.fromCharCode(e)}return c=Base64._utf8_decode(c)},_utf8_encode:function(b){b=b.replace(/\r\n/g,"\n");for(var c="",d=0;d<b.length;d++){var f=b.charCodeAt(d);if(f<128)c+=String.fromCharCode(f);else{if(f>127&&f<2048)c+= -String.fromCharCode(f>>6|192);else{c+=String.fromCharCode(f>>12|224);c+=String.fromCharCode(f>>6&63|128)}c+=String.fromCharCode(f&63|128)}}return c},_utf8_decode:function(b){for(var c="",d=0,f=c1=c2=0;d<b.length;){f=b.charCodeAt(d);if(f<128){c+=String.fromCharCode(f);d++}else if(f>191&&f<224){c2=b.charCodeAt(d+1);c+=String.fromCharCode((f&31)<<6|c2&63);d+=2}else{c2=b.charCodeAt(d+1);c3=b.charCodeAt(d+2);c+=String.fromCharCode((f&15)<<12|(c2&63)<<6|c3&63);d+=3}}return c}};(function(){var b=this,c=b._,d=function(g){this._wrapped=g},f=typeof StopIteration!=="undefined"?StopIteration:"__break__",e=b._=function(g){return new d(g)};if(typeof exports!=="undefined")exports._=e;var h=Array.prototype.slice,j=Array.prototype.unshift,l=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;e.VERSION="0.5.1";e.each=function(g,i,k){try{if(g.forEach)g.forEach(i,k);else if(e.isArray(g)||e.isArguments(g))for(var m=0,q=g.length;m<q;m++)i.call(k, -g[m],m,g);else{var r=e.keys(g);q=r.length;for(m=0;m<q;m++)i.call(k,g[r[m]],r[m],g)}}catch(t){if(t!=f)throw t;}return g};e.map=function(g,i,k){if(g&&e.isFunction(g.map))return g.map(i,k);var m=[];e.each(g,function(q,r,t){m.push(i.call(k,q,r,t))});return m};e.reduce=function(g,i,k,m){if(g&&e.isFunction(g.reduce))return g.reduce(e.bind(k,m),i);e.each(g,function(q,r,t){i=k.call(m,i,q,r,t)});return i};e.reduceRight=function(g,i,k,m){if(g&&e.isFunction(g.reduceRight))return g.reduceRight(e.bind(k,m),i); -var q=e.clone(e.toArray(g)).reverse();e.each(q,function(r,t){i=k.call(m,i,r,t,g)});return i};e.detect=function(g,i,k){var m;e.each(g,function(q,r,t){if(i.call(k,q,r,t)){m=q;e.breakLoop()}});return m};e.select=function(g,i,k){if(g&&e.isFunction(g.filter))return g.filter(i,k);var m=[];e.each(g,function(q,r,t){i.call(k,q,r,t)&&m.push(q)});return m};e.reject=function(g,i,k){var m=[];e.each(g,function(q,r,t){!i.call(k,q,r,t)&&m.push(q)});return m};e.all=function(g,i,k){i=i||e.identity;if(g&&e.isFunction(g.every))return g.every(i, -k);var m=true;e.each(g,function(q,r,t){(m=m&&i.call(k,q,r,t))||e.breakLoop()});return m};e.any=function(g,i,k){i=i||e.identity;if(g&&e.isFunction(g.some))return g.some(i,k);var m=false;e.each(g,function(q,r,t){if(m=i.call(k,q,r,t))e.breakLoop()});return m};e.include=function(g,i){if(e.isArray(g))return e.indexOf(g,i)!=-1;var k=false;e.each(g,function(m){if(k=m===i)e.breakLoop()});return k};e.invoke=function(g,i){var k=e.rest(arguments,2);return e.map(g,function(m){return(i?m[i]:m).apply(m,k)})};e.pluck= -function(g,i){return e.map(g,function(k){return k[i]})};e.max=function(g,i,k){if(!i&&e.isArray(g))return Math.max.apply(Math,g);var m={computed:-Infinity};e.each(g,function(q,r,t){r=i?i.call(k,q,r,t):q;r>=m.computed&&(m={value:q,computed:r})});return m.value};e.min=function(g,i,k){if(!i&&e.isArray(g))return Math.min.apply(Math,g);var m={computed:Infinity};e.each(g,function(q,r,t){r=i?i.call(k,q,r,t):q;r<m.computed&&(m={value:q,computed:r})});return m.value};e.sortBy=function(g,i,k){return e.pluck(e.map(g, -function(m,q,r){return{value:m,criteria:i.call(k,m,q,r)}}).sort(function(m,q){m=m.criteria;q=q.criteria;return m<q?-1:m>q?1:0}),"value")};e.sortedIndex=function(g,i,k){k=k||e.identity;for(var m=0,q=g.length;m<q;){var r=m+q>>1;k(g[r])<k(i)?(m=r+1):(q=r)}return m};e.toArray=function(g){if(!g)return[];if(g.toArray)return g.toArray();if(e.isArray(g))return g;if(e.isArguments(g))return h.call(g);return e.map(g,function(i){return i})};e.size=function(g){return e.toArray(g).length};e.first=function(g,i, -k){return i&&!k?h.call(g,0,i):g[0]};e.rest=function(g,i,k){return h.call(g,e.isUndefined(i)||k?1:i)};e.last=function(g){return g[g.length-1]};e.compact=function(g){return e.select(g,function(i){return!!i})};e.flatten=function(g){return e.reduce(g,[],function(i,k){if(e.isArray(k))return i.concat(e.flatten(k));i.push(k);return i})};e.without=function(g){var i=e.rest(arguments);return e.select(g,function(k){return!e.include(i,k)})};e.uniq=function(g,i){return e.reduce(g,[],function(k,m,q){if(0==q||(i=== -true?e.last(k)!=m:!e.include(k,m)))k.push(m);return k})};e.intersect=function(g){var i=e.rest(arguments);return e.select(e.uniq(g),function(k){return e.all(i,function(m){return e.indexOf(m,k)>=0})})};e.zip=function(){for(var g=e.toArray(arguments),i=e.max(e.pluck(g,"length")),k=new Array(i),m=0;m<i;m++)k[m]=e.pluck(g,String(m));return k};e.indexOf=function(g,i){if(g.indexOf)return g.indexOf(i);for(var k=0,m=g.length;k<m;k++)if(g[k]===i)return k;return-1};e.lastIndexOf=function(g,i){if(g.lastIndexOf)return g.lastIndexOf(i); -for(var k=g.length;k--;)if(g[k]===i)return k;return-1};e.range=function(g,i,k){var m=e.toArray(arguments),q=m.length<=1;g=q?0:m[0];i=q?m[0]:m[1];k=m[2]||1;m=Math.ceil((i-g)/k);if(m<=0)return[];m=new Array(m);q=g;for(var r=0;;q+=k){if((k>0?q-i:i-q)>=0)return m;m[r++]=q}};e.bind=function(g,i){var k=e.rest(arguments,2);return function(){return g.apply(i||b,k.concat(e.toArray(arguments)))}};e.bindAll=function(g){var i=e.rest(arguments);if(i.length==0)i=e.functions(g);e.each(i,function(k){g[k]=e.bind(g[k], -g)});return g};e.delay=function(g,i){var k=e.rest(arguments,2);return setTimeout(function(){return g.apply(g,k)},i)};e.defer=function(g){return e.delay.apply(e,[g,1].concat(e.rest(arguments)))};e.wrap=function(g,i){return function(){var k=[g].concat(e.toArray(arguments));return i.apply(i,k)}};e.compose=function(){var g=e.toArray(arguments);return function(){for(var i=e.toArray(arguments),k=g.length-1;k>=0;k--)i=[g[k].apply(this,i)];return i[0]}};e.keys=function(g){if(e.isArray(g))return e.range(0, -g.length);var i=[];for(var k in g)n.call(g,k)&&i.push(k);return i};e.values=function(g){return e.map(g,e.identity)};e.functions=function(g){return e.select(e.keys(g),function(i){return e.isFunction(g[i])}).sort()};e.extend=function(g,i){for(var k in i)g[k]=i[k];return g};e.clone=function(g){if(e.isArray(g))return g.slice(0);return e.extend({},g)};e.isEqual=function(g,i){if(g===i)return true;var k=typeof g;if(k!=typeof i)return false;if(g==i)return true;if(!g&&i||g&&!i)return false;if(g.isEqual)return g.isEqual(i); -if(e.isDate(g)&&e.isDate(i))return g.getTime()===i.getTime();if(e.isNaN(g)&&e.isNaN(i))return true;if(e.isRegExp(g)&&e.isRegExp(i))return g.source===i.source&&g.global===i.global&&g.ignoreCase===i.ignoreCase&&g.multiline===i.multiline;if(k!=="object")return false;if(g.length&&g.length!==i.length)return false;k=e.keys(g);var m=e.keys(i);if(k.length!=m.length)return false;for(var q in g)if(!e.isEqual(g[q],i[q]))return false;return true};e.isEmpty=function(g){return e.keys(g).length==0};e.isElement= -function(g){return!!(g&&g.nodeType==1)};e.isArguments=function(g){return g&&e.isNumber(g.length)&&!e.isArray(g)&&!o.call(g,"length")};e.isNaN=function(g){return e.isNumber(g)&&isNaN(g)};e.isNull=function(g){return g===null};e.isUndefined=function(g){return typeof g=="undefined"};for(var p=["Array","Date","Function","Number","RegExp","String"],s=0,v=p.length;s<v;s++)(function(){var g="[object "+p[s]+"]";e["is"+p[s]]=function(i){return l.call(i)==g}})();e.noConflict=function(){b._=c;return this};e.identity= -function(g){return g};e.breakLoop=function(){throw f;};var u=0;e.uniqueId=function(g){var i=u++;return g?g+i:i};e.template=function(g,i){g=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+g.replace(/[\r\t\n]/g," ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return i?g(i):g};e.forEach=e.each;e.foldl=e.inject= -e.reduce;e.foldr=e.reduceRight;e.filter=e.select;e.every=e.all;e.some=e.any;e.head=e.first;e.tail=e.rest;e.methods=e.functions;var w=function(g,i){return i?e(g).chain():g};e.each(e.functions(e),function(g){var i=e[g];d.prototype[g]=function(){j.call(arguments,this._wrapped);return w(i.apply(e,arguments),this._chain)}});e.each(["pop","push","reverse","shift","sort","splice","unshift"],function(g){var i=Array.prototype[g];d.prototype[g]=function(){i.apply(this._wrapped,arguments);return w(this._wrapped, -this._chain)}});e.each(["concat","join","slice"],function(g){var i=Array.prototype[g];d.prototype[g]=function(){return w(i.apply(this._wrapped,arguments),this._chain)}});d.prototype.chain=function(){this._chain=true;return this};d.prototype.value=function(){return this._wrapped}})();if(typeof document.getAttribute=="undefined")document.getAttribute=function(){};if(typeof Node=="undefined")Node={ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12};if(_.isUndefined(window.nglr))nglr={};if(_.isUndefined(window.angular))angular={};if(_.isUndefined(angular.validator))angular.validator={}; -if(_.isUndefined(angular.filter))angular.filter={};if(_.isUndefined(window.console))window.console={log:function(){},error:function(){}};if(_.isUndefined(nglr.alert))nglr.alert=function(){console.log(arguments);window.alert.apply(window,arguments)};nglr.consoleLog=function(b,c){var d=document.createElement("div");d.className=b;for(var f=b="",e=0;e<c.length;e++){var h=c[e];b+=f+(typeof h=="string"?h:nglr.toJson(h));f=" "}d.appendChild(document.createTextNode(b));nglr.consoleNode.appendChild(d)}; -nglr.isNode=function(b){return b&&b.tagName&&b.nodeName&&b.ownerDocument&&b.removeAttribute};nglr.isLeafNode=function(b){switch(b.nodeName){case "OPTION":case "PRE":case "TITLE":return true;default:return false}};nglr.noop=function(){};nglr.setHtml=function(b,c){if(nglr.isLeafNode(b))if(nglr.msie)b.innerText=c;else b.textContent=c;else b.innerHTML=c};nglr.escapeHtml=function(b){if(!b||!b.replace)return b;return b.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}; -nglr.escapeAttr=function(b){if(!b||!b.replace)return b;return b.replace(/</g,"<").replace(/>/g,">").replace(/\"/g,""")};nglr.bind=function(b,c){if(!b)throw"Missing this";if(!_.isFunction(c))throw"Missing function";return function(){return c.apply(b,arguments)}};nglr.shiftBind=function(b,c){return function(){for(var d=[this],f=0;f<arguments.length;f++)d.push(arguments[f]);return c.apply(b,d)}}; -nglr.outerHTML=function(b){var c=document.createElement("div");c.appendChild(b);var d=c.innerHTML;c.removeChild(b);return d};nglr.trim=function(b){return b.replace(/^ */,"").replace(/ *$/,"")};nglr.toBoolean=function(b){var c=(""+b).toLowerCase();if(c=="f"||c=="0"||c=="false"||c=="no")b=false;return!!b}; -nglr.merge=function(b,c){for(var d in b){var f=c[d],e=typeof f;if(e=="undefined")c[d]=nglr.fromJson(nglr.toJson(b[d]));else e=="object"&&f.constructor!=nglr.array&&d.substring(0,1)!="$"&&nglr.merge(b[d],f)}};nglr.Loader=function(b,c,d){this.document=jQuery(b);this.head=jQuery(c);this.config=d;this.location=window.location};a=nglr.Loader.prototype; -a.load=function(){this.configureLogging();this.loadCss("/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css");this.loadCss("/stylesheets/nglr.css");console.log("Server: "+this.config.server);nglr.msie=jQuery.browser.msie;this.configureJQueryPlugins();this.computeConfiguration();this.bindHtml()}; -a.configureJQueryPlugins=function(){console.log("Loader.configureJQueryPlugins()");jQuery.fn.removeNode=function(){var b=this.get(0);b.parentNode.removeChild(b)};jQuery.fn.scope=function(){for(var b=this;b&&b.get(0);){var c=b.data("scope");if(c)return c;b=b.parent()}return null};jQuery.fn.controller=function(){return this.data("controller")||nglr.NullController.instance}};a.uid=function(){return""+(new Date).getTime()}; -a.computeConfiguration=function(){var b=this.config;if(!b.database){var c=b.server.match(/https?:\/\/([\w]*)/);b.database=c?c[1]:"$MEMORY"}}; -a.bindHtml=function(){function b(){j.fetchCurrentUser(function(p){!p&&d.find("[ng-auth=eager]").length&&j.login()})}console.log("Loader.bindHtml()");var c=new nglr.UrlWatcher(this.location),d=this.document,f=new nglr.WidgetFactory(this.config.server,this.config.database),e=new nglr.Binder(d[0],f,c,this.config);f.onChangeListener=nglr.shiftBind(e,e.updateModel);f=new nglr.ControlBar(d.find("body"),this.config.server);var h=this.config.database=="$MEMORY"?new nglr.FrameServer(this.window):new nglr.Server(this.config.server, -jQuery.getScript);h=new nglr.VisualServer(h,new nglr.Status(jQuery(d.body)),function(){e.updateView()});var j=new nglr.Users(h,f),l="/data/"+this.config.database,n=new nglr.DataStore(function(p,s){h.request("POST",l,p,s)},j,e.anchor);e.updateListeners.push(function(){n.flush()});var o=new nglr.Scope({$anchor:e.anchor,$binder:e,$config:this.config,$console:window.console,$datastore:n,$save:function(p){n.saveScope(o.state,p,e.anchor)},$window:window,$uid:this.uid,$users:j},"ROOT");jQuery.each(["get", -"set","eval","addWatchListener","updateView"],function(p,s){angular[s]=nglr.bind(o,o[s])});d.data("scope",o);console.log("$binder.entity()");e.entity(o);console.log("$binder.compile()");e.compile();console.log("ControlBar.bind()");f.bind();console.log("$users.fetchCurrentUser()");b();console.log("PopUp.bind()");(new nglr.PopUp(d)).bind();console.log("$binder.parseAnchor()");e.parseAnchor();console.log("$binder.executeInit()");e.executeInit();console.log("$binder.updateView()");e.updateView();c.listener= -nglr.bind(e,e.onUrlChange,c);c.onUpdate=function(){nglr.alert("update")};c.watch();d.find("body").show();console.log("ready()")};a.visualPost=function(b){var c=new nglr.Status(jQuery(document.body));return function(d,f){c.beginRequest(d);b(d,function(){c.endRequest();try{f.apply(this,arguments)}catch(e){nglr.alert(nglr.toJson(e))}})}}; -a.configureLogging=function(){var b=window.location.href+"#";b=b.split("#")[1];var c={debug:null};b=b.split("&");for(var d=0;d<b.length;d++){var f=(b[d]+"=").split("=");c[f[0]]=f[1]}if(c.debug=="console"){nglr.consoleNode=document.createElement("div");nglr.consoleNode.id="ng-console";document.getElementsByTagName("body")[0].appendChild(nglr.consoleNode);console.log=function(){nglr.consoleLog("ng-console-info",arguments)};console.error=function(){nglr.consoleLog("ng-console-error",arguments)}}}; -a.loadCss=function(b){var c=document.createElement("link");c.rel="stylesheet";c.type="text/css";b.match(/^http:/)||(b=this.config.server+b);c.href=b;this.head[0].appendChild(c)};nglr.UrlWatcher=function(b){this.location=b;this.delay=25;this.setTimeout=function(c,d){window.setTimeout(c,d)};this.listener=function(c){return c};this.expectedUrl=b.href}; -nglr.UrlWatcher.prototype.watch=function(){var b=this,c=function(){if(b.expectedUrl!==b.location.href){var d=b.location.hash.match(/^#\$iframe_notify=(.*)$/);if(d){b.expectedUrl.match(/#/)||(b.expectedUrl+="#");b.location.href=b.expectedUrl;d="_iframe_notify_"+d[1];var f=nglr[d];delete nglr[d];try{(f||nglr.noop)()}catch(e){nglr.alert(e)}}else{b.listener(b.location.href);b.expectedUrl=b.location.href}}b.setTimeout(c,b.delay)};c()}; -nglr.UrlWatcher.prototype.setUrl=function(b){var c=window.location.href;c.match(/#/)||(c+="#");if(c!=b)window.location.href=b;self.existingURL=b};nglr.UrlWatcher.prototype.getUrl=function(){return window.location.href};window.angularFactory=function(b){function c(f){(new nglr.Loader(f,jQuery("head"),_(d).extend(b))).load();return jQuery(f).scope()}var d={server:""};return{compile:c}};angular.Global={typeOf:function(b){var c=typeof b;switch(c){case "object":if(b===null)return"null";if(b instanceof Array)return"array";if(b instanceof Date)return"date";if(b.nodeType==1)return"element"}return c}};angular.Collection={};angular.Object={}; -angular.Array={includeIf:function(b,c,d){var f=_.indexOf(b,c);if(d)f==-1&&b.push(c);else b.splice(f,1);return b},sum:function(b,c){c=angular.Function.compile(c);for(var d=0,f=0;f<b.length;f++){var e=1*c(b[f]);isNaN(e)||(d+=e)}return d},remove:function(b,c){var d=_.indexOf(b,c);d>=0&&b.splice(d,1);return c},find:function(b,c,d){if(c){var f=angular.Function.compile(c);_.detect(b,function(e){if(f(e)){d=e;return true}});return d}},findById:function(b,c){return angular.Array.find(b,function(d){return d.$id== -c},null)},filter:function(b,c){var d=[];d.check=function(o){for(var p=0;p<d.length;p++)if(!d[p](o))return false;return true};var f=nglr.Scope.getter,e=function(o,p){if(p.charAt(0)==="!")return!e(o,p.substr(1));switch(typeof o){case "boolean":case "number":case "string":return(""+o).toLowerCase().indexOf(p)>-1;case "object":for(var s in o)if(s.charAt(0)!=="$"&&e(o[s],p))return true;return false;case "array":for(s=0;s<o.length;s++)if(e(o[s],p))return true;return false;default:return false}};switch(typeof c){case "boolean":case "number":case "string":c= -{$:c};case "object":for(var h in c)h=="$"?function(){var o=(""+c[h]).toLowerCase();o&&d.push(function(p){return e(p,o)})}():function(){var o=h,p=(""+c[h]).toLowerCase();p&&d.push(function(s){return e(f(s,o),p)})}();break;case "function":d.push(c);break;default:return b}for(var j=[],l=0;l<b.length;l++){var n=b[l];d.check(n)&&j.push(n)}return j},add:function(b,c){b.push(_.isUndefined(c)?{}:c);return b},count:function(b,c){if(!c)return b.length;var d=angular.Function.compile(c);return _.reduce(b,0,function(f, -e){return f+(d(e)?1:0)})},orderBy:function(b,c,d){function f(h,j){return nglr.toBoolean(j)?function(l,n){return h(n,l)}:h}function e(h,j){var l=typeof h,n=typeof j;if(l==n){if(l=="string")h=h.toLowerCase();if(l=="string")j=j.toLowerCase();if(h===j)return 0;return h<j?-1:1}else return l<n?-1:1}c=_.isArray(c)?c:[c];c=_.map(c,function(h){var j=false;if(typeof h=="string"&&(h.charAt(0)=="+"||h.charAt(0)=="-")){j=h.charAt(0)=="-";h=h.substring(1)}var l=h?angular.Function.compile(h):_.identity;return f(function(n, -o){return e(l(n),l(o))},j)});return _.clone(b).sort(f(function(h,j){for(var l=0;l<c.length;l++){var n=c[l](h,j);if(n!=0)return n}return 0},d))},orderByToggle:function(b,c){var d=false,f=-1;_.detect(b,function(e,h){if(e==c){d=true;f=h;return true}if((e.charAt(0)=="+"||e.charAt(0)=="-")&&e.substring(1)==c){d=e.charAt(0)=="+";f=h;return true}});f>=0&&b.splice(f,1);b.unshift((d?"-":"+")+c);return b},orderByDirection:function(b,c,d,f){d=d||"ng-ascend";f=f||"ng-descend";b=b[0]||"";var e=true;if(b.charAt(0)== -"-"){b=b.substring(1);e=false}else if(b.charAt(0)=="+")b=b.substring(1);return b==c?e?d:f:""},merge:function(b,c,d){var f=b[c];if(!f){f={};b[c]=f}nglr.merge(d,f);return b}}; -angular.String={quote:function(b){return'"'+b.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v")+'"'},quoteUnicode:function(b){b=angular.String.quote(b);for(var c=[],d=0;d<b.length;d++){var f=b.charCodeAt(d);if(f<128)c.push(b.charAt(d));else{f="000"+f.toString(16);c.push("\\u"+f.substring(f.length-4))}}return c.join("")},toDate:function(b){var c;if(typeof b=="string"&&(c=b.match(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/))){b= -new Date(0);b.setUTCFullYear(c[1],c[2]-1,c[3]);b.setUTCHours(c[4],c[5],c[6],0);return b}return b}};angular.Date={toString:function(b){function c(d){return d<10?"0"+d:d}return b.getUTCFullYear()+"-"+c(b.getUTCMonth()+1)+"-"+c(b.getUTCDate())+"T"+c(b.getUTCHours())+":"+c(b.getUTCMinutes())+":"+c(b.getUTCSeconds())+"Z"}};angular.Function={compile:function(b){if(_.isFunction(b))return b;else if(b){var c=new nglr.Scope;return function(d){c.state=d;return c.eval(b)}}else return function(d){return d}}}; -(function(){function b(c,d,f){_.extend(c,d);_.each(f||[],function(e){c[e]=_[e]})}b(angular.Global,{},["extend","clone","isEqual","isElement","isArray","isFunction","isUndefined"]);b(angular.Collection,angular.Global,["each","map","reduce","reduceRight","detect","select","reject","all","any","include","invoke","pluck","max","min","sortBy","sortedIndex","toArray","size"]);b(angular.Array,angular.Collection,["first","last","compact","flatten","without","uniq","intersect","zip","indexOf","lastIndexOf"]); -b(angular.Object,angular.Collection,["keys","values"]);b(angular.String,angular.Global);b(angular.Function,angular.Global,["bind","bindAll","delay","defer","wrap","compose"])})();nglr.Binder=function(b,c,d,f){this.doc=b;this.urlWatcher=d;this.anchor={};this.widgetFactory=c;this.config=f||{};this.updateListeners=[]};nglr.Binder.parseBindings=function(b){for(var c=[],d=0,f;(f=b.indexOf("{{",d))>-1;){d<f&&c.push(b.substr(d,f-d));d=f;f=b.indexOf("}}",f);f=f<0?b.length:f+2;c.push(b.substr(d,f-d));d=f}d!=b.length&&c.push(b.substr(d,b.length-d));return c.length===0?[b]:c}; -nglr.Binder.hasBinding=function(b){b=nglr.Binder.parseBindings(b);return b.length>1||nglr.Binder.binding(b[0])!==null};nglr.Binder.binding=function(b){return(b=b.replace(/\n/gm," ").match(/^\{\{(.*)\}\}$/))?b[1]:null};a=nglr.Binder.prototype;a.parseQueryString=function(b){var c={};b.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(d,f,e){if(f)c[decodeURIComponent(f)]=decodeURIComponent(e)});return c}; -a.parseAnchor=function(b){var c=this;b=b||this.urlWatcher.getUrl();var d=b.indexOf("#");if(!(d<0)){b=this.parseQueryString(b.substring(d+1));jQuery.each(c.anchor,function(f){delete c.anchor[f]});jQuery.each(b,function(f,e){c.anchor[f]=e})}};a.onUrlChange=function(b){console.log("URL change detected",b);this.parseAnchor(b);this.updateView()}; -a.updateAnchor=function(){var b=this.urlWatcher.getUrl(),c=b.indexOf("#");if(c>-1)b=b.substring(0,c);b+="#";c="";for(var d in this.anchor){var f=this.anchor[d];if(typeof f==="undefined"||f===null)delete this.anchor[d];else{b+=c+encodeURIComponent(d);if(f!==true)b+="="+encodeURIComponent(f);c="&"}}this.urlWatcher.setUrl(b);return b}; -a.updateView=function(){(new Date).getTime();var b=jQuery(this.doc).scope();b.set("$invalidWidgets",[]);b.updateView();(new Date).getTime();this.updateAnchor();_.each(this.updateListeners,function(c){c()})};a.docFindWithSelf=function(b){var c=jQuery(this.doc),d=c.find(b);if(c.is(b))d=d.andSelf();return d}; -a.executeInit=function(){this.docFindWithSelf("[ng-init]").each(function(){var b=jQuery(this),c=b.scope();try{c.eval(b.attr("ng-init"))}catch(d){nglr.alert("EVAL ERROR:\n"+b.attr("ng-init")+"\n"+nglr.toJson(d,true))}})};a.entity=function(b){this.docFindWithSelf("[ng-entity]").attr("ng-watch",function(){try{var c=jQuery(this);return b.entity(c.attr("ng-entity"))+(c.attr("ng-watch")||"")}catch(d){nglr.alert(d)}})}; -a.compile=function(){var b=jQuery(this.doc),c=this;if(this.config.autoSubmit){var d=this.docFindWithSelf(":submit").not("[ng-action]");d.attr("ng-action","$save()");d.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr",'{disabled:"{{$invalidWidgets}}"}')}this.precompile(this.doc)(this.doc,b.scope(),"");this.docFindWithSelf("a[ng-action]").live("click",function(){var f=jQuery(this);try{f.scope().eval(f.attr("ng-action"));f.removeAttr("ng-error");f.removeClass("ng-exception")}catch(e){f.addClass("ng-exception"); -f.attr("ng-error",nglr.toJson(e,true))}c.updateView();return false})}; -a.translateBinding=function(b,c,d){c=c.concat();var f=c.pop(),e=nglr.Binder.parseBindings(b.nodeValue);if(e.length>1||nglr.Binder.binding(e[0])){var h=b.parentNode;if(nglr.isLeafNode(h)){h.setAttribute("ng-bind-template",b.nodeValue);d.push({path:c,fn:function(p){return new nglr.BindUpdater(p,p.getAttribute("ng-bind-template"))}})}else for(var j=0;j<e.length;j++){var l=e[j],n=nglr.Binder.binding(l),o;if(n){o=document.createElement("span");jQuery(o).attr("ng-bind",n);j===0&&d.push({path:c.concat(f+ -j),fn:nglr.Binder.prototype.ng_bind})}else if(nglr.msie&&l.charAt(0)==" "){o=document.createElement("span");o.innerHTML=" "+l.substring(1)}else o=document.createTextNode(l);h.insertBefore(o,b)}h.removeChild(b)}};a.precompile=function(b){var c=[];this.precompileNode(b,[],c);return function(d,f,e){for(var h=c.length,j=0;j<h;j++){for(var l=c[j],n=d,o=l.path,p=0;p<o.length;p++)n=n.childNodes[o[p]];try{f.addWidget(l.fn(n,f,e))}catch(s){nglr.alert(s)}}}}; -a.precompileNode=function(b,c,d){var f=b.nodeType;if(f==Node.TEXT_NODE)this.translateBinding(b,c,d);else if(!(f!=Node.ELEMENT_NODE&&f!=Node.DOCUMENT_NODE))if(b.getAttribute){f=b.getAttribute("ng-non-bindable");if(!(f||f==="")){if(f=b.attributes){var e=b.getAttribute("ng-bind-attr");b.removeAttribute("ng-bind-attr");e=e?nglr.fromJson(e):{};for(var h=f.length,j=0;j<h;j++){var l=f[j],n=l.name;l=nglr.msie&&n=="href"?decodeURI(b.getAttribute(n,2)):l.value;if(nglr.Binder.hasBinding(l))e[n]=l}f=nglr.toJson(e); -f.length>2&&b.setAttribute("ng-bind-attr",f)}b.getAttribute||console.log(b);var o=b.getAttribute("ng-repeat");if(o){b.removeAttribute("ng-repeat");var p=this.precompile(b);f=document.createComment("ng-repeat: "+o);e=b.parentNode;e.insertBefore(f,b);e.removeChild(b);var s=function(u,w,g){var i=jQuery(b).clone();i.css("display","");i.attr("ng-repeat-index",""+g);i.data("scope",u);p(i[0],u,w+g+":");return i};d.push({path:c,fn:function(u,w,g){return new nglr.RepeaterUpdater(jQuery(u),o,s,g)}})}else{b.getAttribute("ng-eval")&& -d.push({path:c,fn:this.ng_eval});b.getAttribute("ng-bind")&&d.push({path:c,fn:this.ng_bind});b.getAttribute("ng-bind-attr")&&d.push({path:c,fn:this.ng_bind_attr});b.getAttribute("ng-hide")&&d.push({path:c,fn:this.ng_hide});b.getAttribute("ng-show")&&d.push({path:c,fn:this.ng_show});b.getAttribute("ng-class")&&d.push({path:c,fn:this.ng_class});b.getAttribute("ng-class-odd")&&d.push({path:c,fn:this.ng_class_odd});b.getAttribute("ng-class-even")&&d.push({path:c,fn:this.ng_class_even});b.getAttribute("ng-style")&& -d.push({path:c,fn:this.ng_style});b.getAttribute("ng-watch")&&d.push({path:c,fn:this.ng_watch});f=b.nodeName;if(f=="INPUT"||f=="TEXTAREA"||f=="SELECT"||f=="BUTTON"){var v=this;d.push({path:c,fn:function(u,w,g){u.name=g+u.name.split(":").pop();return v.widgetFactory.createController(jQuery(u),w)}})}if(f=="OPTION")if(!jQuery("<select/>").append(jQuery(b).clone()).html().match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi))b.value=b.text;f=b.childNodes;for(e=0;e<f.length;e++)this.precompileNode(f[e], -c.concat(e),d)}}}};a.ng_eval=function(b){return new nglr.EvalUpdater(b,b.getAttribute("ng-eval"))};a.ng_bind=function(b){return new nglr.BindUpdater(b,"{{"+b.getAttribute("ng-bind")+"}}")};a.ng_bind_attr=function(b){return new nglr.BindAttrUpdater(b,nglr.fromJson(b.getAttribute("ng-bind-attr")))};a.ng_hide=function(b){return new nglr.HideUpdater(b,b.getAttribute("ng-hide"))};a.ng_show=function(b){return new nglr.ShowUpdater(b,b.getAttribute("ng-show"))}; -a.ng_class=function(b){return new nglr.ClassUpdater(b,b.getAttribute("ng-class"))};a.ng_class_even=function(b){return new nglr.ClassEvenUpdater(b,b.getAttribute("ng-class-even"))};a.ng_class_odd=function(b){return new nglr.ClassOddUpdater(b,b.getAttribute("ng-class-odd"))};a.ng_style=function(b){return new nglr.StyleUpdater(b,b.getAttribute("ng-style"))};a.ng_watch=function(b,c){c.watch(b.getAttribute("ng-watch"))};nglr.ControlBar=function(b,c){this.document=b;this.serverUrl=c;this.window=window;this.callbacks=[]};nglr.ControlBar.prototype.bind=function(){};nglr.ControlBar.HTML='<div><div class="ui-widget-overlay"></div><div id="ng-login" ng-non-bindable="true"><div class="ng-login-container"></div></div></div>';nglr.ControlBar.prototype.login=function(b){this.callbacks.push(b);this.callbacks.length==1&&this.doTemplate("/user_session/new.mini?return_url="+encodeURIComponent(this.urlWithoutAnchor()))}; -nglr.ControlBar.prototype.logout=function(b){this.callbacks.push(b);this.callbacks.length==1&&this.doTemplate("/user_session/do_destroy.mini")};nglr.ControlBar.prototype.urlWithoutAnchor=function(){return this.window.location.href.split("#")[0]}; -nglr.ControlBar.prototype.doTemplate=function(b){var c=this,d=(new Date).getTime(),f=this.urlWithoutAnchor();f+="#$iframe_notify="+d;var e=jQuery('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+f+'" src="'+this.serverUrl+b+'" width="500" height="330"/></div>');this.document.append(e);e.dialog({height:363,width:500,resizable:false,modal:true,title:'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>'});nglr["_iframe_notify_"+d]=function(){e.dialog("destroy"); -e.remove();jQuery.each(c.callbacks,function(h,j){j()});c.callbacks=[]}};nglr.ControlBar.FORBIDEN='<div ng-non-bindable="true" title="Permission Error:">Sorry, you do not have permission for this!</div>';nglr.ControlBar.prototype.notAuthorized=function(){if(!this.forbidenView){this.forbidenView=jQuery(nglr.ControlBar.FORBIDEN);this.forbidenView.dialog({bgiframe:true,height:70,modal:true})}};nglr.DataStore=function(b,c,d){this.post=b;this.users=c;this._cache={$collections:[]};this.anchor=d;this.bulkRequest=[]};a=nglr.DataStore.prototype;a.cache=function(b){if(b.constructor!=nglr.Model)throw"Parameter must be an instance of Entity! "+nglr.toJson(b);var c=b.$entity+"/"+b.$id,d=this._cache[c];if(d)nglr.Model.copyDirectFields(b,d);else d=this._cache[c]=b;return d}; -a.load=function(b,c,d,f){if(c&&c!=="*"){var e=this;this._jsonRequest(["GET",b.$entity+"/"+c],function(h){b.$loadFrom(h);b.$migrate();h=b.$$entity(b);e.cache(h);(d||nglr.noop)(b)},f)}return b};a.loadMany=function(b,c,d){var f=this,e=[],h=0;jQuery.each(c,function(j,l){e.push(f.load(b(),l,function(){h++;if(h==c.length)(d||nglr.noop)(e)}))});return e};a.loadOrCreate=function(b,c,d){return this.load(b,c,d,function(f){if(f.$status_code==404){b.$id=c;(d||nglr.noop)(b)}else throw f;})}; -a.loadAll=function(b,c){var d=this,f=[];f.$$accept=function(e){return e.$entity==b.title};this._cache.$collections.push(f);this._jsonRequest(["GET",b.title],function(e){for(var h=0;h<e.length;h++){var j=b();j.$loadFrom(e[h]);f.push(d.cache(j))}(c||nglr.noop)(f)});return f}; -a.save=function(b,c){var d=this,f={};b.$saveTo(f);this._jsonRequest(["POST","",f],function(e){b.$loadFrom(e);var h=d.cache(b);_.each(d._cache.$collections,function(j){j.$$accept(b)&&angular.Array.includeIf(j,h,true)});if(b.$$anchor)d.anchor[b.$$anchor]=b.$id;c&&c(b)})}; -a.remove=function(b,c){var d=this,f={};b.$saveTo(f);this._jsonRequest(["DELETE","",f],function(e){delete d._cache[b.$entity+"/"+b.$id];_.each(d._cache.$collections,function(h){for(var j=0;j<h.length;j++)h[j].$id==b.$id&&h.splice(j,1)});(c||nglr.noop)(e)})};a._jsonRequest=function(b,c,d){b.$$callback=c;b.$$failure=d||function(f){throw f;};this.bulkRequest.push(b)}; -a.flush=function(){function b(f,e){console.log("RESPONSE["+f+"]: ",e);if(e.$status_code==401)c.users.login(function(){c.post(d,b)});else if(e.$status_code)nglr.alert(nglr.toJson(e));else for(var h=0;h<e.length;h++){var j=e[h],l=d[h];if(f=j.$status_code)f==403?c.users.notAuthorized():l.$$failure(j);else l.$$callback(j)}}if(this.bulkRequest.length!==0){var c=this,d=this.bulkRequest;this.bulkRequest=[];console.log("REQUEST:",d);this.post(d,b)}}; -a.saveScope=function(b,c){function d(){f--;f===0&&c&&c()}var f=1;for(var e in b){var h=b[e];if(h&&h.$save==nglr.Model.prototype.$save){f++;h.$save(d)}}d()};a.query=function(b,c,d,f){var e=this,h=[];h.$$accept=function(){return false};this._cache.$collections.push(h);this._jsonRequest(["GET",b.title+"/"+c+"="+d],function(j){for(var l=0;l<j.length;l++){var n=(new b).$loadFrom(j[l]);h.push(e.cache(n))}f&&f(h)});return h}; -a.entities=function(b){var c=[],d=this;this._jsonRequest(["GET","$entities"],function(f){for(var e in f)c.push(d.entity(e));c.sort(function(h,j){return h.title>j.title?1:-1});b&&b(c)});return c};a.documentCountsByUser=function(){var b={};this.post([["GET","$users"]],function(c,d){jQuery.each(d[0],function(f,e){b[f]=e})});return b};a.userDocumentIdsByEntity=function(b){var c={};this.post([["GET","$users/"+b]],function(d,f){jQuery.each(f[0],function(e,h){c[e]=h})});return c}; -nglr.DataStore.NullEntity=function(){};nglr.DataStore.NullEntity.all=function(){return[]};nglr.DataStore.NullEntity.query=function(){return[]};nglr.DataStore.NullEntity.load=function(){return{}};nglr.DataStore.NullEntity.title=undefined; -nglr.DataStore.prototype.entity=function(b,c){if(!b)return nglr.DataStore.NullEntity;var d=this,f=function(e){return new nglr.Model(f,e)};f.title=b;f.$$factory=true;f.datastore=this;f.defaults=c||{};f.load=function(e,h){return d.load(f(),e,h)};f.loadMany=function(e,h){return d.loadMany(f,e,h)};f.loadOrCreate=function(e,h){return d.loadOrCreate(f(),e,h)};f.all=function(e){return d.loadAll(f,e)};f.query=function(e,h,j){return d.query(f,e,h,j)};f.properties=function(e){d._jsonRequest(["GET",b+"/$properties"], -e)};return f}; -nglr.DataStore.prototype.join=function(b){function c(h){return h?h.substring(0,h.indexOf(".")):undefined}function d(h){return h.substring(h.indexOf(".")+1)}var f=function(){throw"Joined entities can not be instantiated into a document.";},e=_(b).chain().map(function(h,j){return j}).sortBy(function(h){var j=[];do{if(_(j).include(h))throw"Infinite loop in join: "+j.join(" -> ");j.push(h);if(!b[h])throw _("Named entity '<%=name%>' is undefined.").template({name:h});h=c(b[h].on)}while(h);return j.length}).value(); -if(_(e).select(function(h){return b[h].on}).length!=e.length-1)throw"Exactly one entity needs to be primary.";f.query=function(h,j){var l=[],n=c(h);if(n!=e[0])throw _("Named entity '<%=name%>' is not a primary entity.").template({name:n});var o=1;b[n].join.query(d(h),j,function(p){var s=e[o++],v=b[s],u=v.on,w={};_(p).each(function(g){var i={};l.push(i);i[n]=g;g=nglr.Scope.getter(i,u);w[g]=g});v.join.loadMany(_.toArray(w),function(g){var i={};_(g).each(function(k){i[k.$id]=k});_(l).each(function(k){var m= -nglr.Scope.getter(k,u);k[s]=i[m]})})});return l};return f};angular.filter.Meta=function(b){if(b)for(var c in b)this[c]=b[c]};angular.filter.Meta.get=function(b,c){c=c||"text";switch(typeof b){case "string":return c=="text"?b:undefined;case "object":if(b&&typeof b[c]!=="undefined")return b[c];return;default:return b}};angular.filter.currency=function(b){jQuery(this.element).toggleClass("ng-format-negative",b<0);return"$"+angular.filter.number.apply(this,[b,2])}; -angular.filter.number=function(b,c){if(isNaN(b)||!isFinite(b))return"";c=typeof c=="undefined"?2:c;var d=b<0;b=Math.abs(b);var f=Math.pow(10,c);b=""+Math.round(b*f);var e=b.substring(0,b.length-c);e=e||"0";f=b.substring(b.length-c);b=d?"-":"";for(d=0;d<e.length;d++){if((e.length-d)%3===0&&d!==0)b+=",";b+=e.charAt(d)}if(c>0){for(d=f.length;d<c;d++)f+="0";b+="."+f.substring(0,c)}return b};angular.filter.date=function(){}; -angular.filter.json=function(b){jQuery(this.element).addClass("ng-monospace");return nglr.toJson(b,true)}; -angular.filter.trackPackage=function(b,c){b=nglr.trim(b);for(var d=b.replace(/ /g,""),f=angular.filter.trackPackage.MATCHERS,e=0;e<f.length;e++)for(var h=f[e],j=0;j<h.regexp.length;j++)if(h.regexp[j].test(d)){c=h.name+": "+b;h=h.url+b;return new angular.filter.Meta({text:c,url:h,html:'<a href="'+nglr.escapeAttr(h)+'">'+c+"</a>",trackingNo:b})}return b?c||new angular.filter.Meta({text:b+" is not recognized"}):null}; -angular.filter.trackPackage.MATCHERS=[{name:"UPS",url:"http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=",regexp:[/^1Z[0-9A-Z]{16}$/i]},{name:"FedEx",url:"http://www.fedex.com/Tracking?tracknumbers=",regexp:[/^96\d{10}?$/i,/^96\d{17}?$/i,/^96\d{20}?$/i,/^\d{15}$/i,/^\d{12}$/i]},{name:"USPS",url:"http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=",regexp:[/^(91\d{20})$/i, -/^(91\d{18})$/i]}];angular.filter.link=function(b,c){c=c||angular.filter.Meta.get(b);var d=angular.filter.Meta.get(b,"url")||angular.filter.Meta.get(b);if(d){if(angular.validator.email(d)===null)d="mailto:"+d;b='<a href="'+nglr.escapeHtml(d)+'">'+c+"</a>";return new angular.filter.Meta({text:c,url:d,html:b})}return b};angular.filter.bytes=function(b){if(b===null)return"";for(var c=0;b>1E3;){b/=1024;c++}b=""+b;var d=b.indexOf(".");if(d>-1&&d+2<b.length)b=b.substring(0,d+2);return b+" "+angular.filter.bytes.SUFFIX[c]}; -angular.filter.bytes.SUFFIX=["bytes","KB","MB","GB","TB","PB"];angular.filter.image=function(b,c,d){if(b&&b.url){var f="";if(c)f=' style="max-width: '+c+"px; max-height: "+(d||c)+'px;"';return new angular.filter.Meta({url:b.url,text:b.url,html:'<img src="'+b.url+'"'+f+"/>"})}return null};angular.filter.lowercase=function(b){return(b=angular.filter.Meta.get(b))?(""+b).toLowerCase():b};angular.filter.uppercase=function(b){return(b=angular.filter.Meta.get(b))?(""+b).toUpperCase():b}; -angular.filter.linecount=function(b){b=angular.filter.Meta.get(b);if(b===""||!b)return 1;return b.split(/\n|\f/).length};angular.filter["if"]=function(b,c){return c?b:undefined};angular.filter.unless=function(b,c){return c?undefined:b}; -angular.filter.googleChartApi=function(b,c,d,f){c=c||{};var e=angular.filter.googleChartApi;b={cht:b,chco:e.collect(c,"color"),chtt:e.title(c),chdl:e.collect(c,"label"),chd:e.values(c),chf:"bg,s,FFFFFF00"};if(_.isArray(c.xLabels)){b.chxt="x";b.chxl="0:|"+c.xLabels.join("|")}return angular.filter.googleChartApi.encode(b,d,f)}; -angular.filter.googleChartApi.values=function(b){var c=[];_.each(b.series||[],function(d){var f=[];_.each(d.values||[],function(e){f.push(e)});c.push(f.join(","))});b=c.join("|");return b===""?null:"t:"+b};angular.filter.googleChartApi.title=function(b){var c=[];b=b.title||[];_.each(_.isArray(b)?b:[b],function(d){c.push(encodeURIComponent(d))});return c.join("|")}; -angular.filter.googleChartApi.collect=function(b,c){var d=[],f=0;_.each(b.series||[],function(e){var h=[];e=e[c]||[];_.each(_.isArray(e)?e:[e],function(j){h.push(encodeURIComponent(j));f++});d.push(h.join("|"))});return f?d.join(","):null}; -angular.filter.googleChartApi.encode=function(b,c,d){c=c||200;d=d||c;var f="http://chart.apis.google.com/chart?",e=[];b.chs=c+"x"+d;for(var h in b){var j=b[h];j&&e.push(h+"="+j)}e.sort();f+=e.join("&");return new angular.filter.Meta({url:f,text:j,html:'<img width="'+c+'" height="'+d+'" src="'+f+'"/>'})};angular.filter.qrcode=function(b,c,d){return angular.filter.googleChartApi.encode({cht:"qr",chl:encodeURIComponent(b)},c,d)}; -angular.filter.chart={pie:function(b,c,d){return angular.filter.googleChartApi("p",b,c,d)},pie3d:function(b,c,d){return angular.filter.googleChartApi("p3",b,c,d)},pieConcentric:function(b,c,d){return angular.filter.googleChartApi("pc",b,c,d)},barHorizontalStacked:function(b,c,d){return angular.filter.googleChartApi("bhs",b,c,d)},barHorizontalGrouped:function(b,c,d){return angular.filter.googleChartApi("bhg",b,c,d)},barVerticalStacked:function(b,c,d){return angular.filter.googleChartApi("bvs",b,c, -d)},barVerticalGrouped:function(b,c,d){return angular.filter.googleChartApi("bvg",b,c,d)},line:function(b,c,d){return angular.filter.googleChartApi("lc",b,c,d)},sparkline:function(b,c,d){return angular.filter.googleChartApi("ls",b,c,d)},scatter:function(b,c,d){return angular.filter.googleChartApi("s",b,c,d)}};angular.filter.html=function(b){return new angular.filter.Meta({html:b})};nglr.array=[].constructor;nglr.toJson=function(b,c){var d=[];nglr.toJsonArray(d,b,c?"\n  ":null);return d.join("")};nglr.toPrettyJson=function(b){return nglr.toJson(b,true)};nglr.fromJson=function(b){try{var c=new nglr.Parser(b,true),d=c.primary();c.assertAllConsumed();return d()}catch(f){console.error("fromJson error: ",b,f);throw f;}}; -nglr.toJsonArray=function(b,c,d){var f=typeof c;if(c===null)b.push("null");else if(f!=="function")if(f==="boolean")b.push(""+c);else if(f==="number")isNaN(c)?b.push("null"):b.push(""+c);else if(f==="string")return b.push(angular.String.quoteUnicode(c));else if(f==="object")if(c instanceof Array){b.push("[");var e=c.length;f=false;for(var h=0;h<e;h++){var j=c[h];f&&b.push(",");typeof j=="function"||typeof j=="undefined"?b.push("null"):nglr.toJsonArray(b,j,d);f=true}b.push("]")}else if(c instanceof -Date)b.push(angular.String.quoteUnicode(angular.Date.toString(c)));else{b.push("{");d&&b.push(d);f=false;h=d?d+"  ":false;j=[];for(var l in c)l.indexOf("$$")!==0&&j.push(l);j.sort();for(l=0;l<j.length;l++){var n=j[l];try{e=c[n];if(typeof e!="function"){if(f){b.push(",");d&&b.push(d)}b.push(angular.String.quote(n));b.push(":");nglr.toJsonArray(b,e,h);f=true}}catch(o){}}b.push("}")}};nglr.Model=function(b,c){this.$$entity=b;this.$loadFrom(c||{});this.$entity=b.title;this.$migrate()};nglr.Model.copyDirectFields=function(b,c){if(!(b===c||!b||!c)){var d=function(e,h,j){return j.substring(0,2)!=="$$"&&typeof e[j]!=="function"&&typeof h[j]!=="function"};for(var f in c)d(b,c,f)&&delete c[f];for(f in b)if(d(b,c,f))c[f]=b[f]}};a=nglr.Model.prototype;a.$migrate=function(){nglr.merge(this.$$entity.defaults,this);return this};a.$merge=function(b){nglr.merge(b,this);return this}; -a.$save=function(b){this.$$entity.datastore.save(this,b===true?undefined:b);b===true&&this.$$entity.datastore.flush();return this};a.$delete=function(b){this.$$entity.datastore.remove(this,b===true?undefined:b);b===true&&this.$$entity.datastore.flush();return this};a.$loadById=function(b,c){this.$$entity.datastore.load(this,b,c);return this};a.$loadFrom=function(b){nglr.Model.copyDirectFields(b,this);return this};a.$saveTo=function(b){nglr.Model.copyDirectFields(this,b);return this};nglr.Lexer=function(b,c){this.text=b;this.dateParseLength=c?20:-1;this.tokens=[];this.index=0}; -nglr.Lexer.OPERATORS={"null":function(){return null},"true":function(){return true},"false":function(){return false},"+":function(b,c,d){return(c||0)+(d||0)},"-":function(b,c,d){return(c||0)-(d||0)},"*":function(b,c,d){return c*d},"/":function(b,c,d){return c/d},"%":function(b,c,d){return c%d},"^":function(b,c,d){return c^d},"=":function(b,c,d){return b.scope.set(c,d)},"==":function(b,c,d){return c==d},"!=":function(b,c,d){return c!=d},"<":function(b,c,d){return c<d},">":function(b,c,d){return c> -d},"<=":function(b,c,d){return c<=d},">=":function(b,c,d){return c>=d},"&&":function(b,c,d){return c&&d},"||":function(b,c,d){return c||d},"&":function(b,c,d){return c&d},"|":function(b,c,d){return d(b,c)},"!":function(b,c){return!c}};a=nglr.Lexer.prototype;a.peek=function(){return this.index+1<this.text.length?this.text.charAt(this.index+1):false}; -a.parse=function(){for(var b=this.tokens,c=nglr.Lexer.OPERATORS,d=true;this.index<this.text.length;){var f=this.text.charAt(this.index);if(f=='"'||f=="'"){this.readString(f);d=true}else if(f=="("||f=="["){b.push({index:this.index,text:f});this.index++}else if(f=="{"){d=this.peek();if(d==":"||d=="("){b.push({index:this.index,text:f+d});this.index++}else b.push({index:this.index,text:f});this.index++;d=true}else if(f==")"||f=="]"||f=="}"){b.push({index:this.index,text:f});this.index++;d=false}else if(f== -":"||f=="."||f==","||f==";"){b.push({index:this.index,text:f});this.index++;d=true}else if(d&&f=="/"){this.readRegexp();d=false}else if(this.isNumber(f)){this.readNumber();d=false}else if(this.isIdent(f)){this.readIdent();d=false}else if(this.isWhitespace(f))this.index++;else{d=f+this.peek();var e=c[f],h=c[d];if(h){b.push({index:this.index,text:d,fn:h});this.index+=2}else if(e){b.push({index:this.index,text:f,fn:e});this.index+=1}else throw"Lexer Error: Unexpected next character ["+this.text.substring(this.index)+ -"] in expression '"+this.text+"' at column '"+(this.index+1)+"'.";d=true}}return b};a.isNumber=function(b){return"0"<=b&&b<="9"};a.isWhitespace=function(b){return b==" "||b=="\r"||b=="\t"||b=="\n"||b=="\u000b"};a.isIdent=function(b){return"a"<=b&&b<="z"||"A"<=b&&b<="Z"||"_"==b||b=="$"};a.readNumber=function(){for(var b="",c=this.index;this.index<this.text.length;){var d=this.text.charAt(this.index);if(d=="."||this.isNumber(d))b+=d;else break;this.index++}b=1*b;this.tokens.push({index:c,text:b,fn:function(){return b}})}; -a.readIdent=function(){for(var b="",c=this.index;this.index<this.text.length;){var d=this.text.charAt(this.index);if(d=="."||this.isIdent(d)||this.isNumber(d))b+=d;else break;this.index++}d=nglr.Lexer.OPERATORS[b];if(!d){d=function(f){return f.scope.get(b)};d.isAssignable=b}this.tokens.push({index:c,text:b,fn:d})};nglr.Lexer.ESCAPE={n:"\n",f:"\u000c",r:"\r",t:"\t",v:"\u000b","'":"'",'"':'"'}; -nglr.Lexer.prototype.readString=function(b){var c=this.index,d=this.dateParseLength;this.index++;for(var f="",e=false;this.index<this.text.length;){var h=this.text.charAt(this.index);if(e){if(h=="u"){h=this.text.substring(this.index+1,this.index+5);this.index+=4;f+=String.fromCharCode(parseInt(h,16))}else{e=nglr.Lexer.ESCAPE[h];f+=e?e:h}e=false}else if(h=="\\")e=true;else if(h==b){this.index++;this.tokens.push({index:c,text:f,fn:function(){return f.length==d?angular.String.toDate(f):f}});return}else f+= -h;this.index++}throw"Lexer Error: Unterminated quote ["+this.text.substring(c)+"] starting at column '"+(c+1)+"' in expression '"+this.text+"'.";}; -nglr.Lexer.prototype.readRegexp=function(){var b=this.index;this.index++;for(var c="",d=false;this.index<this.text.length;){var f=this.text.charAt(this.index);if(d){c+=f;d=false}else if(f==="\\"){c+=f;d=true}else if(f==="/"){this.index++;d="";if(this.isIdent(this.text.charAt(this.index))){this.readIdent();d=this.tokens.pop().text}var e=new RegExp(c,d);this.tokens.push({index:b,text:c,flags:d,fn:function(){return e}});return}else c+=f;this.index++}throw"Lexer Error: Unterminated RegExp ["+this.text.substring(b)+ -"] starting at column '"+(b+1)+"' in expression '"+this.text+"'.";};nglr.Parser=function(b,c){this.text=b;this.tokens=(new nglr.Lexer(b,c)).parse();this.index=0};nglr.Parser.ZERO=function(){return 0};a=nglr.Parser.prototype;a.error=function(b,c){throw"Token '"+c.text+"' is "+b+" at column='"+(c.index+1)+"' of expression '"+this.text+"' starting at '"+this.text.substring(c.index)+"'.";};a.peekToken=function(){if(this.tokens.length===0)throw"Unexpected end of expression: "+this.text;return this.tokens[0]}; -a.peek=function(b,c,d,f){var e=this.tokens;if(e.length>0){e=e[0];var h=e.text;if(h==b||h==c||h==d||h==f||!b&&!c&&!d&&!f)return e}return false};a.expect=function(b,c,d,f){if(b=this.peek(b,c,d,f)){this.tokens.shift();return this.currentToken=b}return false};a.consume=function(b){if(!this.expect(b)){var c=this.peek();throw"Expecting '"+b+"' at column '"+(c.index+1)+"' in '"+this.text+"' got '"+this.text.substring(c.index)+"'.";}}; -a._unary=function(b,c){var d=c.apply(this);return function(f){return b(f,d(f))}};a._binary=function(b,c,d){var f=d.apply(this);return function(e){return c(e,b(e),f(e))}};a.hasTokens=function(){return this.tokens.length>0};a.assertAllConsumed=function(){if(this.tokens.length!==0)throw"Did not understand '"+this.text.substring(this.tokens[0].index)+"' while evaluating '"+this.text+"'.";}; -a.statements=function(){for(var b=[];;){this.tokens.length>0&&!this.peek("}",")",";","]")&&b.push(this.filterChain());if(!this.expect(";"))return function(c){for(var d,f=0;f<b.length;f++){var e=b[f];if(e)d=e(c)}return d}}};a.filterChain=function(){for(var b=this.expression(),c;;)if(c=this.expect("|"))b=this._binary(b,c.fn,this.filter);else return b};a.filter=function(){return this._pipeFunction(angular.filter)};a.validator=function(){return this._pipeFunction(angular.validator)}; -a._pipeFunction=function(b){for(var c=this.functionIdent(b),d=[];;)if(this.expect(":"))d.push(this.expression());else{var f=function(e,h){h=[h];for(var j=0;j<d.length;j++)h.push(d[j](e));return c.apply(e,h)};return function(){return f}}};a.expression=function(){return this.throwStmt()};a.throwStmt=function(){if(this.expect("throw")){var b=this.assignment();return function(c){throw b(c);}}else return this.assignment()}; -a.assignment=function(){var b=this.logicalOR(),c;if(c=this.expect("=")){if(!b.isAssignable)throw"Left hand side '"+this.text.substring(0,c.index)+"' of assignment '"+this.text.substring(c.index)+"' is not assignable.";return this._binary(function(){return b.isAssignable},c.fn,this.logicalOR)}else return b};a.logicalOR=function(){for(var b=this.logicalAND(),c;;)if(c=this.expect("||"))b=this._binary(b,c.fn,this.logicalAND);else return b}; -a.logicalAND=function(){for(var b=this.negated(),c;;)if(c=this.expect("&&"))b=this._binary(b,c.fn,this.negated);else return b};a.negated=function(){var b;return(b=this.expect("!"))?this._unary(b.fn,this.equality):this.equality()};a.equality=function(){for(var b=this.relational(),c;;)if(c=this.expect("==","!="))b=this._binary(b,c.fn,this.relational);else return b};a.relational=function(){for(var b=this.additive(),c;;)if(c=this.expect("<",">","<=",">="))b=this._binary(b,c.fn,this.additive);else return b}; -a.additive=function(){for(var b=this.multiplicative(),c;c=this.expect("+","-");)b=this._binary(b,c.fn,this.multiplicative);return b};a.multiplicative=function(){for(var b=this.unary(),c;c=this.expect("*","/","%");)b=this._binary(b,c.fn,this.unary);return b};a.unary=function(){var b;return this.expect("+")?this.primary():(b=this.expect("-"))?this._binary(nglr.Parser.ZERO,b.fn,this.multiplicative):this.primary()}; -a.functionIdent=function(b){var c=this.expect(),d=c.text.split(".");b=b;for(var f,e=0;e<d.length;e++){f=d[e];if(b)b=b[f]}if(typeof b!="function")throw"Function '"+c.text+"' at column '"+(c.index+1)+"' in '"+this.text+"' is not defined.";return b}; -a.primary=function(){var b;if(this.expect("(")){b=this.filterChain();this.consume(")");b=b}else if(this.expect("["))b=this.arrayDeclaration();else if(this.expect("{"))b=this.object();else if(this.expect("{:"))b=this.closure(false);else if(this.expect("{("))b=this.closure(true);else{var c=this.expect();(b=c.fn)||this.error("not a primary expression",c)}for(;c=this.expect("(","[",".");)if(c.text==="(")b=this.functionCall(b);else if(c.text==="[")b=this.objectIndex(b);else if(c.text===".")b=this.fieldAccess(b); -else throw"IMPOSSIBLE";return b};a.closure=function(b){var c=[];if(b){if(!this.expect(")")){for(c.push(this.expect().text);this.expect(",");)c.push(this.expect().text);this.consume(")")}this.consume(":")}var d=this.statements();this.consume("}");return function(f){return function(e){var h=new nglr.Scope(f.scope.state);h.set("$",e);for(var j=0;j<c.length;j++)h.set(c[j],arguments[j]);return d({scope:h})}}}; -a.fieldAccess=function(b){var c=this.expect().text,d=function(f){return nglr.Scope.getter(b(f),c)};d.isAssignable=c;return d};a.objectIndex=function(b){var c=this.expression();this.consume("]");if(this.expect("=")){var d=this.expression();return function(f){return b(f)[c(f)]=d(f)}}else return function(f){var e=b(f);f=c(f);return e?e[f]:undefined}}; -a.functionCall=function(b){var c=[];if(this.peekToken().text!=")"){do c.push(this.expression());while(this.expect(","))}this.consume(")");return function(d){for(var f=[],e=0;e<c.length;e++)f.push(c[e](d));e=b(d);if(typeof e==="function")return e.apply(d,f);else throw"Expression '"+b.isAssignable+"' is not a function.";}}; -a.arrayDeclaration=function(){var b=[];if(this.peekToken().text!="]"){do b.push(this.expression());while(this.expect(","))}this.consume("]");return function(c){for(var d=[],f=0;f<b.length;f++)d.push(b[f](c));return d}};a.object=function(){var b=[];if(this.peekToken().text!="}"){do{var c=this.expect().text;this.consume(":");var d=this.expression();b.push({key:c,value:d})}while(this.expect(","))}this.consume("}");return function(f){for(var e={},h=0;h<b.length;h++){var j=b[h],l=j.value(f);e[j.key]=l}return e}}; -a.entityDeclaration=function(){for(var b=[];this.hasTokens();){b.push(this.entityDecl());this.expect(";")||this.assertAllConsumed()}return function(c){for(var d="",f=0;f<b.length;f++)d+=b[f](c);return d}}; -a.entityDecl=function(){var b=this.expect().text,c,d;if(this.expect("=")){c=b;b=this.expect().text}if(this.expect(":"))d=this.primary()(null);return function(f){var e=f.scope.get("$datastore").entity(b,d);f.scope.set(b,e);if(c){e=e();e.$$anchor=c;f.scope.set(c,e);return"$anchor."+c+":{"+c+"="+b+".load($anchor."+c+");"+c+".$$anchor="+angular.String.quote(c)+";};"}else return""}}; -a.watch=function(){for(var b=[];this.hasTokens();){b.push(this.watchDecl());this.expect(";")||this.assertAllConsumed()}this.assertAllConsumed();return function(c){for(var d=0;d<b.length;d++){var f=b[d](c);c.addListener(f.name,f.fn)}}};a.watchDecl=function(){var b=this.expect().text;this.consume(":");var c;if(this.peekToken().text=="{"){this.consume("{");c=this.statements();this.consume("}")}else c=this.expression();return function(){return{name:b,fn:c}}};nglr.Scope=function(b,c){this.widgets=[];this.watchListeners={};this.name=c;b=b||{};var d=function(){};d.prototype=b;this.state=new d;this.state.$parent=b;if(c=="ROOT")this.state.$root=this.state};nglr.Scope.expressionCache={};nglr.Scope.prototype.updateView=function(){var b=this;this.fireWatchers();_.each(this.widgets,function(c){b.evalWidget(c,"",{},function(){this.updateView(b)})})};nglr.Scope.prototype.addWidget=function(b){b&&this.widgets.push(b)}; -nglr.Scope.prototype.isProperty=function(b){for(var c=0;c<b.length;c++){var d=b.charAt(c);if(d!="."&&!nglr.Lexer.prototype.isIdent(d))return false}return true}; -nglr.Scope.getter=function(b,c){if(!c)return b;for(var d=c.split("."),f,e=b,h=d.length,j=0;j<h;j++){f=d[j];if(!f.match(/^[\$\w][\$\w\d]*$/))throw"Expression '"+c+"' is not a valid expression for accesing variables.";if(b){e=b;b=b[f]}if(_.isUndefined(b)&&f.charAt(0)=="$"){var l=angular.Global.typeOf(e);if(f=(l=angular[l.charAt(0).toUpperCase()+l.substring(1)])?l[[f.substring(1)]]:undefined)return b=_.bind(f,e,e)}}if(typeof b==="function"&&!b.$$factory)return nglr.bind(e,b);return b};a=nglr.Scope.prototype; -a.get=function(b){return nglr.Scope.getter(this.state,b)};a.set=function(b,c){b=b.split(".");for(var d=this.state,f=0;b.length>1;f++){var e=b.shift(),h=d[e];if(!h){h={};d[e]=h}d=h}return d[b.shift()]=c};a.setEval=function(b,c){this.eval(b+"="+nglr.toJson(c))};a.eval=function(b,c){var d=nglr.Scope.expressionCache[b];if(!d){var f=new nglr.Parser(b);d=f.statements();f.assertAllConsumed();nglr.Scope.expressionCache[b]=d}c=c||{};c.scope=this;return d(c)}; -a.evalWidget=function(b,c,d,f,e){try{var h=this.eval(c,d);if(b.hasError){b.hasError=false;jQuery(b.view).removeClass("ng-exception").removeAttr("ng-error")}f&&f.apply(b,[h]);return true}catch(j){console.error("Eval Widget Error:",j);c=nglr.toJson(j,true);b.hasError=true;jQuery(b.view).addClass("ng-exception").attr("ng-error",c);e&&e.apply(b,[j,c]);return false}}; -a.validate=function(b,c){var d=nglr.Scope.expressionCache[b];if(!d){d=(new nglr.Parser(b)).validator();nglr.Scope.expressionCache[b]=d}b={scope:this};return d(b)(b,c)};a.entity=function(b){return(new nglr.Parser(b)).entityDeclaration()({scope:this})};a.markInvalid=function(b){this.state.$invalidWidgets.push(b)};a.watch=function(b){var c=this;(new nglr.Parser(b)).watch()({scope:this,addListener:function(d,f){c.addWatchListener(d,function(e,h){try{return f({scope:c},e,h)}catch(j){nglr.alert(j)}})}})}; -a.addWatchListener=function(b,c){var d=this.watchListeners[b];if(!d){d={listeners:[],expression:b};this.watchListeners[b]=d}d.listeners.push(c)};a.fireWatchers=function(){var b=this,c=false;jQuery.each(this.watchListeners,function(d,f){var e=b.eval(f.expression);if(e!==f.lastValue){jQuery.each(f.listeners,function(h,j){j(e,f.lastValue);c=true});f.lastValue=e}});return c};nglr.Server=function(b,c){this.url=b;this.nextId=0;this.getScript=c;this.uuid="_"+(""+Math.random()).substr(2)+"_";this.maxSize=1800};nglr.Server.prototype.base64url=function(b){return Base64.encode(b)}; -nglr.Server.prototype.request=function(b,c,d,f){var e=this.uuid+this.nextId++;nglr[e]=function(l){delete nglr[e];f(200,l)};b={u:c,m:b,p:d};b=this.base64url(nglr.toJson(b));c=Math.ceil(b.length/this.maxSize);d=this.url+"/$/"+e+"/"+c+"/";for(var h=0;h<c;h++){var j=b.substr(h*this.maxSize,this.maxSize);this.getScript(d+(h+1)+"?h="+j,nglr.noop)}};nglr.FrameServer=function(b){this.frame=b};nglr.FrameServer.PREFIX="$DATASET:"; -nglr.FrameServer.prototype={read:function(){this.data=nglr.fromJson(this.frame.name.substr(nglr.FrameServer.PREFIX.length))},write:function(){this.frame.name=nglr.FrameServer.PREFIX+nglr.toJson(this.data)},request:function(){}};nglr.VisualServer=function(b,c,d){this.delegate=b;this.update=d;this.status=c};nglr.VisualServer.prototype={request:function(b,c,d,f){var e=this;this.status.beginRequest(d);this.delegate.request(b,c,d,function(){e.status.endRequest();try{f.apply(this,arguments)}catch(h){nglr.alert(nglr.toJson(h))}e.update()})}};nglr.Users=function(b,c){this.server=b;this.controlBar=c};nglr.Users.prototype={fetchCurrentUser:function(b){var c=this;this.server.request("GET","/account.json",{},function(d,f){c.current=f.user;b(f.user)})},logout:function(b){var c=this;this.controlBar.logout(function(){delete c.current;(b||nglr.noop)()})},login:function(b){var c=this;this.controlBar.login(function(){c.fetchCurrentUser(function(){(b||nglr.noop)()})})},notAuthorized:function(){this.controlBar.notAuthorized()}};angular.validator.regexp=function(b,c,d){return b.match(c)?null:d||"Value does not match expected format "+c+"."};angular.validator.number=function(b,c,d){var f=1*b;if(f==b){if(typeof c!="undefined"&&f<c)return"Value can not be less than "+c+".";if(typeof c!="undefined"&&f>d)return"Value can not be greater than "+d+".";return null}else return"Value is not a number."}; -angular.validator.integer=function(b,c,d){c=angular.validator.number(b,c,d);if(c===null&&b!=Math.round(b))return"Value is not a whole number.";return c};angular.validator.date=function(b){if(b.match(/^\d\d?\/\d\d?\/\d\d\d\d$/))return null;return"Value is not a date. (Expecting format: 12/31/2009)."};angular.validator.ssn=function(b){if(b.match(/^\d\d\d-\d\d-\d\d\d\d$/))return null;return"SSN needs to be in 999-99-9999 format."}; -angular.validator.email=function(b){if(b.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/))return null;return"Email needs to be in username@host.com format."};angular.validator.phone=function(b){if(b.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/))return null;if(b.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/))return null;return"Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly."}; -angular.validator.url=function(b){if(b.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/))return null;return"URL needs to be in http://server[:port]/path format."};angular.validator.json=function(b){try{nglr.fromJson(b);return null}catch(c){return c.toString()}};nglr.WidgetFactory=function(b,c){this.nextUploadId=0;this.serverUrl=b;this.database=c;this.createSWF=swfobject.createSWF;this.onChangeListener=function(){}}; -nglr.WidgetFactory.prototype.createController=function(b,c){var d,f=b.attr("type").toLowerCase(),e=b.attr("name");if(e)e=e.split(":").pop();var h="change",j=true;if(f=="button"||f=="submit"||f=="reset"||f=="image"){d=new nglr.ButtonController(b[0],e);h="click";j=false}else if(f=="text"||f=="textarea"||f=="hidden"||f=="password"){d=new nglr.TextController(b[0],e);h="keyup change"}else if(f=="checkbox"){d=new nglr.CheckboxController(b[0],e);h="click"}else if(f=="radio"){d=new nglr.RadioController(b[0], -e);h="click"}else if(f=="select-one")d=new nglr.SelectController(b[0],e);else if(f=="select-multiple")d=new nglr.MultiSelectController(b[0],e);else if(f=="file")d=this.createFileController(b,e);else throw"Unknown type: "+f;b.data("controller",d);var l=c.get("$binder");jQuery(d.view,":input").bind(h,function(){if(d.updateModel(c)){var n=jQuery(d.view).attr("ng-action")||"";c.evalWidget(d,n)&&l.updateView(c)}return j});return d}; -nglr.WidgetFactory.prototype.createFileController=function(b){var c="__uploadWidget_"+this.nextUploadId++,d=nglr.FileController.template(c);b.after(d);c=this.createSWF({data:this.serverUrl+"/admin/ServerAPI.swf",width:"95",height:"20",align:"top",wmode:"transparent"},{flashvars:"uploadWidgetId="+c,allowScriptAccess:"always"},c);b.remove();b=new nglr.FileController(d,b[0].name,c,this.serverUrl+"/data/"+this.database);jQuery(c).data("controller",b);return b}; -nglr.WidgetFactory.prototype.createTextWidget=function(b){b=new nglr.TextController(b);b.onChange(this.onChangeListener);return b};nglr.FileController=function(b,c,d,f){this.view=b;this.uploader=d;this.scopeName=c;this.attachmentsPath=f+"/_attachments";this.value=null;this.lastValue=undefined};nglr.FileController.dispatchEvent=function(b,c,d){b=document.getElementById(b);b=jQuery(b).data("controller");nglr.FileController.prototype["_on_"+c].apply(b,d)}; -nglr.FileController.template=function(b){return jQuery('<span class="ng-upload-widget"><input type="checkbox" ng-non-bindable="true"/><object id="'+b+'" /><a></a><span/></span>')};a=nglr.FileController.prototype;a._on_cancel=function(){};a._on_complete=function(){};a._on_httpStatus=function(b){nglr.alert("httpStatus:"+this.scopeName+" status:"+b)};a._on_ioError=function(){nglr.alert("ioError:"+this.scopeName)};a._on_open=function(){nglr.alert("open:"+this.scopeName)};a._on_progress=function(){}; -a._on_securityError=function(){nglr.alert("securityError:"+this.scopeName)};a._on_uploadCompleteData=function(b){b=nglr.fromJson(b);b.url=this.attachmentsPath+"/"+b.id+"/"+b.text;this.view.find("input").attr("checked",true);var c=this.view.scope();this.value=b;this.updateModel(c);this.value=null;c.get("$binder").updateView()};a._on_select=function(b,c){this.name=b;this.view.find("a").text(b).attr("href",b);this.view.find("span").text(angular.filter.bytes(c));this.upload()}; -a.updateModel=function(b){var c=this.view.find("input").attr("checked")?this.value:null;if(this.lastValue===c)return false;else{b.set(this.scopeName,c);return true}};a.updateView=function(b){if((b=b.get(this.scopeName))&&this.value!==b){this.value=b;this.view.find("a").attr("href",this.value.url).text(this.value.text);this.view.find("span").text(angular.filter.bytes(this.value.size))}this.view.find("input").attr("checked",!!b)};a.upload=function(){this.name&&this.uploader.uploadFile(this.attachmentsPath)}; -nglr.NullController=function(b){this.view=b};nglr.NullController.prototype.updateModel=function(){return true};nglr.NullController.prototype.updateView=function(){};nglr.NullController.instance=new nglr.NullController;nglr.ButtonController=function(b){this.view=b};nglr.ButtonController.prototype.updateModel=function(){return true};nglr.ButtonController.prototype.updateView=function(){}; -nglr.TextController=function(b,c){this.view=b;this.exp=c;this.validator=b.getAttribute("ng-validate");this.required=typeof b.attributes["ng-required"]!="undefined";this.lastErrorText=null;this.lastValue=undefined;this.initialValue=b.value;b.getAttribute("ng-widget")==="datepicker"&&jQuery(b).datepicker()};nglr.TextController.prototype.updateModel=function(b){var c=this.view.value;if(this.lastValue===c)return false;else{b.setEval(this.exp,c);this.lastValue=c;return true}}; -nglr.TextController.prototype.updateView=function(b){var c=this.view,d=b.get(this.exp);if(typeof d==="undefined"){d=this.initialValue;b.setEval(this.exp,d)}d=d?d:"";if(this.lastValue!=d)this.lastValue=c.value=d;var f=false;c.removeAttribute("ng-error");if(this.required)f=!(d&&d.length>0);var e=f?"Required Value":null;if(!f&&this.validator&&d){e=b.validate(this.validator,d);f=!!e}if(this.lastErrorText!==e){this.lastErrorText=f;if(e!==null){c.setAttribute("ng-error",e);b.markInvalid(this)}jQuery(c).toggleClass("ng-validation-error", -f)}};nglr.CheckboxController=function(b,c){this.view=b;this.exp=c;this.lastValue=undefined;this.initialValue=b.checked?b.value:""};nglr.CheckboxController.prototype.updateModel=function(b){var c=this.view;c=c.checked?c.value:"";if(this.lastValue===c)return false;else{b.setEval(this.exp,c);this.lastValue=c;return true}}; -nglr.CheckboxController.prototype.updateView=function(b){var c=this.view,d=b.eval(this.exp);if(typeof d==="undefined"){d=this.initialValue;b.setEval(this.exp,d)}c.checked=c.value==""+d};nglr.SelectController=function(b,c){this.view=b;this.exp=c;this.lastValue=undefined;this.initialValue=b.value}; -nglr.SelectController.prototype.updateModel=function(b){if(this.view.selectedIndex<0)b.setEval(this.exp,null);else{var c=this.view.value;if(this.lastValue===c)return false;else{b.setEval(this.exp,c);this.lastValue=c;return true}}};nglr.SelectController.prototype.updateView=function(b){var c=this.view,d=b.get(this.exp);if(typeof d==="undefined"){d=this.initialValue;b.setEval(this.exp,d)}if(d!==this.lastValue){c.value=d?d:"";this.lastValue=d}}; -nglr.MultiSelectController=function(b,c){this.view=b;this.exp=c;this.lastValue=undefined;this.initialValue=this.selected()};nglr.MultiSelectController.prototype.selected=function(){for(var b=[],c=this.view.options,d=0;d<c.length;d++){var f=c[d];f.selected&&b.push(f.value)}return b};nglr.MultiSelectController.prototype.updateModel=function(b){var c=this.selected();if(this.lastValue===c)return false;else{b.setEval(this.exp,c);this.lastValue=c;return true}}; -nglr.MultiSelectController.prototype.updateView=function(b){var c=this.view,d=b.get(this.exp);if(typeof d==="undefined"){d=this.initialValue;b.setEval(this.exp,d)}if(d!==this.lastValue){b=c.options;for(c=0;c<b.length;c++){var f=b[c];f.selected=_.include(d,f.value)}this.lastValue=d}};nglr.RadioController=function(b,c){this.view=b;this.exp=c;this.lastValue=this.lastChecked=undefined;this.inputValue=b.value;this.initialValue=b.checked?b.value:null}; -nglr.RadioController.prototype.updateModel=function(b){var c=this.view;if(this.lastChecked)return false;else{c.checked=true;this.lastValue=b.setEval(this.exp,this.inputValue);return this.lastChecked=true}};nglr.RadioController.prototype.updateView=function(b){var c=this.view,d=b.get(this.exp);if(this.initialValue&&typeof d==="undefined"){d=this.initialValue;b.setEval(this.exp,d)}if(this.lastValue!=d){this.lastChecked=c.checked=this.inputValue==""+d;this.lastValue=d}}; -nglr.BindUpdater=function(b,c){this.view=b;this.exp=nglr.Binder.parseBindings(c);this.hasError=false;this.scopeSelf={element:b}}; -nglr.BindUpdater.toText=function(b){var c=nglr.escapeHtml;switch(typeof b){case "string":case "boolean":case "number":return c(b);case "function":return nglr.BindUpdater.toText(b());case "object":if(nglr.isNode(b))return nglr.outerHTML(b);else if(b instanceof angular.filter.Meta){switch(typeof b.html){case "string":case "number":return b.html;case "function":return b.html();case "object":if(nglr.isNode(b.html))return nglr.outerHTML(b.html);default:break}switch(typeof b.text){case "string":case "number":return c(b.text); -case "function":return c(b.text());default:break}}if(b===null)return"";return c(nglr.toJson(b,true));default:return""}};nglr.BindUpdater.prototype.updateModel=function(){}; -nglr.BindUpdater.prototype.updateView=function(b){for(var c=[],d=this.exp,f=d.length,e=0;e<f;e++){var h=d[e],j=nglr.Binder.binding(h);if(j){b.evalWidget(this,j,this.scopeSelf,function(l){c.push(nglr.BindUpdater.toText(l))},function(l,n){nglr.setHtml(this.view,n)});if(this.hasError)return}else c.push(nglr.escapeHtml(h))}nglr.setHtml(this.view,c.join(""))};nglr.BindAttrUpdater=function(b,c){this.view=b;this.attrs=c};nglr.BindAttrUpdater.prototype.updateModel=function(){}; -nglr.BindAttrUpdater.prototype.updateView=function(b){var c=jQuery(this.view),d=this.attrs;if(this.hasError){this.hasError=false;c.removeClass("ng-exception").removeAttr("ng-error")}var f=c.is("img");for(var e in d){for(var h=nglr.Binder.parseBindings(d[e]),j=[],l=0;l<h.length;l++){var n=nglr.Binder.binding(h[l]);if(n)try{var o=b.eval(n,{element:c[0],attrName:e});if(o&&(o.constructor!==nglr.array||o.length!==0))j.push(o)}catch(p){this.hasError=true;console.error("BindAttrUpdater",p);n=nglr.toJson(p, -true);j.push("["+n+"]");c.addClass("ng-exception").attr("ng-error",n)}else j.push(h[l])}h=j.length?j.join(""):null;if(f&&e=="src"&&!h)h=b.get("config.server")+"/images/blank.gif";c.attr(e,h)}};nglr.EvalUpdater=function(b,c){this.view=b;this.exp=c;this.hasError=false};nglr.EvalUpdater.prototype.updateModel=function(){};nglr.EvalUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp)};nglr.HideUpdater=function(b,c){this.view=b;this.exp=c};nglr.HideUpdater.prototype.updateModel=function(){}; -nglr.HideUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp,{},function(c){var d=jQuery(this.view);nglr.toBoolean(c)?d.hide():d.show()})};nglr.ShowUpdater=function(b,c){this.view=b;this.exp=c};nglr.ShowUpdater.prototype.updateModel=function(){};nglr.ShowUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp,{},function(c){var d=jQuery(this.view);nglr.toBoolean(c)?d.show():d.hide()})};nglr.ClassUpdater=function(b,c){this.view=b;this.exp=c}; -nglr.ClassUpdater.prototype.updateModel=function(){};nglr.ClassUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp,{},function(c){if(c!==null&&c!==undefined)this.view.className=c})};nglr.ClassEvenUpdater=function(b,c){this.view=b;this.exp=c};nglr.ClassEvenUpdater.prototype.updateModel=function(){};nglr.ClassEvenUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp,{},function(c){var d=b.get("$index");jQuery(this.view).toggleClass(c,d%2===1)})}; -nglr.ClassOddUpdater=function(b,c){this.view=b;this.exp=c};nglr.ClassOddUpdater.prototype.updateModel=function(){};nglr.ClassOddUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp,{},function(c){var d=b.get("$index");jQuery(this.view).toggleClass(c,d%2===0)})};nglr.StyleUpdater=function(b,c){this.view=b;this.exp=c};nglr.StyleUpdater.prototype.updateModel=function(){}; -nglr.StyleUpdater.prototype.updateView=function(b){b.evalWidget(this,this.exp,{},function(c){jQuery(this.view).attr("style","").css(c)})}; -nglr.RepeaterUpdater=function(b,c,d,f){this.view=b;this.template=d;this.prefix=f;this.children=[];b=c.match(/^\s*(.+)\s+in\s+(.*)\s*$/);if(!b)throw"Expected ng-repeat in form of 'item in collection' but got '"+c+"'.";c=b[1];this.iteratorExp=b[2];b=c.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/);if(!b)throw"'item' in 'item in collection' should be identifier or (key, value) but get '"+c+"'.";this.valueExp=b[3]||b[1];this.keyExp=b[2]};nglr.RepeaterUpdater.prototype.updateModel=function(){}; -nglr.RepeaterUpdater.prototype.updateView=function(b){b.evalWidget(this,this.iteratorExp,{},function(c){var d=this;if(!c){c=[];b.isProperty(this.iteratorExp)&&b.set(this.iteratorExp,c)}var f=c.length,e=this.children.length,h=this.view,j=0,l=null,n=this.keyExp,o=this.valueExp,p=0;jQuery.each(c,function(s,v){if(p<e){l=d.children[p];l.scope.set(o,v)}else{var u=new nglr.Scope(b.state,d.prefix+o+" in "+d.iteratorExp+"["+p+"]");u.set("$index",p);n&&u.set(n,s);u.set(o,v);l={scope:u,element:d.template(u, -d.prefix,p)};h.after(l.element);d.children.push(l)}h=l.element;s=(new Date).getTime();l.scope.updateView();j+=(new Date).getTime()-s;p++});for(c=e;c>f;--c)this.children.pop().element.removeNode();if(l&&l.element[0].nodeName==="OPTION")if(f=jQuery(l.element[0].parentNode).data("controller")){f.lastValue=undefined;f.updateView(b)}})};nglr.PopUp=function(b){this.doc=b};nglr.PopUp.OUT_EVENT="mouseleave mouseout click dblclick keypress keyup"; -nglr.PopUp.prototype.bind=function(){this.doc.find(".ng-validation-error,.ng-exception").live("mouseover",nglr.PopUp.onOver)}; -nglr.PopUp.onOver=function(){nglr.PopUp.onOut();var b=jQuery(this);b.bind(nglr.PopUp.OUT_EVENT,nglr.PopUp.onOut);var c=b.position(),d=document.documentElement,f=(self.innerWidth||d&&d.clientWidth||document.body.clientWidth)-c.left;d=b.hasClass("ng-exception")?"EXCEPTION:":"Validation error...";b=b.attr("ng-error");f=f>375?"left":"right";d=jQuery("<div id='ng-callout' style='width:300px'><div class='ng-arrow-"+f+"'/><div class='ng-title'>"+d+"</div><div class='ng-content'>"+b+"</div></div>");jQuery("body").append(d); -if(f==="left")b=c.left+this.offsetWidth+11;else{b=c.left-315;d.find(".ng-arrow-right").css({left:301})}d.css({left:b+"px",top:c.top-3+"px"});return true};nglr.PopUp.onOut=function(){jQuery("#ng-callout").unbind(nglr.PopUp.OUT_EVENT,nglr.PopUp.onOut).remove();return true};nglr.Status=function(b){this.loader=b.append(nglr.Status.DOM).find("#ng-loading");this.requestCount=0};nglr.Status.DOM='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>'; -nglr.Status.prototype.beginRequest=function(){this.requestCount===0&&this.loader.show();this.requestCount++};nglr.Status.prototype.endRequest=function(){this.requestCount--;this.requestCount===0&&this.loader.hide("fold")};(function(b){for(var c=/(.*)\/angular-(.*).js(#(.*))?/,d=document.getElementsByTagName("script"),f={autoSubmit:true,autoBind:true,autoLoadDependencies:false},e=0;e<d.length;e++){var h=d[e].src;if(h&&h.match(c)){h=h.match(c);if(h[2]=="bootstrap")f.autoLoadDependencies=true;f.server=h[1]||"";if(!f.server)f.server=window.location.toString().split(window.location.pathname)[0];if(h[4]){h=h[4].split("&");for(var j=0;j<h.length;j++){var l=h[j].split("="),n=l[0];l=l.length==1?true:l[1];if(l=="false")l=false; -if(l=="true")l=true;f[n]=l}}}}c=function(o,p){p=p||f.server;document.write('<script type="text/javascript" src="'+p+o+'"><\/script>')};if(f.autoLoadDependencies){c("/../lib/webtoolkit/webtoolkit.base64.js");c("/../lib/swfobject/swfobject.js");c("/../lib/jquery/jquery-1.3.2.js");c("/../lib/jquery/jquery-ui-1.7.1.custom.min.js");c("/../lib/underscore/underscore.js");c("/Loader.js");c("/API.js");c("/Binder.js");c("/ControlBar.js");c("/DataStore.js");c("/Filters.js");c("/JSON.js");c("/Model.js");c("/Parser.js"); -c("/Scope.js");c("/Server.js");c("/Users.js");c("/Validators.js");c("/Widgets.js")}else{c("/ajax/libs/swfobject/2.2/swfobject.js","http://ajax.googleapis.com");c("/ajax/libs/jquery/1.3.2/jquery.min.js","http://ajax.googleapis.com");c("/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js","http://ajax.googleapis.com")}window.onload=function(){var o=window.document;if(f.bindRootId){o=null;for(var p=f.bindRootId.split("|"),s=0;s<p.length&&!o;s++){var v=p[s].split("?"),u=v[0];if(v.length>1)if(!window.document.getElementById(v[1]))continue; -o=window.document.getElementById(u)}}p=window.angularFactory(f);if(f.autoBind&&o)window.angularScope=p.compile(o);if(typeof b==="function")try{b.apply(this,arguments)}catch(w){}}})(window.onload); +// Underscore.js +// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the terms of the MIT license. +// Portions of Underscore are inspired by or borrowed from Prototype.js, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore/ + +(function() { + +  /*------------------------- Baseline setup ---------------------------------*/ + +  // Establish the root object, "window" in the browser, or "global" on the server. +  var root = this; + +  // Save the previous value of the "_" variable. +  var previousUnderscore = root._; + +  // If Underscore is called as a function, it returns a wrapped object that +  // can be used OO-style. This wrapper holds altered versions of all the +  // underscore functions. Wrapped objects may be chained. +  var wrapper = function(obj) { this._wrapped = obj; }; + +  // Establish the object that gets thrown to break out of a loop iteration. +  var breaker = typeof StopIteration !== 'undefined' ? StopIteration : '__break__'; + +  // Create a safe reference to the Underscore object for reference below. +  var _ = root._ = function(obj) { return new wrapper(obj); }; + +  // Export the Underscore object for CommonJS. +  if (typeof exports !== 'undefined') exports._ = _; + +  // Create quick reference variables for speed access to core prototypes. +  var slice                 = Array.prototype.slice, +      unshift               = Array.prototype.unshift, +      toString              = Object.prototype.toString, +      hasOwnProperty        = Object.prototype.hasOwnProperty, +      propertyIsEnumerable  = Object.prototype.propertyIsEnumerable; + +  // Current version. +  _.VERSION = '0.5.1'; + +  /*------------------------ Collection Functions: ---------------------------*/ + +  // The cornerstone, an each implementation. +  // Handles objects implementing forEach, arrays, and raw objects. +  _.each = function(obj, iterator, context) { +    var index = 0; +    try { +      if (obj.forEach) { +        obj.forEach(iterator, context); +      } else if (_.isArray(obj) || _.isArguments(obj)) { +        for (var i=0, l=obj.length; i<l; i++) iterator.call(context, obj[i], i, obj); +      } else { +        var keys = _.keys(obj), l = keys.length; +        for (var i=0; i<l; i++) iterator.call(context, obj[keys[i]], keys[i], obj); +      } +    } catch(e) { +      if (e != breaker) throw e; +    } +    return obj; +  }; + +  // Return the results of applying the iterator to each element. Use JavaScript +  // 1.6's version of map, if possible. +  _.map = function(obj, iterator, context) { +    if (obj && _.isFunction(obj.map)) return obj.map(iterator, context); +    var results = []; +    _.each(obj, function(value, index, list) { +      results.push(iterator.call(context, value, index, list)); +    }); +    return results; +  }; + +  // Reduce builds up a single result from a list of values. Also known as +  // inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible. +  _.reduce = function(obj, memo, iterator, context) { +    if (obj && _.isFunction(obj.reduce)) return obj.reduce(_.bind(iterator, context), memo); +    _.each(obj, function(value, index, list) { +      memo = iterator.call(context, memo, value, index, list); +    }); +    return memo; +  }; + +  // The right-associative version of reduce, also known as foldr. Uses +  // JavaScript 1.8's version of reduceRight, if available. +  _.reduceRight = function(obj, memo, iterator, context) { +    if (obj && _.isFunction(obj.reduceRight)) return obj.reduceRight(_.bind(iterator, context), memo); +    var reversed = _.clone(_.toArray(obj)).reverse(); +    _.each(reversed, function(value, index) { +      memo = iterator.call(context, memo, value, index, obj); +    }); +    return memo; +  }; + +  // Return the first value which passes a truth test. +  _.detect = function(obj, iterator, context) { +    var result; +    _.each(obj, function(value, index, list) { +      if (iterator.call(context, value, index, list)) { +        result = value; +        _.breakLoop(); +      } +    }); +    return result; +  }; + +  // Return all the elements that pass a truth test. Use JavaScript 1.6's +  // filter(), if it exists. +  _.select = function(obj, iterator, context) { +    if (obj && _.isFunction(obj.filter)) return obj.filter(iterator, context); +    var results = []; +    _.each(obj, function(value, index, list) { +      iterator.call(context, value, index, list) && results.push(value); +    }); +    return results; +  }; + +  // Return all the elements for which a truth test fails. +  _.reject = function(obj, iterator, context) { +    var results = []; +    _.each(obj, function(value, index, list) { +      !iterator.call(context, value, index, list) && results.push(value); +    }); +    return results; +  }; + +  // Determine whether all of the elements match a truth test. Delegate to +  // JavaScript 1.6's every(), if it is present. +  _.all = function(obj, iterator, context) { +    iterator = iterator || _.identity; +    if (obj && _.isFunction(obj.every)) return obj.every(iterator, context); +    var result = true; +    _.each(obj, function(value, index, list) { +      if (!(result = result && iterator.call(context, value, index, list))) _.breakLoop(); +    }); +    return result; +  }; + +  // Determine if at least one element in the object matches a truth test. Use +  // JavaScript 1.6's some(), if it exists. +  _.any = function(obj, iterator, context) { +    iterator = iterator || _.identity; +    if (obj && _.isFunction(obj.some)) return obj.some(iterator, context); +    var result = false; +    _.each(obj, function(value, index, list) { +      if (result = iterator.call(context, value, index, list)) _.breakLoop(); +    }); +    return result; +  }; + +  // Determine if a given value is included in the array or object, +  // based on '==='. +  _.include = function(obj, target) { +    if (_.isArray(obj)) return _.indexOf(obj, target) != -1; +    var found = false; +    _.each(obj, function(value) { +      if (found = value === target) _.breakLoop(); +    }); +    return found; +  }; + +  // Invoke a method with arguments on every item in a collection. +  _.invoke = function(obj, method) { +    var args = _.rest(arguments, 2); +    return _.map(obj, function(value) { +      return (method ? value[method] : value).apply(value, args); +    }); +  }; + +  // Convenience version of a common use case of map: fetching a property. +  _.pluck = function(obj, key) { +    return _.map(obj, function(value){ return value[key]; }); +  }; + +  // Return the maximum item or (item-based computation). +  _.max = function(obj, iterator, context) { +    if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); +    var result = {computed : -Infinity}; +    _.each(obj, function(value, index, list) { +      var computed = iterator ? iterator.call(context, value, index, list) : value; +      computed >= result.computed && (result = {value : value, computed : computed}); +    }); +    return result.value; +  }; + +  // Return the minimum element (or element-based computation). +  _.min = function(obj, iterator, context) { +    if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); +    var result = {computed : Infinity}; +    _.each(obj, function(value, index, list) { +      var computed = iterator ? iterator.call(context, value, index, list) : value; +      computed < result.computed && (result = {value : value, computed : computed}); +    }); +    return result.value; +  }; + +  // Sort the object's values by a criteria produced by an iterator. +  _.sortBy = function(obj, iterator, context) { +    return _.pluck(_.map(obj, function(value, index, list) { +      return { +        value : value, +        criteria : iterator.call(context, value, index, list) +      }; +    }).sort(function(left, right) { +      var a = left.criteria, b = right.criteria; +      return a < b ? -1 : a > b ? 1 : 0; +    }), 'value'); +  }; + +  // Use a comparator function to figure out at what index an object should +  // be inserted so as to maintain order. Uses binary search. +  _.sortedIndex = function(array, obj, iterator) { +    iterator = iterator || _.identity; +    var low = 0, high = array.length; +    while (low < high) { +      var mid = (low + high) >> 1; +      iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; +    } +    return low; +  }; + +  // Convert anything iterable into a real, live array. +  _.toArray = function(iterable) { +    if (!iterable)                return []; +    if (iterable.toArray)         return iterable.toArray(); +    if (_.isArray(iterable))      return iterable; +    if (_.isArguments(iterable))  return slice.call(iterable); +    return _.map(iterable, function(val){ return val; }); +  }; + +  // Return the number of elements in an object. +  _.size = function(obj) { +    return _.toArray(obj).length; +  }; + +  /*-------------------------- Array Functions: ------------------------------*/ + +  // Get the first element of an array. Passing "n" will return the first N +  // values in the array. Aliased as "head". The "guard" check allows it to work +  // with _.map. +  _.first = function(array, n, guard) { +    return n && !guard ? slice.call(array, 0, n) : array[0]; +  }; + +  // Returns everything but the first entry of the array. Aliased as "tail". +  // Especially useful on the arguments object. Passing an "index" will return +  // the rest of the values in the array from that index onward. The "guard" +   //check allows it to work with _.map. +  _.rest = function(array, index, guard) { +    return slice.call(array, _.isUndefined(index) || guard ? 1 : index); +  }; + +  // Get the last element of an array. +  _.last = function(array) { +    return array[array.length - 1]; +  }; + +  // Trim out all falsy values from an array. +  _.compact = function(array) { +    return _.select(array, function(value){ return !!value; }); +  }; + +  // Return a completely flattened version of an array. +  _.flatten = function(array) { +    return _.reduce(array, [], function(memo, value) { +      if (_.isArray(value)) return memo.concat(_.flatten(value)); +      memo.push(value); +      return memo; +    }); +  }; + +  // Return a version of the array that does not contain the specified value(s). +  _.without = function(array) { +    var values = _.rest(arguments); +    return _.select(array, function(value){ return !_.include(values, value); }); +  }; + +  // Produce a duplicate-free version of the array. If the array has already +  // been sorted, you have the option of using a faster algorithm. +  _.uniq = function(array, isSorted) { +    return _.reduce(array, [], function(memo, el, i) { +      if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo.push(el); +      return memo; +    }); +  }; + +  // Produce an array that contains every item shared between all the +  // passed-in arrays. +  _.intersect = function(array) { +    var rest = _.rest(arguments); +    return _.select(_.uniq(array), function(item) { +      return _.all(rest, function(other) { +        return _.indexOf(other, item) >= 0; +      }); +    }); +  }; + +  // Zip together multiple lists into a single array -- elements that share +  // an index go together. +  _.zip = function() { +    var args = _.toArray(arguments); +    var length = _.max(_.pluck(args, 'length')); +    var results = new Array(length); +    for (var i=0; i<length; i++) results[i] = _.pluck(args, String(i)); +    return results; +  }; + +  // If the browser doesn't supply us with indexOf (I'm looking at you, MSIE), +  // we need this function. Return the position of the first occurence of an +  // item in an array, or -1 if the item is not included in the array. +  _.indexOf = function(array, item) { +    if (array.indexOf) return array.indexOf(item); +    for (var i=0, l=array.length; i<l; i++) if (array[i] === item) return i; +    return -1; +  }; + +  // Provide JavaScript 1.6's lastIndexOf, delegating to the native function, +  // if possible. +  _.lastIndexOf = function(array, item) { +    if (array.lastIndexOf) return array.lastIndexOf(item); +    var i = array.length; +    while (i--) if (array[i] === item) return i; +    return -1; +  }; + +  // Generate an integer Array containing an arithmetic progression. A port of +  // the native Python range() function. See: +  // http://docs.python.org/library/functions.html#range +  _.range = function(start, stop, step) { +    var a     = _.toArray(arguments); +    var solo  = a.length <= 1; +    var start = solo ? 0 : a[0], stop = solo ? a[0] : a[1], step = a[2] || 1; +    var len   = Math.ceil((stop - start) / step); +    if (len <= 0) return []; +    var range = new Array(len); +    for (var i = start, idx = 0; true; i += step) { +      if ((step > 0 ? i - stop : stop - i) >= 0) return range; +      range[idx++] = i; +    } +  }; + +  /* ----------------------- Function Functions: -----------------------------*/ + +  // Create a function bound to a given object (assigning 'this', and arguments, +  // optionally). Binding with arguments is also known as 'curry'. +  _.bind = function(func, obj) { +    var args = _.rest(arguments, 2); +    return function() { +      return func.apply(obj || root, args.concat(_.toArray(arguments))); +    }; +  }; + +  // Bind all of an object's methods to that object. Useful for ensuring that +  // all callbacks defined on an object belong to it. +  _.bindAll = function(obj) { +    var funcs = _.rest(arguments); +    if (funcs.length == 0) funcs = _.functions(obj); +    _.each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); +    return obj; +  }; + +  // Delays a function for the given number of milliseconds, and then calls +  // it with the arguments supplied. +  _.delay = function(func, wait) { +    var args = _.rest(arguments, 2); +    return setTimeout(function(){ return func.apply(func, args); }, wait); +  }; + +  // Defers a function, scheduling it to run after the current call stack has +  // cleared. +  _.defer = function(func) { +    return _.delay.apply(_, [func, 1].concat(_.rest(arguments))); +  }; + +  // Returns the first function passed as an argument to the second, +  // allowing you to adjust arguments, run code before and after, and +  // conditionally execute the original function. +  _.wrap = function(func, wrapper) { +    return function() { +      var args = [func].concat(_.toArray(arguments)); +      return wrapper.apply(wrapper, args); +    }; +  }; + +  // Returns a function that is the composition of a list of functions, each +  // consuming the return value of the function that follows. +  _.compose = function() { +    var funcs = _.toArray(arguments); +    return function() { +      var args = _.toArray(arguments); +      for (var i=funcs.length-1; i >= 0; i--) { +        args = [funcs[i].apply(this, args)]; +      } +      return args[0]; +    }; +  }; + +  /* ------------------------- Object Functions: ---------------------------- */ + +  // Retrieve the names of an object's properties. +  _.keys = function(obj) { +    if(_.isArray(obj)) return _.range(0, obj.length); +    var keys = []; +    for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key); +    return keys; +  }; + +  // Retrieve the values of an object's properties. +  _.values = function(obj) { +    return _.map(obj, _.identity); +  }; + +  // Return a sorted list of the function names available in Underscore. +  _.functions = function(obj) { +    return _.select(_.keys(obj), function(key){ return _.isFunction(obj[key]); }).sort(); +  }; + +  // Extend a given object with all of the properties in a source object. +  _.extend = function(destination, source) { +    for (var property in source) destination[property] = source[property]; +    return destination; +  }; + +  // Create a (shallow-cloned) duplicate of an object. +  _.clone = function(obj) { +    if (_.isArray(obj)) return obj.slice(0); +    return _.extend({}, obj); +  }; + +  // Perform a deep comparison to check if two objects are equal. +  _.isEqual = function(a, b) { +    // Check object identity. +    if (a === b) return true; +    // Different types? +    var atype = typeof(a), btype = typeof(b); +    if (atype != btype) return false; +    // Basic equality test (watch out for coercions). +    if (a == b) return true; +    // One is falsy and the other truthy. +    if ((!a && b) || (a && !b)) return false; +    // One of them implements an isEqual()? +    if (a.isEqual) return a.isEqual(b); +    // Check dates' integer values. +    if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime(); +    // Both are NaN? +    if (_.isNaN(a) && _.isNaN(b)) return true; +    // Compare regular expressions. +    if (_.isRegExp(a) && _.isRegExp(b)) +      return a.source     === b.source && +             a.global     === b.global && +             a.ignoreCase === b.ignoreCase && +             a.multiline  === b.multiline; +    // If a is not an object by this point, we can't handle it. +    if (atype !== 'object') return false; +    // Check for different array lengths before comparing contents. +    if (a.length && (a.length !== b.length)) return false; +    // Nothing else worked, deep compare the contents. +    var aKeys = _.keys(a), bKeys = _.keys(b); +    // Different object sizes? +    if (aKeys.length != bKeys.length) return false; +    // Recursive comparison of contents. +    for (var key in a) if (!_.isEqual(a[key], b[key])) return false; +    return true; +  }; + +  // Is a given array or object empty? +  _.isEmpty = function(obj) { +    return _.keys(obj).length == 0; +  }; + +  // Is a given value a DOM element? +  _.isElement = function(obj) { +    return !!(obj && obj.nodeType == 1); +  }; + +  // Is a given variable an arguments object? +  _.isArguments = function(obj) { +    return obj && _.isNumber(obj.length) && !_.isArray(obj) && !propertyIsEnumerable.call(obj, 'length'); +  }; + +  // Is the given value NaN -- this one is interesting. NaN != NaN, and +  // isNaN(undefined) == true, so we make sure it's a number first. +  _.isNaN = function(obj) { +    return _.isNumber(obj) && isNaN(obj); +  }; + +  // Is a given value equal to null? +  _.isNull = function(obj) { +    return obj === null; +  }; + +  // Is a given variable undefined? +  _.isUndefined = function(obj) { +    return typeof obj == 'undefined'; +  }; + +  // Define the isArray, isDate, isFunction, isNumber, isRegExp, and isString +  // functions based on their toString identifiers. +  var types = ['Array', 'Date', 'Function', 'Number', 'RegExp', 'String']; +  for (var i=0, l=types.length; i<l; i++) { +    (function() { +      var identifier = '[object ' + types[i] + ']'; +      _['is' + types[i]] = function(obj) { return toString.call(obj) == identifier; }; +    })(); +  } + +  /* -------------------------- Utility Functions: -------------------------- */ + +  // Run Underscore.js in noConflict mode, returning the '_' variable to its +  // previous owner. Returns a reference to the Underscore object. +  _.noConflict = function() { +    root._ = previousUnderscore; +    return this; +  }; + +  // Keep the identity function around for default iterators. +  _.identity = function(value) { +    return value; +  }; + +  // Break out of the middle of an iteration. +  _.breakLoop = function() { +    throw breaker; +  }; + +  // Generate a unique integer id (unique within the entire client session). +  // Useful for temporary DOM ids. +  var idCounter = 0; +  _.uniqueId = function(prefix) { +    var id = idCounter++; +    return prefix ? prefix + id : id; +  }; + +  // JavaScript templating a-la ERB, pilfered from John Resig's +  // "Secrets of the JavaScript Ninja", page 83. +  _.template = function(str, data) { +    var fn = new Function('obj', +      'var p=[],print=function(){p.push.apply(p,arguments);};' + +      'with(obj){p.push(\'' + +      str +        .replace(/[\r\t\n]/g, " ") +        .split("<%").join("\t") +        .replace(/((^|%>)[^\t]*)'/g, "$1\r") +        .replace(/\t=(.*?)%>/g, "',$1,'") +        .split("\t").join("');") +        .split("%>").join("p.push('") +        .split("\r").join("\\'") +    + "');}return p.join('');"); +    return data ? fn(data) : fn; +  }; + +  /*------------------------------- Aliases ----------------------------------*/ + +  _.forEach  = _.each; +  _.foldl    = _.inject       = _.reduce; +  _.foldr    = _.reduceRight; +  _.filter   = _.select; +  _.every    = _.all; +  _.some     = _.any; +  _.head     = _.first; +  _.tail     = _.rest; +  _.methods  = _.functions; + +  /*------------------------ Setup the OOP Wrapper: --------------------------*/ + +  // Helper function to continue chaining intermediate results. +  var result = function(obj, chain) { +    return chain ? _(obj).chain() : obj; +  }; + +  // Add all of the Underscore functions to the wrapper object. +  _.each(_.functions(_), function(name) { +    var method = _[name]; +    wrapper.prototype[name] = function() { +      unshift.call(arguments, this._wrapped); +      return result(method.apply(_, arguments), this._chain); +    }; +  }); + +  // Add all mutator Array functions to the wrapper. +  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { +    var method = Array.prototype[name]; +    wrapper.prototype[name] = function() { +      method.apply(this._wrapped, arguments); +      return result(this._wrapped, this._chain); +    }; +  }); + +  // Add all accessor Array functions to the wrapper. +  _.each(['concat', 'join', 'slice'], function(name) { +    var method = Array.prototype[name]; +    wrapper.prototype[name] = function() { +      return result(method.apply(this._wrapped, arguments), this._chain); +    }; +  }); + +  // Start chaining a wrapped Underscore object. +  wrapper.prototype.chain = function() { +    this._chain = true; +    return this; +  }; + +  // Extracts the result from a wrapped and chained object. +  wrapper.prototype.value = function() { +    return this._wrapped; +  }; + +})(); + +(function(window, document){/** +* +*  Base64 encode / decode +*  http://www.webtoolkit.info/ +* +**/ + +var Base64 = { + +	// private property +	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=", + +	// public method for encoding +	encode : function (input) { +		var output = ""; +		var chr1, chr2, chr3, enc1, enc2, enc3, enc4; +		var i = 0; + +		input = Base64._utf8_encode(input); + +		while (i < input.length) { + +			chr1 = input.charCodeAt(i++); +			chr2 = input.charCodeAt(i++); +			chr3 = input.charCodeAt(i++); + +			enc1 = chr1 >> 2; +			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); +			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); +			enc4 = chr3 & 63; + +			if (isNaN(chr2)) { +				enc3 = enc4 = 64; +			} else if (isNaN(chr3)) { +				enc4 = 64; +			} + +			output = output + +			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + +			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + +		} + +		return output; +	}, + +	// public method for decoding +	decode : function (input) { +		var output = ""; +		var chr1, chr2, chr3; +		var enc1, enc2, enc3, enc4; +		var i = 0; + +		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + +		while (i < input.length) { + +			enc1 = this._keyStr.indexOf(input.charAt(i++)); +			enc2 = this._keyStr.indexOf(input.charAt(i++)); +			enc3 = this._keyStr.indexOf(input.charAt(i++)); +			enc4 = this._keyStr.indexOf(input.charAt(i++)); + +			chr1 = (enc1 << 2) | (enc2 >> 4); +			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); +			chr3 = ((enc3 & 3) << 6) | enc4; + +			output = output + String.fromCharCode(chr1); + +			if (enc3 != 64) { +				output = output + String.fromCharCode(chr2); +			} +			if (enc4 != 64) { +				output = output + String.fromCharCode(chr3); +			} + +		} + +		output = Base64._utf8_decode(output); + +		return output; + +	}, + +	// private method for UTF-8 encoding +	_utf8_encode : function (string) { +		string = string.replace(/\r\n/g,"\n"); +		var utftext = ""; + +		for (var n = 0; n < string.length; n++) { + +			var c = string.charCodeAt(n); + +			if (c < 128) { +				utftext += String.fromCharCode(c); +			} +			else if((c > 127) && (c < 2048)) { +				utftext += String.fromCharCode((c >> 6) | 192); +				utftext += String.fromCharCode((c & 63) | 128); +			} +			else { +				utftext += String.fromCharCode((c >> 12) | 224); +				utftext += String.fromCharCode(((c >> 6) & 63) | 128); +				utftext += String.fromCharCode((c & 63) | 128); +			} + +		} + +		return utftext; +	}, + +	// private method for UTF-8 decoding +	_utf8_decode : function (utftext) { +		var string = ""; +		var i = 0; +		var c = c1 = c2 = 0; + +		while ( i < utftext.length ) { + +			c = utftext.charCodeAt(i); + +			if (c < 128) { +				string += String.fromCharCode(c); +				i++; +			} +			else if((c > 191) && (c < 224)) { +				c2 = utftext.charCodeAt(i+1); +				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); +				i += 2; +			} +			else { +				c2 = utftext.charCodeAt(i+1); +				c3 = utftext.charCodeAt(i+2); +				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); +				i += 3; +			} + +		} + +		return string; +	} + +};// Copyright (C) 2008,2009 BRAT Tech LLC + +// IE compatibility + +if (typeof document.getAttribute == 'undefined') +  document.getAttribute = function() { +  }; +if (typeof Node == 'undefined') { +  Node = { +    ELEMENT_NODE : 1, +    ATTRIBUTE_NODE : 2, +    TEXT_NODE : 3, +    CDATA_SECTION_NODE : 4, +    ENTITY_REFERENCE_NODE : 5, +    ENTITY_NODE : 6, +    PROCESSING_INSTRUCTION_NODE : 7, +    COMMENT_NODE : 8, +    DOCUMENT_NODE : 9, +    DOCUMENT_TYPE_NODE : 10, +    DOCUMENT_FRAGMENT_NODE : 11, +    NOTATION_NODE : 12 +  }; +} + +if (_.isUndefined(window.nglr))       nglr = {}; +if (_.isUndefined(window.angular))    angular = {}; +if (_.isUndefined(angular.validator)) angular.validator = {}; +if (_.isUndefined(angular.filter))    angular.filter = {}; +if (_.isUndefined(window.console)) +  window.console = { +    log:function() {}, +    error:function() {} +  }; +if (_.isUndefined(alert)) { +  alert = function(){console.log(arguments); window.alert.apply(window, arguments); }; +} + +consoleLog = function(level, objs) { +  var log = document.createElement("div"); +  log.className = level; +  var msg = ""; +  var sep = ""; +  for ( var i = 0; i < objs.length; i++) { +    var obj = objs[i]; +    msg += sep + (typeof obj == 'string' ? obj : toJson(obj)); +    sep = " "; +  } +  log.appendChild(document.createTextNode(msg)); +  consoleNode.appendChild(log); +}; + +isNode = function(inp) { +  return inp && +      inp.tagName && +      inp.nodeName && +      inp.ownerDocument && +      inp.removeAttribute; +}; + +isLeafNode = function(node) { +  switch (node.nodeName) { +  case "OPTION": +  case "PRE": +  case "TITLE": +    return true; +  default: +    return false; +  } +}; + +noop = function() { +}; +setHtml = function(node, html) { +  if (isLeafNode(node)) { +    if (msie) { +      node.innerText = html; +    } else { +      node.textContent = html; +    } +  } else { +    node.innerHTML = html; +  } +}; + +escapeHtml = function(html) { +  if (!html || !html.replace) +    return html; +  return html. +      replace(/&/g, '&'). +      replace(/</g, '<'). +      replace(/>/g, '>'); +}; + +escapeAttr = function(html) { +  if (!html || !html.replace) +    return html; +  return html.replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, +      '"'); +}; + +bind = function(_this, _function) { +  if (!_this) +    throw "Missing this"; +  if (!_.isFunction(_function)) +    throw "Missing function"; +  return function() { +    return _function.apply(_this, arguments); +  }; +}; + +shiftBind = function(_this, _function) { +  return function() { +    var args = [ this ]; +    for ( var i = 0; i < arguments.length; i++) { +      args.push(arguments[i]); +    } +    return _function.apply(_this, args); +  }; +}; + +outerHTML = function(node) { +  var temp = document.createElement('div'); +  temp.appendChild(node); +  var outerHTML = temp.innerHTML; +  temp.removeChild(node); +  return outerHTML; +}; + +trim = function(str) { +  return str.replace(/^ */, '').replace(/ *$/, ''); +}; + +toBoolean = function(value) { +  var v = ("" + value).toLowerCase(); +  if (v == 'f' || v == '0' || v == 'false' || v == 'no') +    value = false; +  return !!value; +}; + +merge = function(src, dst) { +  for ( var key in src) { +    var value = dst[key]; +    var type = typeof value; +    if (type == 'undefined') { +      dst[key] = fromJson(toJson(src[key])); +    } else if (type == 'object' && value.constructor != array && +        key.substring(0, 1) != "$") { +      merge(src[key], value); +    } +  } +}; + +// //////////////////////////// +// Loader +// //////////////////////////// + +Loader = function(document, head, config) { +  this.document = jQuery(document); +  this.head = jQuery(head); +  this.config = config; +  this.location = window.location; +}; + +Loader.prototype.load = function() { +  this.configureLogging(); +  this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css'); +  this.loadCss('/stylesheets/css'); +  console.log("Server: " + this.config.server); +  msie = jQuery.browser.msie; +  this.configureJQueryPlugins(); +  this.computeConfiguration(); +  this.bindHtml(); +}; + +Loader.prototype.configureJQueryPlugins = function() { +  console.log('Loader.configureJQueryPlugins()'); +  jQuery.fn.removeNode = function() { +    var node = this.get(0); +    node.parentNode.removeChild(node); +  }; +  jQuery.fn.scope = function() { +    var element = this; +    while (element && element.get(0)) { +      var scope = element.data("scope"); +      if (scope) +        return scope; +      element = element.parent(); +    } +    return null; +  }; +  jQuery.fn.controller = function() { +    return this.data('controller') || NullController.instance; +  }; +}; + +Loader.prototype.uid = function() { +  return "" + new Date().getTime(); +}; + +Loader.prototype.computeConfiguration = function() { +  var config = this.config; +  if (!config.database) { +    var match = config.server.match(/https?:\/\/([\w]*)/); +    config.database = match ? match[1] : "$MEMORY"; +  } +}; + +Loader.prototype.bindHtml = function() { +  console.log('Loader.bindHtml()'); +  var watcher = new UrlWatcher(this.location); +  var document = this.document; +  var widgetFactory = new WidgetFactory(this.config.server, this.config.database); +  var binder = new Binder(document[0], widgetFactory, watcher, this.config); +  widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel); +  var controlBar = new ControlBar(document.find('body'), this.config.server); +  var onUpdate = function(){binder.updateView();}; +  var server = this.config.database=="$MEMORY" ? +      new FrameServer(this.window) : +      new Server(this.config.server, jQuery.getScript); +  server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate); +  var users = new Users(server, controlBar); +  var databasePath = '/data/' + this.config.database; +  var post = function(request, callback){ +    server.request("POST", databasePath, request, callback); +  }; +  var datastore = new DataStore(post, users, binder.anchor); +  binder.updateListeners.push(function(){datastore.flush();}); +  var scope = new Scope( { +    $anchor : binder.anchor, +    $binder : binder, +    $config : this.config, +    $console : window.console, +    $datastore : datastore, +    $save : function(callback) { +      datastore.saveScope(scope.state, callback, binder.anchor); +    }, +    $window : window, +    $uid : this.uid, +    $users : users +  }, "ROOT"); + +  jQuery.each(["get", "set", "eval", "addWatchListener", "updateView"], +    function(i, method){ +      angular[method] = bind(scope, scope[method]); +    }); + +  document.data('scope', scope); +  console.log('$binder.entity()'); +  binder.entity(scope); + +  console.log('$binder.compile()'); +  binder.compile(); + +  console.log('ControlBar.bind()'); +  controlBar.bind(); + +  console.log('$users.fetchCurrentUser()'); +  function fetchCurrentUser() { +    users.fetchCurrentUser(function(u) { +      if (!u && document.find("[ng-auth=eager]").length) { +        users.login(); +      } +    }); +  } +  fetchCurrentUser(); + +  console.log('PopUp.bind()'); +  new PopUp(document).bind(); + +  console.log('$binder.parseAnchor()'); +  binder.parseAnchor(); + +  console.log('$binder.executeInit()'); +  binder.executeInit(); + +  console.log('$binder.updateView()'); +  binder.updateView(); + +  watcher.listener = bind(binder, binder.onUrlChange, watcher); +  watcher.onUpdate = function(){alert("update");}; +  watcher.watch(); +  document.find("body").show(); +  console.log('ready()'); + +}; + +Loader.prototype.visualPost = function(delegate) { +  var status = new Status(jQuery(document.body)); +  return function(request, delegateCallback) { +    status.beginRequest(request); +    var callback = function() { +      status.endRequest(); +      try { +        delegateCallback.apply(this, arguments); +      } catch (e) { +        alert(toJson(e)); +      } +    }; +    delegate(request, callback); +  }; +}; + +Loader.prototype.configureLogging = function() { +  var url = window.location.href + '#'; +  url = url.split('#')[1]; +  var config = { +    debug : null +  }; +  var configs = url.split('&'); +  for ( var i = 0; i < configs.length; i++) { +    var part = (configs[i] + '=').split('='); +    config[part[0]] = part[1]; +  } +  if (config.debug == 'console') { +    consoleNode = document.createElement("div"); +    consoleNode.id = 'ng-console'; +    document.getElementsByTagName('body')[0].appendChild(consoleNode); +    console.log = function() { +      consoleLog('ng-console-info', arguments); +    }; +    console.error = function() { +      consoleLog('ng-console-error', arguments); +    }; +  } +}; + +Loader.prototype.loadCss = function(css) { +  var cssTag = document.createElement('link'); +  cssTag.rel = "stylesheet"; +  cssTag.type = "text/css"; +  if (!css.match(/^http:/)) +    css = this.config.server + css; +  cssTag.href = css; +  this.head[0].appendChild(cssTag); +}; + +UrlWatcher = function(location) { +  this.location = location; +  this.delay = 25; +  this.setTimeout = function(fn, delay) { +    window.setTimeout(fn, delay); +  }; +  this.listener = function(url) { +    return url; +  }; +  this.expectedUrl = location.href; +}; + +UrlWatcher.prototype.watch = function() { +  var self = this; +  var pull = function() { +    if (self.expectedUrl !== self.location.href) { +      var notify = self.location.hash.match(/^#\$iframe_notify=(.*)$/); +      if (notify) { +        if (!self.expectedUrl.match(/#/)) { +          self.expectedUrl += "#"; +        } +        self.location.href = self.expectedUrl; +        var id = '_iframe_notify_' + notify[1]; +        var notifyFn = nglr[id]; +        delete nglr[id]; +        try { +          (notifyFn||noop)(); +        } catch (e) { +          alert(e); +        } +      } else { +        self.listener(self.location.href); +        self.expectedUrl = self.location.href; +      } +    } +    self.setTimeout(pull, self.delay); +  }; +  pull(); +}; + +UrlWatcher.prototype.setUrl = function(url) { +  var existingURL = window.location.href; +  if (!existingURL.match(/#/)) +    existingURL += '#'; +  if (existingURL != url) +    window.location.href = url; +  self.existingURL = url; +}; + +UrlWatcher.prototype.getUrl = function() { +  return window.location.href; +}; + +angular['compile'] = function(root, config) { +  config = config || {}; +  var defaults = { +    server: "" +  }; +  //todo: don't load stylesheet by default +  //todo: don't start watcher +  var loader = new Loader(root, jQuery("head"), _(defaults).extend(config)); +  loader.load(); +  return jQuery(root).scope(); +}; + +angular.Global = { +  typeOf:function(obj){ +    var type = typeof obj; +    switch(type) { +    case "object": +      if (obj === null) return "null"; +      if (obj instanceof Array) return "array"; +      if (obj instanceof Date) return "date"; +      if (obj.nodeType == 1) return "element"; +    } +    return type; +  } +}; + +angular.Collection = {}; +angular.Object = {}; +angular.Array = { +  includeIf:function(array, value, condition) { +    var index = _.indexOf(array, value); +    if (condition) { +      if (index == -1) +        array.push(value); +    } else { +      array.splice(index, 1); +    } +    return array; +  }, +  sum:function(array, expression) { +    var fn = angular.Function.compile(expression); +    var sum = 0; +    for (var i = 0; i < array.length; i++) { +      var value = 1 * fn(array[i]); +      if (!isNaN(value)){ +        sum += value; +      } +    } +    return sum; +  }, +  remove:function(array, value) { +    var index = _.indexOf(array, value); +    if (index >=0) +      array.splice(index, 1); +    return value; +  }, +  find:function(array, condition, defaultValue) { +    if (!condition) return undefined; +    var fn = angular.Function.compile(condition); +    _.detect(array, function($){ +      if (fn($)){ +        defaultValue = $; +        return true; +      }       +    }); +    return defaultValue; +  }, +  findById:function(array, id) { +    return angular.Array.find(array, function($){return $.$id == id;}, null); +  }, +  filter:function(array, expression) { +    var predicates = []; +    predicates.check = function(value) { +      for (var j = 0; j < predicates.length; j++) { +        if(!predicates[j](value)) { +          return false; +        } +      } +      return true; +    }; +    var getter = Scope.getter; +    var search = function(obj, text){ +      if (text.charAt(0) === '!') { +        return !search(obj, text.substr(1)); +      } +      switch (typeof obj) { +      case "boolean": +      case "number": +      case "string": +        return ('' + obj).toLowerCase().indexOf(text) > -1; +      case "object": +        for ( var objKey in obj) { +          if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) { +            return true; +          } +        } +        return false; +      case "array": +        for ( var i = 0; i < obj.length; i++) { +          if (search(obj[i], text)) { +            return true; +          } +        } +        return false; +      default: +        return false; +      } +    }; +    switch (typeof expression) { +      case "boolean": +      case "number": +      case "string": +        expression = {$:expression}; +      case "object": +        for (var key in expression) { +          if (key == '$') { +            (function(){ +              var text = (''+expression[key]).toLowerCase(); +              if (!text) return; +              predicates.push(function(value) { +                return search(value, text); +              }); +            })(); +          } else { +            (function(){ +              var path = key; +              var text = (''+expression[key]).toLowerCase(); +              if (!text) return; +              predicates.push(function(value) { +                return search(getter(value, path), text); +              }); +            })(); +          } +        } +        break; +      case "function": +        predicates.push(expression); +        break; +      default: +        return array; +    } +    var filtered = []; +    for ( var j = 0; j < array.length; j++) { +      var value = array[j]; +      if (predicates.check(value)) { +        filtered.push(value); +      } +    } +    return filtered; +  }, +  add:function(array, value) { +    array.push(_.isUndefined(value)? {} : value); +    return array; +  }, +  count:function(array, condition) { +    if (!condition) return array.length; +    var fn = angular.Function.compile(condition); +    return _.reduce(array, 0, function(count, $){return count + (fn($)?1:0);}); +  }, +  orderBy:function(array, expression, descend) { +    function reverse(comp, descending) { +      return toBoolean(descending) ?  +          function(a,b){return comp(b,a);} : comp; +    } +    function compare(v1, v2){ +      var t1 = typeof v1; +      var t2 = typeof v2; +      if (t1 == t2) { +        if (t1 == "string") v1 = v1.toLowerCase(); +        if (t1 == "string") v2 = v2.toLowerCase(); +        if (v1 === v2) return 0; +        return v1 < v2 ? -1 : 1; +      } else { +        return t1 < t2 ? -1 : 1; +      } +    } +    expression = _.isArray(expression) ? expression: [expression]; +    expression = _.map(expression, function($){ +      var descending = false; +      if (typeof $ == "string" && ($.charAt(0) == '+' || $.charAt(0) == '-')) { +        descending = $.charAt(0) == '-'; +        $ = $.substring(1); +      } +      var get = $ ? angular.Function.compile($) : _.identity; +      return reverse(function(a,b){ +        return compare(get(a),get(b)); +      }, descending); +    }); +    var comparator = function(o1, o2){ +      for ( var i = 0; i < expression.length; i++) { +        var comp = expression[i](o1, o2); +        if (comp != 0) return comp; +      } +      return 0; +    }; +    return _.clone(array).sort(reverse(comparator, descend)); +  }, +  orderByToggle:function(predicate, attribute) { +    var STRIP = /^([+|-])?(.*)/; +    var ascending = false; +    var index = -1; +    _.detect(predicate, function($, i){ +      if ($ == attribute) { +        ascending = true; +        index = i; +        return true; +      } +      if (($.charAt(0)=='+'||$.charAt(0)=='-') && $.substring(1) == attribute) { +        ascending = $.charAt(0) == '+'; +        index = i; +        return true; +      }; +    }); +    if (index >= 0) { +      predicate.splice(index, 1); +    } +    predicate.unshift((ascending ? "-" : "+") + attribute); +    return predicate; +  }, +  orderByDirection:function(predicate, attribute, ascend, descend) { +    ascend = ascend || 'ng-ascend'; +    descend = descend || 'ng-descend'; +    var att = predicate[0] || ''; +    var direction = true; +    if (att.charAt(0) == '-') { +      att = att.substring(1); +      direction = false; +    } else if(att.charAt(0) == '+') { +      att = att.substring(1); +    } +    return att == attribute ? (direction ? ascend : descend) : ""; +  }, +  merge:function(array, index, mergeValue) { +    var value = array[index]; +    if (!value) { +      value = {}; +      array[index] = value; +    } +    merge(mergeValue, value); +    return array; +  } +}; +angular.String = { +  quote:function(string) { +    return '"' + string.replace(/\\/g, '\\\\'). +                        replace(/"/g, '\\"'). +                        replace(/\n/g, '\\n'). +                        replace(/\f/g, '\\f'). +                        replace(/\r/g, '\\r'). +                        replace(/\t/g, '\\t'). +                        replace(/\v/g, '\\v') + +             '"'; +  }, +  quoteUnicode:function(string) { +    var str = angular.String.quote(string); +    var chars = []; +    for ( var i = 0; i < str.length; i++) { +      var ch = str.charCodeAt(i); +      if (ch < 128) { +        chars.push(str.charAt(i)); +      } else { +        var encode = "000" + ch.toString(16); +        chars.push("\\u" + encode.substring(encode.length - 4)); +      } +    } +    return chars.join(''); +  }, +  toDate:function(string){ +    var match; +    if (typeof string == 'string' &&  +        (match = string.match(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/))){ +      var date = new Date(0); +      date.setUTCFullYear(match[1], match[2] - 1, match[3]); +      date.setUTCHours(match[4], match[5], match[6], 0); +      return date; +    } +    return string; +  } +}; +angular.Date = { +    toString:function(date){ +      function pad(n) { return n < 10 ? "0" + n : n; } +      return  (date.getUTCFullYear()) + '-' + +        pad(date.getUTCMonth() + 1) + '-' + +        pad(date.getUTCDate()) + 'T' + +        pad(date.getUTCHours()) + ':' + +        pad(date.getUTCMinutes()) + ':' + +        pad(date.getUTCSeconds()) + 'Z'; +    } +  }; +angular.Function = { +  compile:function(expression) { +    if (_.isFunction(expression)){ +      return expression; +    } else if (expression){ +      var scope = new Scope(); +      return function($) { +        scope.state = $; +        return scope.eval(expression); +      }; +    } else { +      return function($){return $;}; +    } +  } +}; + +(function(){ +  function extend(dst, src, names){ +    _.extend(dst, src); +    _.each((names||[]), function(name){ +      dst[name] = _[name]; +    }); +  }; +  extend(angular.Global, {},  +      ['extend', 'clone','isEqual',  +       'isElement', 'isArray', 'isFunction', 'isUndefined']); +  extend(angular.Collection, angular.Global,  +      ['each', 'map', 'reduce', 'reduceRight', 'detect',  +       'select', 'reject', 'all', 'any', 'include',  +       'invoke', 'pluck', 'max', 'min', 'sortBy',  +       'sortedIndex', 'toArray', 'size']); +  extend(angular.Array, angular.Collection,  +      ['first', 'last', 'compact', 'flatten', 'without',  +       'uniq', 'intersect', 'zip', 'indexOf', 'lastIndexOf']); +  extend(angular.Object, angular.Collection, +      ['keys', 'values']); +  extend(angular.String, angular.Global); +  extend(angular.Function, angular.Global, +      ['bind', 'bindAll', 'delay', 'defer', 'wrap', 'compose']); +})();// Copyright (C) 2009 BRAT Tech LLC +Binder = function(doc, widgetFactory, urlWatcher, config) { +  this.doc = doc; +  this.urlWatcher = urlWatcher; +  this.anchor = {}; +  this.widgetFactory = widgetFactory; +  this.config = config || {}; +  this.updateListeners = []; +}; + +Binder.parseBindings = function(string) { +  var results = []; +  var lastIndex = 0; +  var index; +  while((index = string.indexOf('{{', lastIndex)) > -1) { +    if (lastIndex < index) +      results.push(string.substr(lastIndex, index - lastIndex)); +    lastIndex = index; + +    index = string.indexOf('}}', index); +    index = index < 0 ? string.length : index + 2; + +    results.push(string.substr(lastIndex, index - lastIndex)); +    lastIndex = index; +  } +  if (lastIndex != string.length) +    results.push(string.substr(lastIndex, string.length - lastIndex)); +  return results.length === 0 ? [ string ] : results; +}; + +Binder.hasBinding = function(string) { +  var bindings = Binder.parseBindings(string); +  return bindings.length > 1 || Binder.binding(bindings[0]) !== null; +}; + +Binder.binding = function(string) { +  var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/); +  return binding ? binding[1] : null; +}; + + +Binder.prototype.parseQueryString = function(query) { +  var params = {}; +  query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, +      function (match, left, right) { +        if (left) params[decodeURIComponent(left)] = decodeURIComponent(right); +      }); +  return params; +}; + +Binder.prototype.parseAnchor = function(url) { +  var self = this; +  url = url || this.urlWatcher.getUrl(); + +  var anchorIndex = url.indexOf('#'); +  if (anchorIndex < 0) return; +  var anchor = url.substring(anchorIndex + 1); + +  var anchorQuery = this.parseQueryString(anchor); +  jQuery.each(self.anchor, function(key, newValue) { +    delete self.anchor[key]; +  }); +  jQuery.each(anchorQuery, function(key, newValue) { +    self.anchor[key] = newValue; +  }); +}; + +Binder.prototype.onUrlChange = function (url) { +  console.log("URL change detected", url); +  this.parseAnchor(url); +  this.updateView(); +}; + +Binder.prototype.updateAnchor = function() { +  var url = this.urlWatcher.getUrl(); +  var anchorIndex = url.indexOf('#'); +  if (anchorIndex > -1) +    url = url.substring(0, anchorIndex); +  url += "#"; +  var sep = ''; +  for (var key in this.anchor) { +    var value = this.anchor[key]; +    if (typeof value === 'undefined' || value === null) { +      delete this.anchor[key]; +    } else { +      url += sep + encodeURIComponent(key); +      if (value !== true) +        url += "=" + encodeURIComponent(value); +      sep = '&'; +    } +  } +  this.urlWatcher.setUrl(url); +  return url; +}; + +Binder.prototype.updateView = function() { +  var start = new Date().getTime(); +  var scope = jQuery(this.doc).scope(); +  scope.set("$invalidWidgets", []); +  scope.updateView(); +  var end = new Date().getTime(); +  this.updateAnchor(); +  _.each(this.updateListeners, function(fn) {fn();}); +}; + +Binder.prototype.docFindWithSelf = function(exp){ +  var doc = jQuery(this.doc); +  var selection = doc.find(exp); +  if (doc.is(exp)){ +    selection = selection.andSelf(); +  } +  return selection; +}; + +Binder.prototype.executeInit = function() { +  this.docFindWithSelf("[ng-init]").each(function() { +    var jThis = jQuery(this); +    var scope = jThis.scope(); +    try { +      scope.eval(jThis.attr('ng-init')); +    } catch (e) { +      alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + toJson(e, true)); +    } +  }); +}; + +Binder.prototype.entity = function (scope) { +  this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() { +    try { +      var jNode = jQuery(this); +      var decl = scope.entity(jNode.attr("ng-entity")); +      return decl + (jNode.attr('ng-watch') || ""); +    } catch (e) { +      alert(e); +    } +  }); +}; + +Binder.prototype.compile = function() { +  var jNode = jQuery(this.doc); +  var self = this; +  if (this.config.autoSubmit) { +    var submits = this.docFindWithSelf(":submit").not("[ng-action]"); +    submits.attr("ng-action", "$save()"); +    submits.not(":disabled").not("ng-bind-attr").attr("ng-bind-attr", '{disabled:"{{$invalidWidgets}}"}'); +  } +  this.precompile(this.doc)(this.doc, jNode.scope(), ""); +  this.docFindWithSelf("a[ng-action]").live('click', function (event) { +    var jNode = jQuery(this); +    try { +      jNode.scope().eval(jNode.attr('ng-action')); +      jNode.removeAttr('ng-error'); +      jNode.removeClass("ng-exception"); +    } catch (e) { +      jNode.addClass("ng-exception"); +      jNode.attr('ng-error', toJson(e, true)); +    } +    self.updateView(); +    return false; +  }); +}; + +Binder.prototype.translateBinding = function(node, parentPath, factories) { +  var path = parentPath.concat(); +  var offset = path.pop(); +  var parts = Binder.parseBindings(node.nodeValue); +  if (parts.length > 1 || Binder.binding(parts[0])) { +    var parent = node.parentNode; +    if (isLeafNode(parent)) { +      parent.setAttribute('ng-bind-template', node.nodeValue); +      factories.push({path:path, fn:function(node, scope, prefix) { +        return new BindUpdater(node, node.getAttribute('ng-bind-template')); +      }}); +    } else { +      for (var i = 0; i < parts.length; i++) { +        var part = parts[i]; +        var binding = Binder.binding(part); +        var newNode; +        if (binding) { +          newNode = document.createElement("span"); +          var jNewNode = jQuery(newNode); +          jNewNode.attr("ng-bind", binding); +          if (i === 0) { +            factories.push({path:path.concat(offset + i), fn:Binder.prototype.ng_bind}); +          } +        } else if (msie && part.charAt(0) == ' ') { +          newNode = document.createElement("span"); +          newNode.innerHTML = ' ' + part.substring(1); +        } else { +          newNode = document.createTextNode(part); +        } +        parent.insertBefore(newNode, node); +      } +    } +    parent.removeChild(node); +  } +}; + +Binder.prototype.precompile = function(root) { +  var factories = []; +  this.precompileNode(root, [], factories); +  return function (template, scope, prefix) { +    var len = factories.length; +    for (var i = 0; i < len; i++) { +      var factory = factories[i]; +      var node = template; +      var path = factory.path; +      for (var j = 0; j < path.length; j++) { +        node = node.childNodes[path[j]]; +      } +      try { +        scope.addWidget(factory.fn(node, scope, prefix)); +      } catch (e) { +        alert(e); +      } +    } +  }; +}; + +Binder.prototype.precompileNode = function(node, path, factories) { +  var nodeType = node.nodeType; +  if (nodeType == Node.TEXT_NODE) { +    this.translateBinding(node, path, factories); +    return; +  } else if (nodeType != Node.ELEMENT_NODE && nodeType != Node.DOCUMENT_NODE) { +    return; +  } + +  if (!node.getAttribute) return; +  var nonBindable = node.getAttribute('ng-non-bindable'); +  if (nonBindable || nonBindable === "") return; + +  var attributes = node.attributes; +  if (attributes) { +    var bindings = node.getAttribute('ng-bind-attr'); +    node.removeAttribute('ng-bind-attr'); +    bindings = bindings ? fromJson(bindings) : {}; +    var attrLen = attributes.length; +    for (var i = 0; i < attrLen; i++) { +      var attr = attributes[i]; +      var attrName = attr.name; +      // http://www.glennjones.net/Post/809/getAttributehrefbug.htm +      var attrValue = msie && attrName == 'href' ? +                      decodeURI(node.getAttribute(attrName, 2)) : attr.value; +      if (Binder.hasBinding(attrValue)) { +        bindings[attrName] = attrValue; +      } +    } +    var json = toJson(bindings); +    if (json.length > 2) { +      node.setAttribute("ng-bind-attr", json); +    } +  } + +  if (!node.getAttribute) console.log(node); +  var repeaterExpression = node.getAttribute('ng-repeat'); +  if (repeaterExpression) { +    node.removeAttribute('ng-repeat'); +    var precompiled = this.precompile(node); +    var view = document.createComment("ng-repeat: " + repeaterExpression); +    var parentNode = node.parentNode; +    parentNode.insertBefore(view, node); +    parentNode.removeChild(node); +    var template = function(childScope, prefix, i) { +      var clone = jQuery(node).clone(); +      clone.css('display', ''); +      clone.attr('ng-repeat-index', "" + i); +      clone.data('scope', childScope); +      precompiled(clone[0], childScope, prefix + i + ":"); +      return clone; +    }; +    factories.push({path:path, fn:function(node, scope, prefix) { +      return new RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix); +    }}); +    return; +  } + +  if (node.getAttribute('ng-eval')) factories.push({path:path, fn:this.ng_eval}); +  if (node.getAttribute('ng-bind')) factories.push({path:path, fn:this.ng_bind}); +  if (node.getAttribute('ng-bind-attr')) factories.push({path:path, fn:this.ng_bind_attr}); +  if (node.getAttribute('ng-hide')) factories.push({path:path, fn:this.ng_hide}); +  if (node.getAttribute('ng-show')) factories.push({path:path, fn:this.ng_show}); +  if (node.getAttribute('ng-class')) factories.push({path:path, fn:this.ng_class}); +  if (node.getAttribute('ng-class-odd')) factories.push({path:path, fn:this.ng_class_odd}); +  if (node.getAttribute('ng-class-even')) factories.push({path:path, fn:this.ng_class_even}); +  if (node.getAttribute('ng-style')) factories.push({path:path, fn:this.ng_style}); +  if (node.getAttribute('ng-watch')) factories.push({path:path, fn:this.ng_watch}); +  var nodeName = node.nodeName; +  if ((nodeName == 'INPUT' ) || +      nodeName == 'TEXTAREA' || +      nodeName == 'SELECT' || +      nodeName == 'BUTTON') { +    var self = this; +    factories.push({path:path, fn:function(node, scope, prefix) { +      node.name = prefix + node.name.split(":").pop(); +      return self.widgetFactory.createController(jQuery(node), scope); +    }}); +  } +  if (nodeName == 'OPTION') { +    var html = jQuery('<select/>').append(jQuery(node).clone()).html(); +    if (!html.match(/<option(\s.*\s|\s)value\s*=\s*.*>.*<\/\s*option\s*>/gi)) { +      node.value = node.text; +    } +  } + +  var children = node.childNodes; +  for (var k = 0; k < children.length; k++) { +    this.precompileNode(children[k], path.concat(k), factories); +  } +}; + +Binder.prototype.ng_eval = function(node) { +  return new EvalUpdater(node, node.getAttribute('ng-eval')); +}; + +Binder.prototype.ng_bind = function(node) { +  return new BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}"); +}; + +Binder.prototype.ng_bind_attr = function(node) { +  return new BindAttrUpdater(node, fromJson(node.getAttribute('ng-bind-attr'))); +}; + +Binder.prototype.ng_hide = function(node) { +  return new HideUpdater(node, node.getAttribute('ng-hide')); +}; + +Binder.prototype.ng_show = function(node) { +  return new ShowUpdater(node, node.getAttribute('ng-show')); +}; + +Binder.prototype.ng_class = function(node) { +  return new ClassUpdater(node, node.getAttribute('ng-class')); +}; + +Binder.prototype.ng_class_even = function(node) { +  return new ClassEvenUpdater(node, node.getAttribute('ng-class-even')); +}; + +Binder.prototype.ng_class_odd = function(node) { +  return new ClassOddUpdater(node, node.getAttribute('ng-class-odd')); +}; + +Binder.prototype.ng_style = function(node) { +  return new StyleUpdater(node, node.getAttribute('ng-style')); +}; + +Binder.prototype.ng_watch = function(node, scope) { +  scope.watch(node.getAttribute('ng-watch')); +}; +// Copyright (C) 2008,2009 BRAT Tech LLC + +ControlBar = function (document, serverUrl) { +  this.document = document; +  this.serverUrl = serverUrl; +  this.window = window; +  this.callbacks = []; +}; + +ControlBar.prototype.bind = function () { +}; + +ControlBar.HTML = +  '<div>' + +    '<div class="ui-widget-overlay"></div>' + +    '<div id="ng-login" ng-non-bindable="true">' + +      '<div class="ng-login-container"></div>' + +    '</div>' + +  '</div>'; + +ControlBar.prototype.login = function (loginSubmitFn) { +  this.callbacks.push(loginSubmitFn); +  if (this.callbacks.length == 1) { +    this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor())); +  } +}; + +ControlBar.prototype.logout = function (loginSubmitFn) { +  this.callbacks.push(loginSubmitFn); +  if (this.callbacks.length == 1) { +    this.doTemplate("/user_session/do_destroy.mini"); +  } +}; + +ControlBar.prototype.urlWithoutAnchor = function (path) { +  return this.window.location.href.split("#")[0]; +}; + +ControlBar.prototype.doTemplate = function (path) { +  var self = this; +  var id = new Date().getTime(); +  var url = this.urlWithoutAnchor(); +  url += "#$iframe_notify=" + id; +  var iframeHeight = 330; +  var loginView = jQuery('<div style="overflow:hidden; padding:2px 0 0 0;"><iframe name="'+ url +'" src="'+this.serverUrl + path + '" width="500" height="'+ iframeHeight +'"/></div>'); +  this.document.append(loginView); +  loginView.dialog({ +    height:iframeHeight + 33, width:500, +    resizable: false, modal:true, +    title: 'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>' +  }); +  nglr["_iframe_notify_" + id] = function() { +    loginView.dialog("destroy"); +    loginView.remove(); +    jQuery.each(self.callbacks, function(i, callback){ +      callback(); +    }); +    self.callbacks = []; +  }; +}; + +ControlBar.FORBIDEN = +  '<div ng-non-bindable="true" title="Permission Error:">' + +    'Sorry, you do not have permission for this!'+ +  '</div>'; + +ControlBar.prototype.notAuthorized = function () { +  if (this.forbidenView) return; +  this.forbidenView = jQuery(ControlBar.FORBIDEN); +  this.forbidenView.dialog({bgiframe:true, height:70, modal:true}); +}; +// Copyright (C) 2009 BRAT Tech LLC + +DataStore = function(post, users, anchor) { +  this.post = post; +  this.users = users; +  this._cache = {$collections:[]}; +  this.anchor = anchor; +  this.bulkRequest = []; +}; + +DataStore.prototype.cache = function(document) { +  if (document.constructor != Model) { +    throw "Parameter must be an instance of Entity! " + toJson(document); +  } +  var key = document.$entity + '/' + document.$id; +  var cachedDocument = this._cache[key]; +  if (cachedDocument) { +    Model.copyDirectFields(document, cachedDocument); +  } else { +    this._cache[key] = document; +    cachedDocument = document; +  } +  return cachedDocument; +}; + +DataStore.prototype.load = function(instance, id, callback, failure) { +  if (id && id !== '*') { +    var self = this; +    this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) { +      instance.$loadFrom(response); +      instance.$migrate(); +      var clone = instance.$$entity(instance); +      self.cache(clone); +      (callback||noop)(instance); +    }, failure); +  } +  return instance; +}; + +DataStore.prototype.loadMany = function(entity, ids, callback) { +  var self=this; +  var list = []; +  var callbackCount = 0; +  jQuery.each(ids, function(i, id){ +    list.push(self.load(entity(), id, function(){ +      callbackCount++; +      if (callbackCount == ids.length) { +        (callback||noop)(list); +      } +    })); +  }); +  return list; +} + +DataStore.prototype.loadOrCreate = function(instance, id, callback) { +  var self=this; +  return this.load(instance, id, callback, function(response){ +    if (response.$status_code == 404) { +      instance.$id = id; +      (callback||noop)(instance); +    } else { +      throw response; +    } +  }); +}; + +DataStore.prototype.loadAll = function(entity, callback) { +  var self = this; +  var list = []; +  list.$$accept = function(doc){ +    return doc.$entity == entity.title; +  }; +  this._cache.$collections.push(list); +  this._jsonRequest(["GET", entity.title], function(response) { +    var rows = response; +    for ( var i = 0; i < rows.length; i++) { +      var document = entity(); +      document.$loadFrom(rows[i]); +      list.push(self.cache(document)); +    } +    (callback||noop)(list); +  }); +  return list; +}; + +DataStore.prototype.save = function(document, callback) { +  var self = this; +  var data = {}; +  document.$saveTo(data); +  this._jsonRequest(["POST", "", data], function(response) { +    document.$loadFrom(response); +    var cachedDoc = self.cache(document); +    _.each(self._cache.$collections, function(collection){ +      if (collection.$$accept(document)) { +        angular.Array.includeIf(collection, cachedDoc, true); +      } +    }); +    if (document.$$anchor) { +      self.anchor[document.$$anchor] = document.$id; +    } +    if (callback) +      callback(document); +  }); +}; + +DataStore.prototype.remove = function(document, callback) { +  var self = this; +  var data = {}; +  document.$saveTo(data); +  this._jsonRequest(["DELETE", "", data], function(response) { +    delete self._cache[document.$entity + '/' + document.$id]; +    _.each(self._cache.$collections, function(collection){ +      for ( var i = 0; i < collection.length; i++) { +        var item = collection[i]; +        if (item.$id == document.$id) { +          collection.splice(i, 1); +        } +      } +    }); +    (callback||noop)(response); +  }); +}; + +DataStore.prototype._jsonRequest = function(request, callback, failure) { +  request.$$callback = callback; +  request.$$failure = failure||function(response){ +    throw response; +  }; +  this.bulkRequest.push(request); +}; + +DataStore.prototype.flush = function() { +  if (this.bulkRequest.length === 0) return; +  var self = this; +  var bulkRequest = this.bulkRequest; +  this.bulkRequest = []; +  console.log('REQUEST:', bulkRequest); +  function callback(code, bulkResponse){ +    console.log('RESPONSE[' + code + ']: ', bulkResponse); +    if(bulkResponse.$status_code == 401) { +      self.users.login(function(){ +        self.post(bulkRequest, callback); +      }); +    } else if(bulkResponse.$status_code) { +      alert(toJson(bulkResponse)); +    } else { +      for ( var i = 0; i < bulkResponse.length; i++) { +        var response = bulkResponse[i]; +        var request = bulkRequest[i]; +        var code = response.$status_code; +        if(code) { +          if(code == 403) { +            self.users.notAuthorized(); +          } else { +            request.$$failure(response); +          } +        } else { +          request.$$callback(response); +        } +      } +    } +  } +  this.post(bulkRequest, callback); +}; + +DataStore.prototype.saveScope = function(scope, callback) { +  var saveCounter = 1; +  function onSaveDone() { +    saveCounter--; +    if (saveCounter === 0 && callback) +      callback(); +  } +  for(var key in scope) { +    var item = scope[key]; +    if (item && item.$save == Model.prototype.$save) { +      saveCounter++; +      item.$save(onSaveDone); +    } +  } +  onSaveDone(); +}; + +DataStore.prototype.query = function(type, query, arg, callback){ +  var self = this; +  var queryList = []; +  queryList.$$accept = function(doc){ +    return false; +  }; +  this._cache.$collections.push(queryList); +  var request = type.title + '/' + query + '=' + arg; +  this._jsonRequest(["GET", request], function(response){ +    var list = response; +    for(var i = 0; i < list.length; i++) { +      var document = new type().$loadFrom(list[i]); +      queryList.push(self.cache(document)); +    } +    if (callback) +      callback(queryList); +  }); +  return queryList; +}; + +DataStore.prototype.entities = function(callback) { +  var entities = []; +  var self = this; +  this._jsonRequest(["GET", "$entities"], function(response) { +    for (var entityName in response) { +      entities.push(self.entity(entityName)); +    } +    entities.sort(function(a,b){return a.title > b.title ? 1 : -1;}); +    if (callback) callback(entities); +  }); +  return entities; +}; + +DataStore.prototype.documentCountsByUser = function(){ +  var counts = {}; +  var self = this; +  self.post([["GET", "$users"]], function(code, response){ +    jQuery.each(response[0], function(key, value){ +      counts[key] = value; +    }); +  }); +  return counts; +}; + +DataStore.prototype.userDocumentIdsByEntity = function(user){ +  var ids = {}; +  var self = this; +  self.post([["GET", "$users/" + user]], function(code, response){ +    jQuery.each(response[0], function(key, value){ +      ids[key] = value; +    }); +  }); +  return ids; +}; + +DataStore.NullEntity = function(){}; +DataStore.NullEntity.all = function(){return [];}; +DataStore.NullEntity.query = function(){return [];}; +DataStore.NullEntity.load = function(){return {};}; +DataStore.NullEntity.title = undefined; + +DataStore.prototype.entity = function(name, defaults){ +  if (!name) { +    return DataStore.NullEntity; +  } +  var self = this; +  var entity =  function(initialState){ +    return new Model(entity, initialState); +  }; +  // entity.name does not work as name seems to be reserved for functions +  entity.title = name; +  entity.$$factory = true; +  entity.datastore = this; +  entity.defaults = defaults || {}; +  entity.load = function(id, callback){ +    return self.load(entity(), id, callback); +  }; +  entity.loadMany = function(ids, callback){ +    return self.loadMany(entity, ids, callback); +  }; +  entity.loadOrCreate = function(id, callback){ +    return self.loadOrCreate(entity(), id, callback); +  }; +  entity.all = function(callback){ +    return self.loadAll(entity, callback); +  }; +  entity.query = function(query, queryArgs, callback){ +    return self.query(entity, query, queryArgs, callback); +  }; +  entity.properties = function(callback) { +    self._jsonRequest(["GET", name + "/$properties"], callback); +  }; +  return entity; +}; + +DataStore.prototype.join = function(join){ +  var fn = function(){ +    throw "Joined entities can not be instantiated into a document."; +  }; +  function base(name){return name ? name.substring(0, name.indexOf('.')) : undefined;} +  function next(name){return name.substring(name.indexOf('.') + 1);} +  var joinOrder = _(join).chain(). +    map(function($, name){ +      return name;}). +    sortBy(function(name){ +      var path = []; +      do { +        if (_(path).include(name)) throw "Infinite loop in join: " + path.join(" -> "); +        path.push(name); +        if (!join[name]) throw _("Named entity '<%=name%>' is undefined.").template({name:name}); +        name = base(join[name].on); +      } while(name); +      return path.length; +    }). +    value(); +  if (_(joinOrder).select(function($){return join[$].on;}).length != joinOrder.length - 1) +    throw "Exactly one entity needs to be primary."; +  fn.query = function(exp, value) { +    var joinedResult = []; +    var baseName = base(exp); +    if (baseName != joinOrder[0]) throw _("Named entity '<%=name%>' is not a primary entity.").template({name:baseName}); +    var Entity = join[baseName].join; +    var joinIndex = 1; +    Entity.query(next(exp), value, function(result){ +      var nextJoinName = joinOrder[joinIndex++]; +      var nextJoin = join[nextJoinName]; +      var nextJoinOn = nextJoin.on; +      var joinIds = {}; +      _(result).each(function(doc){ +        var row = {}; +        joinedResult.push(row); +        row[baseName] = doc; +        var id = Scope.getter(row, nextJoinOn); +        joinIds[id] = id; +      }); +      nextJoin.join.loadMany(_.toArray(joinIds), function(result){ +        var byId = {}; +        _(result).each(function(doc){ +          byId[doc.$id] = doc; +        }); +        _(joinedResult).each(function(row){ +          var id = Scope.getter(row, nextJoinOn); +          row[nextJoinName] = byId[id]; +        }); +      }); +    }); +    return joinedResult; +  }; +  return fn; +}; +// Copyright (C) 2009 BRAT Tech LLC + +angular.filter.Meta = function(obj){ +  if (obj) { +    for ( var key in obj) { +      this[key] = obj[key]; +    } +  } +}; +angular.filter.Meta.get = function(obj, attr){ +  attr = attr || 'text'; +  switch(typeof obj) { +  case "string": +    return attr == "text" ? obj : undefined; +  case "object": +    if (obj && typeof obj[attr] !== "undefined") { +      return obj[attr]; +    } +    return undefined; +  default: +    return obj; +  } +}; + +angular.filter.currency = function(amount){ +  jQuery(this.element).toggleClass('ng-format-negative', amount < 0); +  return '$' + angular.filter.number.apply(this, [amount, 2]); +}; + +angular.filter.number = function(amount, fractionSize){ +  if (isNaN(amount) || !isFinite(amount)) { +    return ''; +  } +  fractionSize = typeof fractionSize == 'undefined' ? 2 : fractionSize; +  var isNegative = amount < 0; +  amount = Math.abs(amount); +  var pow = Math.pow(10, fractionSize); +  var text = "" + Math.round(amount * pow); +  var whole = text.substring(0, text.length - fractionSize); +  whole = whole || '0'; +  var frc = text.substring(text.length - fractionSize); +  text = isNegative ? '-' : ''; +  for (var i = 0; i < whole.length; i++) { +    if ((whole.length - i)%3 === 0 && i !== 0) { +      text += ','; +    } +    text += whole.charAt(i); +  } +  if (fractionSize > 0) { +    for (var j = frc.length; j < fractionSize; j++) { +      frc += '0'; +    } +    text += '.' + frc.substring(0, fractionSize); +  } +  return text; +}; + +angular.filter.date = function(amount) { +}; + +angular.filter.json = function(object) { +  jQuery(this.element).addClass("ng-monospace"); +  return toJson(object, true); +}; + +angular.filter.trackPackage = function(trackingNo, noMatch) { +  trackingNo = trim(trackingNo); +  var tNo = trackingNo.replace(/ /g, ''); +  var MATCHERS = angular.filter.trackPackage.MATCHERS; +  for ( var i = 0; i < MATCHERS.length; i++) { +    var carrier = MATCHERS[i]; +    for ( var j = 0; j < carrier.regexp.length; j++) { +      var regexp = carrier.regexp[j]; +      if (regexp.test(tNo)) { +        var text = carrier.name + ": " + trackingNo; +        var url = carrier.url + trackingNo; +        return new angular.filter.Meta({ +          text:text, +          url:url, +          html: '<a href="' + escapeAttr(url) + '">' + text + '</a>', +          trackingNo:trackingNo}); +      } +    } +  } +  if (trackingNo) +    return noMatch || +      new angular.filter.Meta({text:trackingNo + " is not recognized"}); +  else +    return null; +}; + +angular.filter.trackPackage.MATCHERS = [ +    { name: "UPS", +      url: "http://wwwapps.ups.com/WebTracking/processInputRequest?sort_by=status&tracknums_displayed=1&TypeOfInquiryNumber=T&loc=en_US&track.x=0&track.y=0&InquiryNumber1=", +      regexp: [ +        /^1Z[0-9A-Z]{16}$/i]}, +    { name: "FedEx", +      url: "http://www.fedex.com/Tracking?tracknumbers=", +      regexp: [ +        /^96\d{10}?$/i, +        /^96\d{17}?$/i, +        /^96\d{20}?$/i, +        /^\d{15}$/i, +        /^\d{12}$/i]}, +    { name: "USPS", +      url: "http://trkcnfrm1.smi.usps.com/PTSInternetWeb/InterLabelInquiry.do?origTrackNum=", +      regexp: [ +        /^(91\d{20})$/i, +        /^(91\d{18})$/i]}]; + +angular.filter.link = function(obj, title) { +  var text = title || angular.filter.Meta.get(obj); +  var url = angular.filter.Meta.get(obj, "url") || angular.filter.Meta.get(obj); +  if (url) { +    if (angular.validator.email(url) === null) { +      url = "mailto:" + url; +    } +    var html = '<a href="' + escapeHtml(url) + '">' + text + '</a>'; +    return new angular.filter.Meta({text:text, url:url, html:html}); +  } +  return obj; +}; + + +angular.filter.bytes = function(size) { +  if(size === null) return ""; + +  var suffix = 0; +  while (size > 1000) { +    size = size / 1024; +    suffix++; +  } +  var txt = "" + size; +  var dot = txt.indexOf('.'); +  if (dot > -1 && dot + 2 < txt.length) { +    txt = txt.substring(0, dot + 2); +  } +  return txt + " " + angular.filter.bytes.SUFFIX[suffix]; +}; +angular.filter.bytes.SUFFIX = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB']; + +angular.filter.image = function(obj, width, height) { +  if (obj && obj.url) { +    var style = ""; +    if (width) { +      style = ' style="max-width: ' + width + +              'px; max-height: ' + (height || width) + 'px;"'; +    } +    return new angular.filter.Meta({url:obj.url, text:obj.url, +      html:'<img src="'+obj.url+'"' + style + '/>'}); +  } +  return null; +}; + +angular.filter.lowercase = function (obj) { +  var text = angular.filter.Meta.get(obj); +  return text ? ("" + text).toLowerCase() : text; +}; + +angular.filter.uppercase = function (obj) { +  var text = angular.filter.Meta.get(obj); +  return text ? ("" + text).toUpperCase() : text; +}; + +angular.filter.linecount = function (obj) { +  var text = angular.filter.Meta.get(obj); +  if (text==='' || !text) return 1; +  return text.split(/\n|\f/).length; +}; + +angular.filter['if'] = function (result, expression) { +  return expression ? result : undefined; +}; + +angular.filter.unless = function (result, expression) { +  return expression ? undefined : result; +}; + +angular.filter.googleChartApi = function(type, data, width, height) { +  data = data || {}; +  var api = angular.filter.googleChartApi; +  var chart = { +      cht:type,  +      chco:api.collect(data, 'color'), +      chtt:api.title(data), +      chdl:api.collect(data, 'label'), +      chd:api.values(data), +      chf:'bg,s,FFFFFF00' +    }; +  if (_.isArray(data.xLabels)) { +    chart.chxt='x'; +    chart.chxl='0:|' + data.xLabels.join('|'); +  } +  return angular.filter.googleChartApi.encode(chart, width, height); +}; + +angular.filter.googleChartApi.values = function(data){ +  var seriesValues = []; +  _.each(data.series||[], function(serie){ +    var values = []; +    _.each(serie.values||[], function(value){ +      values.push(value); +    }); +    seriesValues.push(values.join(',')); +  }); +  var values = seriesValues.join('|'); +  return values === "" ? null : "t:" + values; +}; + +angular.filter.googleChartApi.title = function(data){ +  var titles = []; +  var title = data.title || []; +  _.each(_.isArray(title)?title:[title], function(text){ +    titles.push(encodeURIComponent(text)); +  }); +  return titles.join('|'); +}; + +angular.filter.googleChartApi.collect = function(data, key){ +  var outterValues = []; +  var count = 0; +  _.each(data.series||[], function(serie){ +    var innerValues = []; +    var value = serie[key] || []; +    _.each(_.isArray(value)?value:[value], function(color){ +        innerValues.push(encodeURIComponent(color)); +        count++; +      }); +    outterValues.push(innerValues.join('|')); +  }); +  return count?outterValues.join(','):null; +}; + +angular.filter.googleChartApi.encode= function(params, width, height) { +  width = width || 200; +  height = height || width; +  var url = "http://chart.apis.google.com/chart?"; +  var urlParam = []; +  params.chs = width + "x" + height; +  for ( var key in params) { +    var value = params[key]; +    if (value) { +      urlParam.push(key + "=" + value); +    } +  } +  urlParam.sort(); +  url += urlParam.join("&"); +  return new angular.filter.Meta({url:url, text:value, +    html:'<img width="' + width + '" height="' + height + '" src="'+url+'"/>'}); +}; + +angular.filter.qrcode = function(value, width, height) { +  return angular.filter.googleChartApi.encode({cht:'qr', chl:encodeURIComponent(value)}, width, height); +}; +angular.filter.chart = { +  pie:function(data, width, height) { +    return angular.filter.googleChartApi('p', data, width, height); +  }, +  pie3d:function(data, width, height) { +    return angular.filter.googleChartApi('p3', data, width, height); +  }, +  pieConcentric:function(data, width, height) { +    return angular.filter.googleChartApi('pc', data, width, height); +  }, +  barHorizontalStacked:function(data, width, height) { +    return angular.filter.googleChartApi('bhs', data, width, height); +  }, +  barHorizontalGrouped:function(data, width, height) { +    return angular.filter.googleChartApi('bhg', data, width, height); +  }, +  barVerticalStacked:function(data, width, height) { +    return angular.filter.googleChartApi('bvs', data, width, height); +  }, +  barVerticalGrouped:function(data, width, height) { +    return angular.filter.googleChartApi('bvg', data, width, height); +  }, +  line:function(data, width, height) { +    return angular.filter.googleChartApi('lc', data, width, height); +  }, +  sparkline:function(data, width, height) { +    return angular.filter.googleChartApi('ls', data, width, height); +  }, +  scatter:function(data, width, height) { +    return angular.filter.googleChartApi('s', data, width, height); +  } +}; + +angular.filter.html = function(html){ +  return new angular.filter.Meta({html:html}); +}; +array = [].constructor; + +toJson = function(obj, pretty){ +  var buf = []; +  toJsonArray(buf, obj, pretty ? "\n  " : null); +  return buf.join(''); +}; + +toPrettyJson = function(obj) { +  return toJson(obj, true); +}; + +fromJson = function(json) { +  try { +    var parser = new Parser(json, true); +    var expression =  parser.primary(); +    parser.assertAllConsumed(); +    return expression(); +  } catch (e) { +    console.error("fromJson error: ", json, e); +    throw e; +  } +}; + + +toJsonArray = function(buf, obj, pretty){ +  var type = typeof obj; +  if (obj === null) { +    buf.push("null"); +  } else if (type === 'function') { +    return; +  } else if (type === 'boolean') { +    buf.push('' + obj); +  } else if (type === 'number') { +    if (isNaN(obj)) { +      buf.push('null'); +    } else { +      buf.push('' + obj); +    } +  } else if (type === 'string') { +    return buf.push(angular.String.quoteUnicode(obj)); +  } else if (type === 'object') { +    if (obj instanceof Array) { +      buf.push("["); +      var len = obj.length; +      var sep = false; +      for(var i=0; i<len; i++) { +        var item = obj[i]; +        if (sep) buf.push(","); +        if (typeof item == 'function' || typeof item == 'undefined') { +          buf.push("null"); +        } else { +          toJsonArray(buf, item, pretty); +        } +        sep = true; +      } +      buf.push("]"); +    } else if (obj instanceof Date) { +      buf.push(angular.String.quoteUnicode(angular.Date.toString(obj))); +    } else { +      buf.push("{"); +      if (pretty) buf.push(pretty); +      var comma = false; +      var childPretty = pretty ? pretty + "  " : false; +      var keys = []; +      for(var k in obj) { +        if (k.indexOf('$$') === 0) +          continue; +        keys.push(k); +      } +      keys.sort(); +      for ( var keyIndex = 0; keyIndex < keys.length; keyIndex++) { +        var key = keys[keyIndex]; +        try { +          var value = obj[key]; +          if (typeof value != 'function') { +            if (comma) { +              buf.push(","); +              if (pretty) buf.push(pretty); +            } +            buf.push(angular.String.quote(key)); +            buf.push(":"); +            toJsonArray(buf, value, childPretty); +            comma = true; +          } +        } catch (e) { +        } +      } +      buf.push("}"); +    } +  } +}; +// Copyright (C) 2009 BRAT Tech LLC + +// Single $ is special and does not get searched +// Double $$ is special an is client only (does not get sent to server) + +Model = function(entity, initial) { +  this.$$entity = entity; +  this.$loadFrom(initial||{}); +  this.$entity = entity.title; +  this.$migrate(); +}; + +Model.copyDirectFields = function(src, dst) { +  if (src === dst || !src || !dst) return; +  var isDataField = function(src, dst, field) { +    return (field.substring(0,2) !== '$$') && +        (typeof src[field] !== 'function') && +        (typeof dst[field] !== 'function'); +  }; +  for (var field in dst) { +    if (isDataField(src, dst, field)) +      delete dst[field]; +  } +  for (field in src) { +    if (isDataField(src, dst, field)) +      dst[field] = src[field]; +  } +}; + +Model.prototype.$migrate = function() { +  merge(this.$$entity.defaults, this); +  return this; +}; + +Model.prototype.$merge = function(other) { +  merge(other, this); +  return this; +}; + +Model.prototype.$save = function(callback) { +  this.$$entity.datastore.save(this, callback === true ? undefined : callback); +  if (callback === true) this.$$entity.datastore.flush(); +  return this; +}; + +Model.prototype.$delete = function(callback) { +  this.$$entity.datastore.remove(this, callback === true ? undefined : callback); +  if (callback === true) this.$$entity.datastore.flush(); +  return this; +}; + +Model.prototype.$loadById = function(id, callback) { +  this.$$entity.datastore.load(this, id, callback); +  return this; +}; + +Model.prototype.$loadFrom = function(other) { +  Model.copyDirectFields(other, this); +  return this; +}; + +Model.prototype.$saveTo = function(other) { +  Model.copyDirectFields(this, other); +  return this; +}; +Lexer = function(text, parsStrings){ +  this.text = text; +  // UTC dates have 20 characters, we send them through parser +  this.dateParseLength = parsStrings ? 20 : -1; +  this.tokens = []; +  this.index = 0; +}; + +Lexer.OPERATORS = { +    'null':function(self){return null;}, +    'true':function(self){return true;}, +    'false':function(self){return false;}, +    '+':function(self, a,b){return (a||0)+(b||0);}, +    '-':function(self, a,b){return (a||0)-(b||0);}, +    '*':function(self, a,b){return a*b;}, +    '/':function(self, a,b){return a/b;}, +    '%':function(self, a,b){return a%b;}, +    '^':function(self, a,b){return a^b;}, +    '=':function(self, a,b){return self.scope.set(a, b);}, +    '==':function(self, a,b){return a==b;}, +    '!=':function(self, a,b){return a!=b;}, +    '<':function(self, a,b){return a<b;}, +    '>':function(self, a,b){return a>b;}, +    '<=':function(self, a,b){return a<=b;}, +    '>=':function(self, a,b){return a>=b;}, +    '&&':function(self, a,b){return a&&b;}, +    '||':function(self, a,b){return a||b;}, +    '&':function(self, a,b){return a&b;}, +//    '|':function(self, a,b){return a|b;}, +    '|':function(self, a,b){return b(self, a);}, +    '!':function(self, a){return !a;} +}; + +Lexer.prototype.peek = function() { +  if (this.index + 1 < this.text.length) { +    return this.text.charAt(this.index + 1); +  } else { +    return false; +  } +}; + +Lexer.prototype.parse = function() { +  var tokens = this.tokens; +  var OPERATORS = Lexer.OPERATORS; +  var canStartRegExp = true; +  while (this.index < this.text.length) { +    var ch = this.text.charAt(this.index); +    if (ch == '"' || ch == "'") { +      this.readString(ch); +      canStartRegExp = true; +    } else if (ch == '(' || ch == '[') { +      tokens.push({index:this.index, text:ch}); +      this.index++; +    } else if (ch == '{' ) { +      var peekCh = this.peek(); +      if (peekCh == ':' || peekCh == '(') { +        tokens.push({index:this.index, text:ch + peekCh}); +        this.index++; +      } else { +        tokens.push({index:this.index, text:ch}); +      } +      this.index++; +      canStartRegExp = true; +    } else if (ch == ')' || ch == ']' || ch == '}' ) { +      tokens.push({index:this.index, text:ch}); +      this.index++; +      canStartRegExp = false; +    } else if ( ch == ':' || ch == '.' || ch == ',' || ch == ';') { +      tokens.push({index:this.index, text:ch}); +      this.index++; +      canStartRegExp = true; +    } else if ( canStartRegExp && ch == '/' ) { +      this.readRegexp(); +      canStartRegExp = false; +    } else if ( this.isNumber(ch) ) { +      this.readNumber(); +      canStartRegExp = false; +    } else if (this.isIdent(ch)) { +      this.readIdent(); +      canStartRegExp = false; +    } else if (this.isWhitespace(ch)) { +      this.index++; +    } else { +      var ch2 = ch + this.peek(); +      var fn = OPERATORS[ch]; +      var fn2 = OPERATORS[ch2]; +      if (fn2) { +        tokens.push({index:this.index, text:ch2, fn:fn2}); +        this.index += 2; +      } else if (fn) { +        tokens.push({index:this.index, text:ch, fn:fn}); +        this.index += 1; +      } else { +        throw "Lexer Error: Unexpected next character [" + +            this.text.substring(this.index) + +            "] in expression '" + this.text + +            "' at column '" + (this.index+1) + "'."; +      } +      canStartRegExp = true; +    } +  } +  return tokens; +}; + +Lexer.prototype.isNumber = function(ch) { +  return '0' <= ch && ch <= '9'; +}; + +Lexer.prototype.isWhitespace = function(ch) { +  return ch == ' ' || ch == '\r' || ch == '\t' || +         ch == '\n' || ch == '\v'; +}; + +Lexer.prototype.isIdent = function(ch) { +  return 'a' <= ch && ch <= 'z' || +         'A' <= ch && ch <= 'Z' || +         '_' == ch || ch == '$'; +}; + +Lexer.prototype.readNumber = function() { +  var number = ""; +  var start = this.index; +  while (this.index < this.text.length) { +    var ch = this.text.charAt(this.index); +    if (ch == '.' || this.isNumber(ch)) { +      number += ch; +    } else { +      break; +    } +    this.index++; +  } +  number = 1 * number; +  this.tokens.push({index:start, text:number, +    fn:function(){return number;}}); +}; + +Lexer.prototype.readIdent = function() { +  var ident = ""; +  var start = this.index; +  while (this.index < this.text.length) { +    var ch = this.text.charAt(this.index); +    if (ch == '.' || this.isIdent(ch) || this.isNumber(ch)) { +      ident += ch; +    } else { +      break; +    } +    this.index++; +  } +  var fn = Lexer.OPERATORS[ident]; +  if (!fn) { +    fn = function(self){ +      return self.scope.get(ident); +    }; +    fn.isAssignable = ident; +  } +  this.tokens.push({index:start, text:ident, fn:fn}); +}; +Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; +Lexer.prototype.readString = function(quote) { +  var start = this.index; +  var dateParseLength = this.dateParseLength; +  this.index++; +  var string = ""; +  var escape = false; +  while (this.index < this.text.length) { +    var ch = this.text.charAt(this.index); +    if (escape) { +      if (ch == 'u') { +        var hex = this.text.substring(this.index + 1, this.index + 5); +        this.index += 4; +        string += String.fromCharCode(parseInt(hex, 16)); +      } else { +        var rep = Lexer.ESCAPE[ch]; +        if (rep) { +          string += rep; +        } else { +          string += ch; +        } +      } +      escape = false; +    } else if (ch == '\\') { +      escape = true; +    } else if (ch == quote) { +      this.index++; +      this.tokens.push({index:start, text:string, +        fn:function(){ +          return (string.length == dateParseLength) ? +            angular.String.toDate(string) : string; +        }}); +      return; +    } else { +      string += ch; +    } +    this.index++; +  } +  throw "Lexer Error: Unterminated quote [" + +      this.text.substring(start) + "] starting at column '" + +      (start+1) + "' in expression '" + this.text + "'."; +}; + +Lexer.prototype.readRegexp = function(quote) { +  var start = this.index; +  this.index++; +  var regexp = ""; +  var escape = false; +  while (this.index < this.text.length) { +    var ch = this.text.charAt(this.index); +    if (escape) { +      regexp += ch; +      escape = false; +    } else if (ch === '\\') { +      regexp += ch; +      escape = true; +    } else if (ch === '/') { +      this.index++; +      var flags = ""; +      if (this.isIdent(this.text.charAt(this.index))) { +        this.readIdent(); +        flags = this.tokens.pop().text; +      } +      var compiledRegexp = new RegExp(regexp, flags); +      this.tokens.push({index:start, text:regexp, flags:flags, +        fn:function(){return compiledRegexp;}}); +      return; +    } else { +      regexp += ch; +    } +    this.index++; +  } +  throw "Lexer Error: Unterminated RegExp [" + +      this.text.substring(start) + "] starting at column '" + +      (start+1) + "' in expression '" + this.text + "'."; +}; + + +Parser = function(text, parseStrings){ +  this.text = text; +  this.tokens = new Lexer(text, parseStrings).parse(); +  this.index = 0; +}; + +Parser.ZERO = function(){ +  return 0; +}; + +Parser.prototype.error = function(msg, token) { +  throw "Token '" + token.text +  +    "' is " + msg + " at column='" +  +    (token.index + 1) + "' of expression '" +  +    this.text + "' starting at '" + this.text.substring(token.index) + "'."; +}; + +Parser.prototype.peekToken = function() { +  if (this.tokens.length === 0)  +    throw "Unexpected end of expression: " + this.text; +  return this.tokens[0]; +}; + +Parser.prototype.peek = function(e1, e2, e3, e4) { +  var tokens = this.tokens; +  if (tokens.length > 0) { +    var token = tokens[0]; +    var t = token.text; +    if (t==e1 || t==e2 || t==e3 || t==e4 || +        (!e1 && !e2 && !e3 && !e4)) { +      return token; +    } +  } +  return false; +}; + +Parser.prototype.expect = function(e1, e2, e3, e4){ +  var token = this.peek(e1, e2, e3, e4); +  if (token) { +    this.tokens.shift(); +    this.currentToken = token; +    return token; +  } +  return false; +}; + +Parser.prototype.consume = function(e1){ +  if (!this.expect(e1)) { +    var token = this.peek(); +    throw "Expecting '" + e1 + "' at column '" + +        (token.index+1) + "' in '" + +        this.text + "' got '" + +        this.text.substring(token.index) + "'."; +  } +}; + +Parser.prototype._unary = function(fn, parse) { +  var right = parse.apply(this); +  return function(self) { +    return fn(self, right(self)); +  }; +}; + +Parser.prototype._binary = function(left, fn, parse) { +  var right = parse.apply(this); +  return function(self) { +    return fn(self, left(self), right(self)); +  }; +}; + +Parser.prototype.hasTokens = function () { +  return this.tokens.length > 0; +}; + +Parser.prototype.assertAllConsumed = function(){ +  if (this.tokens.length !== 0) { +    throw "Did not understand '" + this.text.substring(this.tokens[0].index) + +        "' while evaluating '" + this.text + "'."; +  } +}; + +Parser.prototype.statements = function(){ +  var statements = []; +  while(true) { +    if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']')) +      statements.push(this.filterChain()); +    if (!this.expect(';')) { +      return function (self){ +        var value; +        for ( var i = 0; i < statements.length; i++) { +          var statement = statements[i]; +          if (statement) +            value = statement(self); +        } +        return value; +      }; +    } +  } +}; + +Parser.prototype.filterChain = function(){ +  var left = this.expression(); +  var token; +  while(true) { +    if ((token = this.expect('|'))) { +      left = this._binary(left, token.fn, this.filter); +    } else { +      return left; +    } +  } +}; + +Parser.prototype.filter = function(){ +  return this._pipeFunction(angular.filter); +}; + +Parser.prototype.validator = function(){ +  return this._pipeFunction(angular.validator); +}; + +Parser.prototype._pipeFunction = function(fnScope){ +  var fn = this.functionIdent(fnScope); +  var argsFn = []; +  var token; +  while(true) { +    if ((token = this.expect(':'))) { +      argsFn.push(this.expression()); +    } else { +      var fnInvoke = function(self, input){ +        var args = [input]; +        for ( var i = 0; i < argsFn.length; i++) { +          args.push(argsFn[i](self)); +        } +        return fn.apply(self, args); +      }; +      return function(){ +        return fnInvoke; +      }; +    } +  } +}; + +Parser.prototype.expression = function(){ +  return this.throwStmt(); +}; + +Parser.prototype.throwStmt = function(){ +  if (this.expect('throw')) { +    var throwExp = this.assignment(); +    return function (self) { +      throw throwExp(self); +    }; +  } else { +   return this.assignment(); +  } +}; + +Parser.prototype.assignment = function(){ +  var left = this.logicalOR(); +  var token; +  if (token = this.expect('=')) { +    if (!left.isAssignable) { +      throw "Left hand side '" + +          this.text.substring(0, token.index) + "' of assignment '" + +          this.text.substring(token.index) + "' is not assignable."; +    } +    var ident = function(){return left.isAssignable;}; +    return this._binary(ident, token.fn, this.logicalOR); +  } else { +   return left; +  } +}; + +Parser.prototype.logicalOR = function(){ +  var left = this.logicalAND(); +  var token; +  while(true) { +    if ((token = this.expect('||'))) { +      left = this._binary(left, token.fn, this.logicalAND); +    } else { +      return left; +    } +  } +}; + +Parser.prototype.logicalAND = function(){ +  var left = this.negated(); +  var token; +  while(true) { +    if ((token = this.expect('&&'))) { +      left = this._binary(left, token.fn, this.negated); +    } else { +      return left; +    } +  } +}; + +Parser.prototype.negated = function(){ +  var token; +  if (token = this.expect('!')) { +    return this._unary(token.fn, this.equality); +  } else { +   return this.equality(); +  } +}; + +Parser.prototype.equality = function(){ +  var left = this.relational(); +  var token; +  while(true) { +    if ((token = this.expect('==','!='))) { +      left = this._binary(left, token.fn, this.relational); +    } else { +      return left; +    } +  } +}; + +Parser.prototype.relational = function(){ +  var left = this.additive(); +  var token; +  while(true) { +    if ((token = this.expect('<', '>', '<=', '>='))) { +      left = this._binary(left, token.fn, this.additive); +    } else { +      return left; +    } +  } +}; + +Parser.prototype.additive = function(){ +  var left = this.multiplicative(); +  var token; +  while(token = this.expect('+','-')) { +    left = this._binary(left, token.fn, this.multiplicative); +  } +  return left; +}; + +Parser.prototype.multiplicative = function(){ +  var left = this.unary(); +  var token; +  while(token = this.expect('*','/','%')) { +      left = this._binary(left, token.fn, this.unary); +  } +  return left; +}; + +Parser.prototype.unary = function(){ +  var token; +  if (this.expect('+')) { +    return this.primary(); +  } else if (token = this.expect('-')) { +    return this._binary(Parser.ZERO, token.fn, this.multiplicative); +  } else { +   return this.primary(); +  } +}; + +Parser.prototype.functionIdent = function(fnScope) { +  var token = this.expect(); +  var element = token.text.split('.'); +  var instance = fnScope; +  var key; +  for ( var i = 0; i < element.length; i++) { +    key = element[i]; +    if (instance) +      instance = instance[key]; +  } +  if (typeof instance != 'function') { +    throw "Function '" + token.text + "' at column '" + +    (token.index+1)  + "' in '" + this.text + "' is not defined."; +  } +  return instance; +}; + +Parser.prototype.primary = function() { +  var primary; +  if (this.expect('(')) { +    var expression = this.filterChain(); +    this.consume(')'); +    primary = expression; +  } else if (this.expect('[')) { +    primary = this.arrayDeclaration(); +  } else if (this.expect('{')) { +    primary = this.object(); +  } else if (this.expect('{:')) { +    primary = this.closure(false); +  } else if (this.expect('{(')) { +    primary = this.closure(true); +  } else { +    var token = this.expect(); +    primary = token.fn; +    if (!primary) { +      this.error("not a primary expression", token); +    } +  } +  var next; +  while (next = this.expect('(', '[', '.')) { +    if (next.text === '(') { +      primary = this.functionCall(primary); +    } else if (next.text === '[') { +      primary = this.objectIndex(primary); +    } else if (next.text === '.') { +      primary = this.fieldAccess(primary); +    } else { +      throw "IMPOSSIBLE"; +    } +  } +  return primary; +}; + +Parser.prototype.closure = function(hasArgs) { +  var args = []; +  if (hasArgs) { +    if (!this.expect(')')) { +      args.push(this.expect().text); +      while(this.expect(',')) { +        args.push(this.expect().text); +      } +      this.consume(')'); +    } +    this.consume(":"); +  } +  var statements = this.statements(); +  this.consume("}"); +  return function(self){ +    return function($){ +      var scope = new Scope(self.scope.state); +      scope.set('$', $); +      for ( var i = 0; i < args.length; i++) { +        scope.set(args[i], arguments[i]); +      } +      return statements({scope:scope}); +    }; +  }; +}; + +Parser.prototype.fieldAccess = function(object) { +  var field = this.expect().text; +  var fn = function (self){ +    return Scope.getter(object(self), field); +  }; +  fn.isAssignable = field; +  return fn; +}; + +Parser.prototype.objectIndex = function(obj) { +  var indexFn = this.expression(); +  this.consume(']'); +  if (this.expect('=')) { +    var rhs = this.expression(); +    return function (self){ +      return obj(self)[indexFn(self)] = rhs(self); +    }; +  } else { +    return function (self){ +      var o = obj(self); +      var i = indexFn(self); +      return (o) ? o[i] : undefined; +    }; +  } +}; + +Parser.prototype.functionCall = function(fn) { +  var argsFn = []; +  if (this.peekToken().text != ')') { +    do { +      argsFn.push(this.expression()); +    } while (this.expect(',')); +  } +  this.consume(')'); +  return function (self){ +    var args = []; +    for ( var i = 0; i < argsFn.length; i++) { +      args.push(argsFn[i](self)); +    } +    var fnPtr = fn(self); +    if (typeof fnPtr === 'function') { +      return fnPtr.apply(self, args); +    } else { +      throw "Expression '" + fn.isAssignable + "' is not a function."; +    } +  }; +}; + +// This is used with json array declaration +Parser.prototype.arrayDeclaration = function () { +  var elementFns = []; +  if (this.peekToken().text != ']') { +    do { +      elementFns.push(this.expression()); +    } while (this.expect(',')); +  } +  this.consume(']'); +  return function (self){ +    var array = []; +    for ( var i = 0; i < elementFns.length; i++) { +      array.push(elementFns[i](self)); +    } +    return array; +  }; +}; + +Parser.prototype.object = function () { +  var keyValues = []; +  if (this.peekToken().text != '}') { +    do { +      var key = this.expect().text; +      this.consume(":"); +      var value = this.expression(); +      keyValues.push({key:key, value:value}); +    } while (this.expect(',')); +  } +  this.consume('}'); +  return function (self){ +    var object = {}; +    for ( var i = 0; i < keyValues.length; i++) { +      var keyValue = keyValues[i]; +      var value = keyValue.value(self); +      object[keyValue.key] = value; +    } +    return object; +  }; +}; + +Parser.prototype.entityDeclaration = function () { +  var decl = []; +  while(this.hasTokens()) { +    decl.push(this.entityDecl()); +    if (!this.expect(';')) { +      this.assertAllConsumed(); +    } +  } +  return function (self){ +    var code = ""; +    for ( var i = 0; i < decl.length; i++) { +      code += decl[i](self); +    } +    return code; +  }; +}; + +Parser.prototype.entityDecl = function () { +  var entity = this.expect().text; +  var instance; +  var defaults; +  if (this.expect('=')) { +    instance = entity; +    entity = this.expect().text; +  } +  if (this.expect(':')) { +    defaults = this.primary()(null); +  } +  return function(self) { +    var datastore = self.scope.get('$datastore'); +    var Entity = datastore.entity(entity, defaults); +    self.scope.set(entity, Entity); +    if (instance) { +      var document = Entity(); +      document.$$anchor = instance; +      self.scope.set(instance, document); +      return "$anchor." + instance + ":{" +  +          instance + "=" + entity + ".load($anchor." + instance + ");" + +          instance + ".$$anchor=" + angular.String.quote(instance) + ";" +  +        "};"; +    } else { +      return ""; +    } +  }; +}; + +Parser.prototype.watch = function () { +  var decl = []; +  while(this.hasTokens()) { +    decl.push(this.watchDecl()); +    if (!this.expect(';')) { +      this.assertAllConsumed(); +    } +  } +  this.assertAllConsumed(); +  return function (self){ +    for ( var i = 0; i < decl.length; i++) { +      var d = decl[i](self); +      self.addListener(d.name, d.fn); +    } +  }; +}; + +Parser.prototype.watchDecl = function () { +  var anchorName = this.expect().text; +  this.consume(":"); +  var expression; +  if (this.peekToken().text == '{') { +    this.consume("{"); +    expression = this.statements(); +    this.consume("}"); +  } else { +    expression = this.expression(); +  } +  return function(self) { +    return {name:anchorName, fn:expression}; +  }; +}; + + +// Copyright (C) 2009 BRAT Tech LLC + +Scope = function(initialState, name) { +  this.widgets = []; +  this.watchListeners = {}; +  this.name = name; +  initialState = initialState || {}; +  var State = function(){}; +  State.prototype = initialState; +  this.state = new State(); +  this.state.$parent = initialState; +  if (name == "ROOT") { +    this.state.$root = this.state; +  } +}; + +Scope.expressionCache = {}; + +Scope.prototype.updateView = function() { +  var self = this; +  this.fireWatchers(); +  _.each(this.widgets, function(widget){ +    self.evalWidget(widget, "", {}, function(){ +      this.updateView(self); +    }); +  }); +}; + +Scope.prototype.addWidget = function(controller) { +  if (controller) this.widgets.push(controller); +}; + +Scope.prototype.isProperty = function(exp) { +  for ( var i = 0; i < exp.length; i++) { +    var ch = exp.charAt(i); +    if (ch!='.'  && !Lexer.prototype.isIdent(ch)) { +      return false; +    } +  } +  return true; +}; + +Scope.getter = function(instance, path) { +  if (!path) return instance; +  var element = path.split('.'); +  var key; +  var lastInstance = instance; +  var len = element.length; +  for ( var i = 0; i < len; i++) { +    key = element[i]; +    if (!key.match(/^[\$\w][\$\w\d]*$/)) +        throw "Expression '" + path + "' is not a valid expression for accesing variables."; +    if (instance) { +      lastInstance = instance; +      instance = instance[key]; +    } +    if (_.isUndefined(instance)  && key.charAt(0) == '$') { +      var type = angular.Global.typeOf(lastInstance); +      type = angular[type.charAt(0).toUpperCase()+type.substring(1)]; +      var fn = type ? type[[key.substring(1)]] : undefined; +      if (fn) { +        instance = _.bind(fn, lastInstance, lastInstance); +        return instance; +      } +    } +  } +  if (typeof instance === 'function' && !instance.$$factory) { +    return bind(lastInstance, instance); +  } +  return instance; +}; + +Scope.prototype.get = function(path) { +  return Scope.getter(this.state, path); +}; + +Scope.prototype.set = function(path, value) { +  var element = path.split('.'); +  var instance = this.state; +  for ( var i = 0; element.length > 1; i++) { +    var key = element.shift(); +    var newInstance = instance[key]; +    if (!newInstance) { +      newInstance = {}; +      instance[key] = newInstance; +    } +    instance = newInstance; +  } +  instance[element.shift()] = value; +  return value; +}; + +Scope.prototype.setEval = function(expressionText, value) { +  this.eval(expressionText + "=" + toJson(value)); +}; + +Scope.prototype.eval = function(expressionText, context) { +  var expression = Scope.expressionCache[expressionText]; +  if (!expression) { +    var parser = new Parser(expressionText); +    expression = parser.statements(); +    parser.assertAllConsumed(); +    Scope.expressionCache[expressionText] = expression; +  } +  context = context || {}; +  context.scope = this; +  return expression(context); +}; + +//TODO: Refactor. This function needs to be an execution closure for widgets +// move to widgets +// remove expression, just have inner closure. +Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) { +  try { +    var value = this.eval(expression, context); +    if (widget.hasError) { +      widget.hasError = false; +      jQuery(widget.view). +        removeClass('ng-exception'). +        removeAttr('ng-error'); +    } +    if (onSuccess) { +      value = onSuccess.apply(widget, [value]); +    } +    return true; +  } catch (e){ +    console.error('Eval Widget Error:', e); +    var jsonError = toJson(e, true); +    widget.hasError = true; +    jQuery(widget.view). +      addClass('ng-exception'). +      attr('ng-error', jsonError); +    if (onFailure) { +      onFailure.apply(widget, [e, jsonError]); +    } +    return false; +  } +}; + +Scope.prototype.validate = function(expressionText, value) { +  var expression = Scope.expressionCache[expressionText]; +  if (!expression) { +    expression = new Parser(expressionText).validator(); +    Scope.expressionCache[expressionText] = expression; +  } +  var self = {scope:this}; +  return expression(self)(self, value); +}; + +Scope.prototype.entity = function(entityDeclaration) { +  var expression = new Parser(entityDeclaration).entityDeclaration(); +  return expression({scope:this}); +}; + +Scope.prototype.markInvalid = function(widget) { +  this.state.$invalidWidgets.push(widget); +}; + +Scope.prototype.watch = function(declaration) { +  var self = this; +  new Parser(declaration).watch()({ +    scope:this, +    addListener:function(watch, exp){ +      self.addWatchListener(watch, function(n,o){ +        try { +          return exp({scope:self}, n, o); +        } catch(e) { +          alert(e); +        } +      }); +    } +  }); +}; + +Scope.prototype.addWatchListener = function(watchExpression, listener) { +  var watcher = this.watchListeners[watchExpression]; +  if (!watcher) { +    watcher = {listeners:[], expression:watchExpression}; +    this.watchListeners[watchExpression] = watcher; +  } +  watcher.listeners.push(listener); +}; + +Scope.prototype.fireWatchers = function() { +  var self = this; +  var fired = false; +  jQuery.each(this.watchListeners, function(name, watcher) { +    var value = self.eval(watcher.expression); +    if (value !== watcher.lastValue) { +      jQuery.each(watcher.listeners, function(i, listener){ +        listener(value, watcher.lastValue); +        fired = true; +      }); +      watcher.lastValue = value; +    } +  }); +  return fired; +}; +// Copyright (C) 2008,2009 BRAT Tech LLC + +Server = function(url, getScript) { +  this.url = url; +  this.nextId = 0; +  this.getScript = getScript; +  this.uuid = "_" + ("" + Math.random()).substr(2) + "_"; +  this.maxSize = 1800; +}; + +Server.prototype.base64url = function(txt) { +  return Base64.encode(txt); +}; + +Server.prototype.request = function(method, url, request, callback) { +  var requestId = this.uuid + (this.nextId++); +  nglr[requestId] = function(response) { +    delete nglr[requestId]; +    callback(200, response); +  }; +  var payload = {u:url, m:method, p:request}; +  payload = this.base64url(toJson(payload)); +  var totalPockets = Math.ceil(payload.length / this.maxSize); +  var baseUrl = this.url + "/$/" + requestId +  "/" + totalPockets + "/"; +  for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) { +    var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize); +    this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop); +  } +}; + +FrameServer = function(frame) { +  this.frame = frame; +}; +FrameServer.PREFIX = "$DATASET:"; + +FrameServer.prototype = { +  read:function(){ +    this.data = fromJson(this.frame.name.substr(FrameServer.PREFIX.length)); +  }, +  write:function(){ +    this.frame.name = FrameServer.PREFIX +  toJson(this.data); +  },  +  request: function(method, url, request, callback) { +    //alert(method + " " + url + " " + toJson(request) + " " + toJson(callback)); +  } +}; + + +VisualServer = function(delegate, status, update) { +  this.delegate = delegate; +  this.update = update; +  this.status = status; +}; + +VisualServer.prototype = { +  request:function(method, url, request, callback) { +    var self = this; +    this.status.beginRequest(request); +    this.delegate.request(method, url, request, function() { +      self.status.endRequest(); +      try { +        callback.apply(this, arguments); +      } catch (e) { +        alert(toJson(e)); +      } +      self.update(); +    }); +  } +}; +// Copyright (C) 2008,2009 BRAT Tech LLC +Users = function(server, controlBar) { +  this.server = server; +  this.controlBar = controlBar; +}; + +Users.prototype = { +  fetchCurrentUser:function(callback) { +    var self = this; +    this.server.request("GET", "/account.json", {}, function(code, response){ +      self.current = response.user; +      callback(response.user); +    }); +  }, +   +  logout: function(callback) { +    var self = this; +    this.controlBar.logout(function(){ +      delete self.current; +      (callback||noop)(); +    }); +  }, +   +  login: function(callback) { +    var self = this; +    this.controlBar.login(function(){ +      self.fetchCurrentUser(function(){ +        (callback||noop)(); +      }); +    }); +  }, + +  notAuthorized: function(){ +    this.controlBar.notAuthorized(); +  } +}; +// Copyright (C) 2009 BRAT Tech LLC + +angular.validator.regexp = function(value, regexp, msg) { +  if (!value.match(regexp)) { +    return msg || +      "Value does not match expected format " + regexp + "."; +  } else { +    return null; +  } +}; + +angular.validator.number = function(value, min, max) { +  var num = 1 * value; +  if (num == value) { +    if (typeof min != 'undefined' && num < min) { +      return "Value can not be less than " + min + "."; +    } +    if (typeof min != 'undefined' && num > max) { +      return "Value can not be greater than " + max + "."; +    } +    return null; +  } else { +    return "Value is not a number."; +  } +}; + +angular.validator.integer = function(value, min, max) { +  var number = angular.validator.number(value, min, max); +  if (number === null && value != Math.round(value)) { +    return "Value is not a whole number."; +  } +  return number; +}; + +angular.validator.date = function(value, min, max) { +  if (value.match(/^\d\d?\/\d\d?\/\d\d\d\d$/)) { +    return null; +  } +  return "Value is not a date. (Expecting format: 12/31/2009)."; +}; + +angular.validator.ssn = function(value) { +  if (value.match(/^\d\d\d-\d\d-\d\d\d\d$/)) { +    return null; +  } +  return "SSN needs to be in 999-99-9999 format."; +}; + +angular.validator.email = function(value) { +  if (value.match(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)) { +    return null; +  } +  return "Email needs to be in username@host.com format."; +}; + +angular.validator.phone = function(value) { +  if (value.match(/^1\(\d\d\d\)\d\d\d-\d\d\d\d$/)) { +    return null; +  } +  if (value.match(/^\+\d{2,3} (\(\d{1,5}\))?[\d ]+\d$/)) { +    return null; +  } +  return "Phone number needs to be in 1(987)654-3210 format in North America or +999 (123) 45678 906 internationaly."; +}; + +angular.validator.url = function(value) { +  if (value.match(/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/)) { +    return null; +  } +  return "URL needs to be in http://server[:port]/path format."; +}; + +angular.validator.json = function(value) { +  try { +    fromJson(value); +    return null; +  } catch (e) { +    return e.toString(); +  } +}; +// Copyright (C) 2009 BRAT Tech LLC + + +WidgetFactory = function(serverUrl, database) { +  this.nextUploadId = 0; +  this.serverUrl = serverUrl; +  this.database = database; +  this.createSWF = swfobject.createSWF; +  this.onChangeListener = function(){}; +}; + +WidgetFactory.prototype.createController = function(input, scope) { +  var controller; +  var type = input.attr('type').toLowerCase(); +  var exp = input.attr('name'); +  if (exp) exp = exp.split(':').pop(); +  var event = "change"; +  var bubbleEvent = true; +  if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') { +    controller = new ButtonController(input[0], exp); +    event = "click"; +    bubbleEvent = false; +  } else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') { +    controller = new TextController(input[0], exp); +    event = "keyup change"; +  } else if (type == 'checkbox') { +    controller = new CheckboxController(input[0], exp); +    event = "click"; +  } else if (type == 'radio') { +    controller = new RadioController(input[0], exp); +    event="click"; +  } else if (type == 'select-one') { +    controller = new SelectController(input[0], exp); +  } else if (type == 'select-multiple') { +    controller = new MultiSelectController(input[0], exp); +  } else if (type == 'file') { +    controller = this.createFileController(input, exp); +  } else { +    throw 'Unknown type: ' + type; +  } +  input.data('controller', controller); +  var binder = scope.get('$binder'); +  var action = function() { +    if (controller.updateModel(scope)) { +      var action = jQuery(controller.view).attr('ng-action') || ""; +      if (scope.evalWidget(controller, action)) { +        binder.updateView(scope); +      } +    } +    return bubbleEvent; +  }; +  jQuery(controller.view, ":input"). +    bind(event, action); +  return controller; +}; + +WidgetFactory.prototype.createFileController = function(fileInput) { +  var uploadId = '__uploadWidget_' + (this.nextUploadId++); +  var view = FileController.template(uploadId); +  fileInput.after(view); +  var att = { +      data:this.serverUrl + "/admin/ServerAPI.swf", +      width:"95", height:"20", align:"top", +      wmode:"transparent"}; +  var par = { +      flashvars:"uploadWidgetId=" + uploadId, +      allowScriptAccess:"always"}; +  var swfNode = this.createSWF(att, par, uploadId); +  fileInput.remove(); +  var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database); +  jQuery(swfNode).data('controller', cntl); +  return cntl; +}; + +WidgetFactory.prototype.createTextWidget = function(textInput) { +  var controller = new TextController(textInput); +  controller.onChange(this.onChangeListener); +  return controller; +}; + +///////////////////// +// FileController +/////////////////////// + +FileController = function(view, scopeName, uploader, databaseUrl) { +  this.view = view; +  this.uploader = uploader; +  this.scopeName = scopeName; +  this.attachmentsPath = databaseUrl + '/_attachments'; +  this.value = null; +  this.lastValue = undefined; +}; + +FileController.dispatchEvent = function(id, event, args) { +  var object = document.getElementById(id); +  var controller = jQuery(object).data("controller"); +  FileController.prototype['_on_' + event].apply(controller, args); +}; + +FileController.template = function(id) { +  return jQuery('<span class="ng-upload-widget">' + +      '<input type="checkbox" ng-non-bindable="true"/>' + +      '<object id="' + id + '" />' + +      '<a></a>' + +      '<span/>' + +    '</span>'); +}; + +FileController.prototype._on_cancel = function() { +}; + +FileController.prototype._on_complete = function() { +}; + +FileController.prototype._on_httpStatus = function(status) { +  alert("httpStatus:" + this.scopeName + " status:" + status); +}; + +FileController.prototype._on_ioError = function() { +  alert("ioError:" + this.scopeName); +}; + +FileController.prototype._on_open = function() { +  alert("open:" + this.scopeName); +}; + +FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) { +}; + +FileController.prototype._on_securityError = function() { +  alert("securityError:" + this.scopeName); +}; + +FileController.prototype._on_uploadCompleteData = function(data) { +  var value = fromJson(data); +  value.url = this.attachmentsPath + '/' + value.id + '/' + value.text; +  this.view.find("input").attr('checked', true); +  var scope = this.view.scope(); +  this.value = value; +  this.updateModel(scope); +  this.value = null; +  scope.get('$binder').updateView(); +}; + +FileController.prototype._on_select = function(name, size, type) { +  this.name = name; +  this.view.find("a").text(name).attr('href', name); +  this.view.find("span").text(angular.filter.bytes(size)); +  this.upload(); +}; + +FileController.prototype.updateModel = function(scope) { +  var isChecked = this.view.find("input").attr('checked'); +  var value = isChecked ? this.value : null; +  if (this.lastValue === value) { +    return false; +  } else { +    scope.set(this.scopeName, value); +    return true; +  } +}; + +FileController.prototype.updateView = function(scope) { +  var modelValue = scope.get(this.scopeName); +  if (modelValue && this.value !== modelValue) { +    this.value = modelValue; +    this.view.find("a"). +      attr("href", this.value.url). +      text(this.value.text); +    this.view.find("span").text(angular.filter.bytes(this.value.size)); +  } +  this.view.find("input").attr('checked', !!modelValue); +}; + +FileController.prototype.upload = function() { +  if (this.name) { +    this.uploader.uploadFile(this.attachmentsPath); +  } +}; + + +/////////////////////// +// NullController +/////////////////////// +NullController = function(view) {this.view = view;}; +NullController.prototype.updateModel = function() { return true; }; +NullController.prototype.updateView = function() { }; +NullController.instance = new NullController(); + + +/////////////////////// +// ButtonController +/////////////////////// +ButtonController = function(view) {this.view = view;}; +ButtonController.prototype.updateModel = function(scope) { return true; }; +ButtonController.prototype.updateView = function(scope) {}; + +/////////////////////// +// TextController +/////////////////////// +TextController = function(view, exp) { +  this.view = view; +  this.exp = exp; +  this.validator = view.getAttribute('ng-validate'); +  this.required = typeof view.attributes['ng-required'] != "undefined"; +  this.lastErrorText = null; +  this.lastValue = undefined; +  this.initialValue = view.value; +  var widget = view.getAttribute('ng-widget'); +  if (widget === 'datepicker') { +    jQuery(view).datepicker(); +  } +}; + +TextController.prototype.updateModel = function(scope) { +  var value = this.view.value; +  if (this.lastValue === value) { +    return false; +  } else { +    scope.setEval(this.exp, value); +    this.lastValue = value; +    return true; +  } +}; + +TextController.prototype.updateView = function(scope) { +  var view = this.view; +  var value = scope.get(this.exp); +  if (typeof value === "undefined") { +    value = this.initialValue; +    scope.setEval(this.exp, value); +  } +  value = value ? value : ''; +  if (this.lastValue != value) { +    view.value = value; +    this.lastValue = value; +  } +  var isValidationError = false; +  view.removeAttribute('ng-error'); +  if (this.required) { +    isValidationError = !(value && value.length > 0); +  } +  var errorText = isValidationError ? "Required Value" : null; +  if (!isValidationError && this.validator && value) { +    errorText = scope.validate(this.validator, value); +    isValidationError = !!errorText; +  } +  if (this.lastErrorText !== errorText) { +    this.lastErrorText = isValidationError; +    if (errorText !== null) { +      view.setAttribute('ng-error', errorText); +      scope.markInvalid(this); +    } +    jQuery(view).toggleClass('ng-validation-error', isValidationError); +  } +}; + +/////////////////////// +// CheckboxController +/////////////////////// +CheckboxController = function(view, exp) { +  this.view = view; +  this.exp = exp; +  this.lastValue = undefined; +  this.initialValue = view.checked ? view.value : ""; +}; + +CheckboxController.prototype.updateModel = function(scope) { +  var input = this.view; +  var value = input.checked ? input.value : ''; +  if (this.lastValue === value) { +    return false; +  } else { +    scope.setEval(this.exp, value); +    this.lastValue = value; +    return true; +  } +}; + +CheckboxController.prototype.updateView = function(scope) { +  var input = this.view; +  var value = scope.eval(this.exp); +  if (typeof value === "undefined") { +    value = this.initialValue; +    scope.setEval(this.exp, value); +  } +  input.checked = input.value == (''+value); +}; + +/////////////////////// +// SelectController +/////////////////////// +SelectController = function(view, exp) { +  this.view = view; +  this.exp = exp; +  this.lastValue = undefined; +  this.initialValue = view.value; +}; + +SelectController.prototype.updateModel = function(scope) { +  var input = this.view; +  if (input.selectedIndex < 0) { +    scope.setEval(this.exp, null); +  } else { +    var value = this.view.value; +    if (this.lastValue === value) { +      return false; +    } else { +      scope.setEval(this.exp, value); +      this.lastValue = value; +      return true; +    } +  } +}; + +SelectController.prototype.updateView = function(scope) { +  var input = this.view; +  var value = scope.get(this.exp); +  if (typeof value === 'undefined') { +    value = this.initialValue; +    scope.setEval(this.exp, value); +  } +  if (value !== this.lastValue) { +    input.value = value ? value : ""; +    this.lastValue = value; +  } +}; + +/////////////////////// +// MultiSelectController +/////////////////////// +MultiSelectController = function(view, exp) { +  this.view = view; +  this.exp = exp; +  this.lastValue = undefined; +  this.initialValue = this.selected(); +}; + +MultiSelectController.prototype.selected = function () { +  var value = []; +  var options = this.view.options; +  for ( var i = 0; i < options.length; i++) { +    var option = options[i]; +    if (option.selected) { +      value.push(option.value); +    } +  } +  return value; +}; + +MultiSelectController.prototype.updateModel = function(scope) { +  var value = this.selected(); +  // TODO: This is wrong! no caching going on here as we are always comparing arrays +  if (this.lastValue === value) { +    return false; +  } else { +    scope.setEval(this.exp, value); +    this.lastValue = value; +    return true; +  } +}; + +MultiSelectController.prototype.updateView = function(scope) { +  var input = this.view; +  var selected = scope.get(this.exp); +  if (typeof selected === "undefined") { +    selected = this.initialValue; +    scope.setEval(this.exp, selected); +  } +  if (selected !== this.lastValue) { +    var options = input.options; +    for ( var i = 0; i < options.length; i++) { +      var option = options[i]; +      option.selected = _.include(selected, option.value); +    } +    this.lastValue = selected; +  } +}; + +/////////////////////// +// RadioController +/////////////////////// +RadioController = function(view, exp) { +  this.view = view; +  this.exp = exp; +  this.lastChecked = undefined; +  this.lastValue = undefined; +  this.inputValue = view.value; +  this.initialValue = view.checked ? view.value : null; +}; + +RadioController.prototype.updateModel = function(scope) { +  var input = this.view; +  if (this.lastChecked) { +    return false; +  } else { +    input.checked = true; +    this.lastValue = scope.setEval(this.exp, this.inputValue); +    this.lastChecked = true; +    return true; +  } +}; + +RadioController.prototype.updateView = function(scope) { +  var input = this.view; +  var value = scope.get(this.exp); +  if (this.initialValue && typeof value === "undefined") { +    value = this.initialValue; +    scope.setEval(this.exp, value); +  } +  if (this.lastValue != value) { +    this.lastChecked = input.checked = this.inputValue == (''+value); +    this.lastValue = value; +  } +}; + +/////////////////////// +//ElementController +/////////////////////// +BindUpdater = function(view, exp) { +  this.view = view; +  this.exp = Binder.parseBindings(exp); +  this.hasError = false; +  this.scopeSelf = {element:view}; +}; + +BindUpdater.toText = function(obj) { +  var e = escapeHtml; +  switch(typeof obj) { +    case "string": +    case "boolean": +    case "number": +      return e(obj); +    case "function": +      return BindUpdater.toText(obj()); +    case "object": +      if (isNode(obj)) { +        return outerHTML(obj); +      } else if (obj instanceof angular.filter.Meta) { +        switch(typeof obj.html) { +          case "string": +          case "number": +            return obj.html; +          case "function": +            return obj.html(); +          case "object": +            if (isNode(obj.html)) +              return outerHTML(obj.html); +          default: +            break; +        } +        switch(typeof obj.text) { +          case "string": +          case "number": +            return e(obj.text); +          case "function": +            return e(obj.text()); +          default: +            break; +        } +      } +      if (obj === null) +        return ""; +      return e(toJson(obj, true)); +    default: +      return ""; +  } +}; + +BindUpdater.prototype.updateModel = function(scope) {}; +BindUpdater.prototype.updateView = function(scope) { +  var html = []; +  var parts = this.exp; +  var length = parts.length; +  for(var i=0; i<length; i++) { +    var part = parts[i]; +    var binding = Binder.binding(part); +    if (binding) { +      scope.evalWidget(this, binding, this.scopeSelf, function(value){ +        html.push(BindUpdater.toText(value)); +      }, function(e, text){ +        setHtml(this.view, text); +      }); +      if (this.hasError) { +        return; +      } +    } else { +      html.push(escapeHtml(part)); +    } +  } +  setHtml(this.view, html.join('')); +}; + +BindAttrUpdater = function(view, attrs) { +  this.view = view; +  this.attrs = attrs; +}; + +BindAttrUpdater.prototype.updateModel = function(scope) {}; +BindAttrUpdater.prototype.updateView = function(scope) { +  var jNode = jQuery(this.view); +  var attributeTemplates = this.attrs; +  if (this.hasError) { +    this.hasError = false; +    jNode. +      removeClass('ng-exception'). +      removeAttr('ng-error'); +  } +  var isImage = jNode.is('img'); +  for (var attrName in attributeTemplates) { +    var attributeTemplate = Binder.parseBindings(attributeTemplates[attrName]); +    var attrValues = []; +    for ( var i = 0; i < attributeTemplate.length; i++) { +      var binding = Binder.binding(attributeTemplate[i]); +      if (binding) { +        try { +          var value = scope.eval(binding, {element:jNode[0], attrName:attrName}); +          if (value && (value.constructor !== array || value.length !== 0)) +            attrValues.push(value); +        } catch (e) { +          this.hasError = true; +          console.error('BindAttrUpdater', e); +          var jsonError = toJson(e, true); +          attrValues.push('[' + jsonError + ']'); +          jNode. +            addClass('ng-exception'). +            attr('ng-error', jsonError); +        } +      } else { +        attrValues.push(attributeTemplate[i]); +      } +    } +    var attrValue = attrValues.length ? attrValues.join('') : null; +    if(isImage && attrName == 'src' && !attrValue) +      attrValue = scope.get('config.server') + '/images/blank.gif'; +    jNode.attr(attrName, attrValue); +  } +}; + +EvalUpdater = function(view, exp) { +  this.view = view; +  this.exp = exp; +  this.hasError = false; +}; +EvalUpdater.prototype.updateModel = function(scope) {}; +EvalUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp); +}; + +HideUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +HideUpdater.prototype.updateModel = function(scope) {}; +HideUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp, {}, function(hideValue){ +    var view = jQuery(this.view); +    if (toBoolean(hideValue)) { +      view.hide(); +    } else { +      view.show(); +    } +  }); +}; + +ShowUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ShowUpdater.prototype.updateModel = function(scope) {}; +ShowUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp, {}, function(hideValue){ +    var view = jQuery(this.view); +    if (toBoolean(hideValue)) { +      view.show(); +    } else { +      view.hide(); +    } +  }); +}; + +ClassUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ClassUpdater.prototype.updateModel = function(scope) {}; +ClassUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp, {}, function(classValue){ +    if (classValue !== null && classValue !== undefined) { +      this.view.className = classValue; +    } +  }); +}; + +ClassEvenUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ClassEvenUpdater.prototype.updateModel = function(scope) {}; +ClassEvenUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp, {}, function(classValue){ +    var index = scope.get('$index'); +    jQuery(this.view).toggleClass(classValue, index % 2 === 1); +  }); +}; + +ClassOddUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ClassOddUpdater.prototype.updateModel = function(scope) {}; +ClassOddUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp, {}, function(classValue){ +    var index = scope.get('$index'); +    jQuery(this.view).toggleClass(classValue, index % 2 === 0); +  }); +}; + +StyleUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +StyleUpdater.prototype.updateModel = function(scope) {}; +StyleUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.exp, {}, function(styleValue){ +    jQuery(this.view).attr('style', "").css(styleValue); +  }); +}; + +/////////////////////// +// RepeaterUpdater +/////////////////////// +RepeaterUpdater = function(view, repeaterExpression, template, prefix) { +  this.view = view; +  this.template = template; +  this.prefix = prefix; +  this.children = []; +  var match = repeaterExpression.match(/^\s*(.+)\s+in\s+(.*)\s*$/); +  if (! match) { +    throw "Expected ng-repeat in form of 'item in collection' but got '" + +      repeaterExpression + "'."; +  } +  var keyValue = match[1]; +  this.iteratorExp = match[2]; +  match = keyValue.match(/^([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\)$/); +  if (!match) { +    throw "'item' in 'item in collection' should be identifier or (key, value) but get '" + +      keyValue + "'."; +  } +  this.valueExp = match[3] || match[1]; +  this.keyExp = match[2]; +}; + +RepeaterUpdater.prototype.updateModel = function(scope) {}; +RepeaterUpdater.prototype.updateView = function(scope) { +  scope.evalWidget(this, this.iteratorExp, {}, function(iterator){ +    var self = this; +    if (!iterator) { +      iterator = []; +      if (scope.isProperty(this.iteratorExp)) { +        scope.set(this.iteratorExp, iterator); +      } +    } +    var iteratorLength = iterator.length; +    var childrenLength = this.children.length; +    var cursor = this.view; +    var time = 0; +    var child = null; +    var keyExp = this.keyExp; +    var valueExp = this.valueExp; +    var i = 0; +    jQuery.each(iterator, function(key, value){ +      if (i < childrenLength) { +        // reuse children +        child = self.children[i]; +        child.scope.set(valueExp, value); +      } else { +        // grow children +        var name = self.prefix + +          valueExp + " in " + self.iteratorExp + "[" + i + "]"; +        var childScope = new Scope(scope.state, name); +        childScope.set('$index', i); +        if (keyExp) +          childScope.set(keyExp, key); +        childScope.set(valueExp, value); +        child = { scope:childScope, element:self.template(childScope, self.prefix, i) }; +        cursor.after(child.element); +        self.children.push(child); +      } +      cursor = child.element; +      var s = new Date().getTime(); +      child.scope.updateView(); +      time += new Date().getTime() - s; +      i++; +    }); +    // shrink children +    for ( var r = childrenLength; r > iteratorLength; --r) { +      var unneeded = this.children.pop(); +      unneeded.element.removeNode(); +    } +    // Special case for option in select +    if (child && child.element[0].nodeName === "OPTION") { +      var select = jQuery(child.element[0].parentNode); +      var cntl = select.data('controller'); +      if (cntl) { +        cntl.lastValue = undefined; +        cntl.updateView(scope); +      } +    } +  }); +}; + +////////////////////////////////// +// PopUp +////////////////////////////////// + +PopUp = function(doc) { +  this.doc = doc; +}; + +PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup"; + +PopUp.prototype.bind = function () { +  var self = this; +  this.doc.find('.ng-validation-error,.ng-exception'). +    live("mouseover", PopUp.onOver); +}; + +PopUp.onOver = function(e) { +  PopUp.onOut(); +  var jNode = jQuery(this); +  jNode.bind(PopUp.OUT_EVENT, PopUp.onOut); +  var position = jNode.position(); +  var de = document.documentElement; +  var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; +  var hasArea = w - position.left; +  var width = 300; +  var title = jNode.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error..."; +  var msg = jNode.attr("ng-error"); + +  var x; +  var arrowPos = hasArea>(width+75) ? "left" : "right"; +  var tip = jQuery( +    "<div id='ng-callout' style='width:"+width+"px'>" + +      "<div class='ng-arrow-"+arrowPos+"'/>" + +      "<div class='ng-title'>"+title+"</div>" + +      "<div class='ng-content'>"+msg+"</div>" + +    "</div>"); +  jQuery("body").append(tip); +  if(arrowPos === 'left'){ +    x = position.left + this.offsetWidth + 11; +  }else{ +    x = position.left - (width + 15); +    tip.find('.ng-arrow-right').css({left:width+1}); +  } + +  tip.css({left: x+"px", top: (position.top - 3)+"px"}); +  return true; +}; + +PopUp.onOut = function() { +  jQuery('#ng-callout'). +    unbind(PopUp.OUT_EVENT, PopUp.onOut). +    remove(); +  return true; +}; + +////////////////////////////////// +// Status +////////////////////////////////// + + +Status = function(body) { +  this.loader = body.append(Status.DOM).find("#ng-loading"); +  this.requestCount = 0; +}; + +Status.DOM ='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>'; + +Status.prototype.beginRequest = function () { +  if (this.requestCount === 0) { +    this.loader.show(); +  } +  this.requestCount++; +}; + +Status.prototype.endRequest = function () { +  this.requestCount--; +  if (this.requestCount === 0) { +    this.loader.hide("fold"); +  } +}; +})(window, document);
\ No newline at end of file diff --git a/jsTestDriver.conf b/jsTestDriver.conf index 97136e7b..ebd45d9d 100644 --- a/jsTestDriver.conf +++ b/jsTestDriver.conf @@ -15,3 +15,6 @@ load:  exclude:    - src/angular-bootstrap.js +  - src/angular.prefix +  - src/angular.suffix +  
\ No newline at end of file diff --git a/lib/shrinksafe/js.jar b/lib/shrinksafe/js.jar Binary files differdeleted file mode 100644 index c081d16b..00000000 --- a/lib/shrinksafe/js.jar +++ /dev/null diff --git a/lib/shrinksafe/shrinksafe.jar b/lib/shrinksafe/shrinksafe.jar Binary files differdeleted file mode 100644 index eeb7b14e..00000000 --- a/lib/shrinksafe/shrinksafe.jar +++ /dev/null @@ -66,7 +66,7 @@ angular.Array = {        }        return true;      }; -    var getter = nglr.Scope.getter; +    var getter = Scope.getter;      var search = function(obj, text){        if (text.charAt(0) === '!') {          return !search(obj, text.substr(1)); @@ -147,7 +147,7 @@ angular.Array = {    },    orderBy:function(array, expression, descend) {      function reverse(comp, descending) { -      return nglr.toBoolean(descending) ?  +      return toBoolean(descending) ?             function(a,b){return comp(b,a);} : comp;      }      function compare(v1, v2){ @@ -224,7 +224,7 @@ angular.Array = {        value = {};        array[index] = value;      } -    nglr.merge(mergeValue, value); +    merge(mergeValue, value);      return array;    }  }; @@ -281,7 +281,7 @@ angular.Function = {      if (_.isFunction(expression)){        return expression;      } else if (expression){ -      var scope = new nglr.Scope(); +      var scope = new Scope();        return function($) {          scope.state = $;          return scope.eval(expression); diff --git a/src/Binder.js b/src/Binder.js index 8b4d27fb..3589cb88 100644 --- a/src/Binder.js +++ b/src/Binder.js @@ -1,5 +1,5 @@  // Copyright (C) 2009 BRAT Tech LLC -nglr.Binder = function(doc, widgetFactory, urlWatcher, config) { +Binder = function(doc, widgetFactory, urlWatcher, config) {    this.doc = doc;    this.urlWatcher = urlWatcher;    this.anchor = {}; @@ -8,7 +8,7 @@ nglr.Binder = function(doc, widgetFactory, urlWatcher, config) {    this.updateListeners = [];  }; -nglr.Binder.parseBindings = function(string) { +Binder.parseBindings = function(string) {    var results = [];    var lastIndex = 0;    var index; @@ -28,18 +28,18 @@ nglr.Binder.parseBindings = function(string) {    return results.length === 0 ? [ string ] : results;  }; -nglr.Binder.hasBinding = function(string) { -  var bindings = nglr.Binder.parseBindings(string); -  return bindings.length > 1 || nglr.Binder.binding(bindings[0]) !== null; +Binder.hasBinding = function(string) { +  var bindings = Binder.parseBindings(string); +  return bindings.length > 1 || Binder.binding(bindings[0]) !== null;  }; -nglr.Binder.binding = function(string) { +Binder.binding = function(string) {    var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/);    return binding ? binding[1] : null;  }; -nglr.Binder.prototype.parseQueryString = function(query) { +Binder.prototype.parseQueryString = function(query) {    var params = {};    query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,        function (match, left, right) { @@ -48,7 +48,7 @@ nglr.Binder.prototype.parseQueryString = function(query) {    return params;  }; -nglr.Binder.prototype.parseAnchor = function(url) { +Binder.prototype.parseAnchor = function(url) {    var self = this;    url = url || this.urlWatcher.getUrl(); @@ -65,13 +65,13 @@ nglr.Binder.prototype.parseAnchor = function(url) {    });  }; -nglr.Binder.prototype.onUrlChange = function (url) { +Binder.prototype.onUrlChange = function (url) {    console.log("URL change detected", url);    this.parseAnchor(url);    this.updateView();  }; -nglr.Binder.prototype.updateAnchor = function() { +Binder.prototype.updateAnchor = function() {    var url = this.urlWatcher.getUrl();    var anchorIndex = url.indexOf('#');    if (anchorIndex > -1) @@ -93,7 +93,7 @@ nglr.Binder.prototype.updateAnchor = function() {    return url;  }; -nglr.Binder.prototype.updateView = function() { +Binder.prototype.updateView = function() {    var start = new Date().getTime();    var scope = jQuery(this.doc).scope();    scope.set("$invalidWidgets", []); @@ -103,7 +103,7 @@ nglr.Binder.prototype.updateView = function() {    _.each(this.updateListeners, function(fn) {fn();});  }; -nglr.Binder.prototype.docFindWithSelf = function(exp){ +Binder.prototype.docFindWithSelf = function(exp){    var doc = jQuery(this.doc);    var selection = doc.find(exp);    if (doc.is(exp)){ @@ -112,31 +112,31 @@ nglr.Binder.prototype.docFindWithSelf = function(exp){    return selection;  }; -nglr.Binder.prototype.executeInit = function() { +Binder.prototype.executeInit = function() {    this.docFindWithSelf("[ng-init]").each(function() {      var jThis = jQuery(this);      var scope = jThis.scope();      try {        scope.eval(jThis.attr('ng-init'));      } catch (e) { -      nglr.alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + nglr.toJson(e, true)); +      alert("EVAL ERROR:\n" + jThis.attr('ng-init') + '\n' + toJson(e, true));      }    });  }; -nglr.Binder.prototype.entity = function (scope) { +Binder.prototype.entity = function (scope) {    this.docFindWithSelf("[ng-entity]").attr("ng-watch", function() {      try {        var jNode = jQuery(this);        var decl = scope.entity(jNode.attr("ng-entity"));        return decl + (jNode.attr('ng-watch') || "");      } catch (e) { -      nglr.alert(e); +      alert(e);      }    });  }; -nglr.Binder.prototype.compile = function() { +Binder.prototype.compile = function() {    var jNode = jQuery(this.doc);    var self = this;    if (this.config.autoSubmit) { @@ -153,37 +153,37 @@ nglr.Binder.prototype.compile = function() {        jNode.removeClass("ng-exception");      } catch (e) {        jNode.addClass("ng-exception"); -      jNode.attr('ng-error', nglr.toJson(e, true)); +      jNode.attr('ng-error', toJson(e, true));      }      self.updateView();      return false;    });  }; -nglr.Binder.prototype.translateBinding = function(node, parentPath, factories) { +Binder.prototype.translateBinding = function(node, parentPath, factories) {    var path = parentPath.concat();    var offset = path.pop(); -  var parts = nglr.Binder.parseBindings(node.nodeValue); -  if (parts.length > 1 || nglr.Binder.binding(parts[0])) { +  var parts = Binder.parseBindings(node.nodeValue); +  if (parts.length > 1 || Binder.binding(parts[0])) {      var parent = node.parentNode; -    if (nglr.isLeafNode(parent)) { +    if (isLeafNode(parent)) {        parent.setAttribute('ng-bind-template', node.nodeValue);        factories.push({path:path, fn:function(node, scope, prefix) { -        return new nglr.BindUpdater(node, node.getAttribute('ng-bind-template')); +        return new BindUpdater(node, node.getAttribute('ng-bind-template'));        }});      } else {        for (var i = 0; i < parts.length; i++) {          var part = parts[i]; -        var binding = nglr.Binder.binding(part); +        var binding = Binder.binding(part);          var newNode;          if (binding) {            newNode = document.createElement("span");            var jNewNode = jQuery(newNode);            jNewNode.attr("ng-bind", binding);            if (i === 0) { -            factories.push({path:path.concat(offset + i), fn:nglr.Binder.prototype.ng_bind}); +            factories.push({path:path.concat(offset + i), fn:Binder.prototype.ng_bind});            } -        } else if (nglr.msie && part.charAt(0) == ' ') { +        } else if (msie && part.charAt(0) == ' ') {            newNode = document.createElement("span");            newNode.innerHTML = ' ' + part.substring(1);          } else { @@ -196,7 +196,7 @@ nglr.Binder.prototype.translateBinding = function(node, parentPath, factories) {    }  }; -nglr.Binder.prototype.precompile = function(root) { +Binder.prototype.precompile = function(root) {    var factories = [];    this.precompileNode(root, [], factories);    return function (template, scope, prefix) { @@ -211,13 +211,13 @@ nglr.Binder.prototype.precompile = function(root) {        try {          scope.addWidget(factory.fn(node, scope, prefix));        } catch (e) { -        nglr.alert(e); +        alert(e);        }      }    };  }; -nglr.Binder.prototype.precompileNode = function(node, path, factories) { +Binder.prototype.precompileNode = function(node, path, factories) {    var nodeType = node.nodeType;    if (nodeType == Node.TEXT_NODE) {      this.translateBinding(node, path, factories); @@ -234,19 +234,19 @@ nglr.Binder.prototype.precompileNode = function(node, path, factories) {    if (attributes) {      var bindings = node.getAttribute('ng-bind-attr');      node.removeAttribute('ng-bind-attr'); -    bindings = bindings ? nglr.fromJson(bindings) : {}; +    bindings = bindings ? fromJson(bindings) : {};      var attrLen = attributes.length;      for (var i = 0; i < attrLen; i++) {        var attr = attributes[i];        var attrName = attr.name;        // http://www.glennjones.net/Post/809/getAttributehrefbug.htm -      var attrValue = nglr.msie && attrName == 'href' ? +      var attrValue = msie && attrName == 'href' ?                        decodeURI(node.getAttribute(attrName, 2)) : attr.value; -      if (nglr.Binder.hasBinding(attrValue)) { +      if (Binder.hasBinding(attrValue)) {          bindings[attrName] = attrValue;        }      } -    var json = nglr.toJson(bindings); +    var json = toJson(bindings);      if (json.length > 2) {        node.setAttribute("ng-bind-attr", json);      } @@ -270,7 +270,7 @@ nglr.Binder.prototype.precompileNode = function(node, path, factories) {        return clone;      };      factories.push({path:path, fn:function(node, scope, prefix) { -      return new nglr.RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix); +      return new RepeaterUpdater(jQuery(node), repeaterExpression, template, prefix);      }});      return;    } @@ -309,42 +309,42 @@ nglr.Binder.prototype.precompileNode = function(node, path, factories) {    }  }; -nglr.Binder.prototype.ng_eval = function(node) { -  return new nglr.EvalUpdater(node, node.getAttribute('ng-eval')); +Binder.prototype.ng_eval = function(node) { +  return new EvalUpdater(node, node.getAttribute('ng-eval'));  }; -nglr.Binder.prototype.ng_bind = function(node) { -  return new nglr.BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}"); +Binder.prototype.ng_bind = function(node) { +  return new BindUpdater(node, "{{" + node.getAttribute('ng-bind') + "}}");  }; -nglr.Binder.prototype.ng_bind_attr = function(node) { -  return new nglr.BindAttrUpdater(node, nglr.fromJson(node.getAttribute('ng-bind-attr'))); +Binder.prototype.ng_bind_attr = function(node) { +  return new BindAttrUpdater(node, fromJson(node.getAttribute('ng-bind-attr')));  }; -nglr.Binder.prototype.ng_hide = function(node) { -  return new nglr.HideUpdater(node, node.getAttribute('ng-hide')); +Binder.prototype.ng_hide = function(node) { +  return new HideUpdater(node, node.getAttribute('ng-hide'));  }; -nglr.Binder.prototype.ng_show = function(node) { -  return new nglr.ShowUpdater(node, node.getAttribute('ng-show')); +Binder.prototype.ng_show = function(node) { +  return new ShowUpdater(node, node.getAttribute('ng-show'));  }; -nglr.Binder.prototype.ng_class = function(node) { -  return new nglr.ClassUpdater(node, node.getAttribute('ng-class')); +Binder.prototype.ng_class = function(node) { +  return new ClassUpdater(node, node.getAttribute('ng-class'));  }; -nglr.Binder.prototype.ng_class_even = function(node) { -  return new nglr.ClassEvenUpdater(node, node.getAttribute('ng-class-even')); +Binder.prototype.ng_class_even = function(node) { +  return new ClassEvenUpdater(node, node.getAttribute('ng-class-even'));  }; -nglr.Binder.prototype.ng_class_odd = function(node) { -  return new nglr.ClassOddUpdater(node, node.getAttribute('ng-class-odd')); +Binder.prototype.ng_class_odd = function(node) { +  return new ClassOddUpdater(node, node.getAttribute('ng-class-odd'));  }; -nglr.Binder.prototype.ng_style = function(node) { -  return new nglr.StyleUpdater(node, node.getAttribute('ng-style')); +Binder.prototype.ng_style = function(node) { +  return new StyleUpdater(node, node.getAttribute('ng-style'));  }; -nglr.Binder.prototype.ng_watch = function(node, scope) { +Binder.prototype.ng_watch = function(node, scope) {    scope.watch(node.getAttribute('ng-watch'));  }; diff --git a/src/ControlBar.js b/src/ControlBar.js index 3e1f0b57..b66a1464 100644 --- a/src/ControlBar.js +++ b/src/ControlBar.js @@ -1,16 +1,16 @@  // Copyright (C) 2008,2009 BRAT Tech LLC -nglr.ControlBar = function (document, serverUrl) { +ControlBar = function (document, serverUrl) {    this.document = document;    this.serverUrl = serverUrl;    this.window = window;    this.callbacks = [];  }; -nglr.ControlBar.prototype.bind = function () { +ControlBar.prototype.bind = function () {  }; -nglr.ControlBar.HTML = +ControlBar.HTML =    '<div>' +      '<div class="ui-widget-overlay"></div>' +      '<div id="ng-login" ng-non-bindable="true">' + @@ -18,25 +18,25 @@ nglr.ControlBar.HTML =      '</div>' +    '</div>'; -nglr.ControlBar.prototype.login = function (loginSubmitFn) { +ControlBar.prototype.login = function (loginSubmitFn) {    this.callbacks.push(loginSubmitFn);    if (this.callbacks.length == 1) {      this.doTemplate("/user_session/new.mini?return_url=" + encodeURIComponent(this.urlWithoutAnchor()));    }  }; -nglr.ControlBar.prototype.logout = function (loginSubmitFn) { +ControlBar.prototype.logout = function (loginSubmitFn) {    this.callbacks.push(loginSubmitFn);    if (this.callbacks.length == 1) {      this.doTemplate("/user_session/do_destroy.mini");    }  }; -nglr.ControlBar.prototype.urlWithoutAnchor = function (path) { +ControlBar.prototype.urlWithoutAnchor = function (path) {    return this.window.location.href.split("#")[0];  }; -nglr.ControlBar.prototype.doTemplate = function (path) { +ControlBar.prototype.doTemplate = function (path) {    var self = this;    var id = new Date().getTime();    var url = this.urlWithoutAnchor(); @@ -49,7 +49,7 @@ nglr.ControlBar.prototype.doTemplate = function (path) {      resizable: false, modal:true,      title: 'Authentication: <a href="http://www.getangular.com"><tt><angular/></tt></a>'    }); -  nglr["_iframe_notify_" + id] = function() { +  callbacks["_iframe_notify_" + id] = function() {      loginView.dialog("destroy");      loginView.remove();      jQuery.each(self.callbacks, function(i, callback){ @@ -59,13 +59,13 @@ nglr.ControlBar.prototype.doTemplate = function (path) {    };  }; -nglr.ControlBar.FORBIDEN = +ControlBar.FORBIDEN =    '<div ng-non-bindable="true" title="Permission Error:">' +      'Sorry, you do not have permission for this!'+    '</div>'; -nglr.ControlBar.prototype.notAuthorized = function () { +ControlBar.prototype.notAuthorized = function () {    if (this.forbidenView) return; -  this.forbidenView = jQuery(nglr.ControlBar.FORBIDEN); +  this.forbidenView = jQuery(ControlBar.FORBIDEN);    this.forbidenView.dialog({bgiframe:true, height:70, modal:true});  }; diff --git a/src/DataStore.js b/src/DataStore.js index 97ab92ff..bdf882a0 100644 --- a/src/DataStore.js +++ b/src/DataStore.js @@ -1,6 +1,6 @@  // Copyright (C) 2009 BRAT Tech LLC -nglr.DataStore = function(post, users, anchor) { +DataStore = function(post, users, anchor) {    this.post = post;    this.users = users;    this._cache = {$collections:[]}; @@ -8,14 +8,14 @@ nglr.DataStore = function(post, users, anchor) {    this.bulkRequest = [];  }; -nglr.DataStore.prototype.cache = function(document) { -  if (document.constructor != nglr.Model) { -    throw "Parameter must be an instance of Entity! " + nglr.toJson(document); +DataStore.prototype.cache = function(document) { +  if (document.constructor != Model) { +    throw "Parameter must be an instance of Entity! " + toJson(document);    }    var key = document.$entity + '/' + document.$id;    var cachedDocument = this._cache[key];    if (cachedDocument) { -    nglr.Model.copyDirectFields(document, cachedDocument); +    Model.copyDirectFields(document, cachedDocument);    } else {      this._cache[key] = document;      cachedDocument = document; @@ -23,7 +23,7 @@ nglr.DataStore.prototype.cache = function(document) {    return cachedDocument;  }; -nglr.DataStore.prototype.load = function(instance, id, callback, failure) { +DataStore.prototype.load = function(instance, id, callback, failure) {    if (id && id !== '*') {      var self = this;      this._jsonRequest(["GET", instance.$entity + "/" + id], function(response) { @@ -31,13 +31,13 @@ nglr.DataStore.prototype.load = function(instance, id, callback, failure) {        instance.$migrate();        var clone = instance.$$entity(instance);        self.cache(clone); -      (callback||nglr.noop)(instance); +      (callback||noop)(instance);      }, failure);    }    return instance;  }; -nglr.DataStore.prototype.loadMany = function(entity, ids, callback) { +DataStore.prototype.loadMany = function(entity, ids, callback) {    var self=this;    var list = [];    var callbackCount = 0; @@ -45,26 +45,26 @@ nglr.DataStore.prototype.loadMany = function(entity, ids, callback) {      list.push(self.load(entity(), id, function(){        callbackCount++;        if (callbackCount == ids.length) { -        (callback||nglr.noop)(list); +        (callback||noop)(list);        }      }));    });    return list;  } -nglr.DataStore.prototype.loadOrCreate = function(instance, id, callback) { +DataStore.prototype.loadOrCreate = function(instance, id, callback) {    var self=this;    return this.load(instance, id, callback, function(response){      if (response.$status_code == 404) {        instance.$id = id; -      (callback||nglr.noop)(instance); +      (callback||noop)(instance);      } else {        throw response;      }    });  }; -nglr.DataStore.prototype.loadAll = function(entity, callback) { +DataStore.prototype.loadAll = function(entity, callback) {    var self = this;    var list = [];    list.$$accept = function(doc){ @@ -78,12 +78,12 @@ nglr.DataStore.prototype.loadAll = function(entity, callback) {        document.$loadFrom(rows[i]);        list.push(self.cache(document));      } -    (callback||nglr.noop)(list); +    (callback||noop)(list);    });    return list;  }; -nglr.DataStore.prototype.save = function(document, callback) { +DataStore.prototype.save = function(document, callback) {    var self = this;    var data = {};    document.$saveTo(data); @@ -103,7 +103,7 @@ nglr.DataStore.prototype.save = function(document, callback) {    });  }; -nglr.DataStore.prototype.remove = function(document, callback) { +DataStore.prototype.remove = function(document, callback) {    var self = this;    var data = {};    document.$saveTo(data); @@ -117,11 +117,11 @@ nglr.DataStore.prototype.remove = function(document, callback) {          }        }      }); -    (callback||nglr.noop)(response); +    (callback||noop)(response);    });  }; -nglr.DataStore.prototype._jsonRequest = function(request, callback, failure) { +DataStore.prototype._jsonRequest = function(request, callback, failure) {    request.$$callback = callback;    request.$$failure = failure||function(response){      throw response; @@ -129,7 +129,7 @@ nglr.DataStore.prototype._jsonRequest = function(request, callback, failure) {    this.bulkRequest.push(request);  }; -nglr.DataStore.prototype.flush = function() { +DataStore.prototype.flush = function() {    if (this.bulkRequest.length === 0) return;    var self = this;    var bulkRequest = this.bulkRequest; @@ -142,7 +142,7 @@ nglr.DataStore.prototype.flush = function() {          self.post(bulkRequest, callback);        });      } else if(bulkResponse.$status_code) { -      nglr.alert(nglr.toJson(bulkResponse)); +      alert(toJson(bulkResponse));      } else {        for ( var i = 0; i < bulkResponse.length; i++) {          var response = bulkResponse[i]; @@ -163,7 +163,7 @@ nglr.DataStore.prototype.flush = function() {    this.post(bulkRequest, callback);  }; -nglr.DataStore.prototype.saveScope = function(scope, callback) { +DataStore.prototype.saveScope = function(scope, callback) {    var saveCounter = 1;    function onSaveDone() {      saveCounter--; @@ -172,7 +172,7 @@ nglr.DataStore.prototype.saveScope = function(scope, callback) {    }    for(var key in scope) {      var item = scope[key]; -    if (item && item.$save == nglr.Model.prototype.$save) { +    if (item && item.$save == Model.prototype.$save) {        saveCounter++;        item.$save(onSaveDone);      } @@ -180,7 +180,7 @@ nglr.DataStore.prototype.saveScope = function(scope, callback) {    onSaveDone();  }; -nglr.DataStore.prototype.query = function(type, query, arg, callback){ +DataStore.prototype.query = function(type, query, arg, callback){    var self = this;    var queryList = [];    queryList.$$accept = function(doc){ @@ -200,7 +200,7 @@ nglr.DataStore.prototype.query = function(type, query, arg, callback){    return queryList;  }; -nglr.DataStore.prototype.entities = function(callback) { +DataStore.prototype.entities = function(callback) {    var entities = [];    var self = this;    this._jsonRequest(["GET", "$entities"], function(response) { @@ -213,7 +213,7 @@ nglr.DataStore.prototype.entities = function(callback) {    return entities;  }; -nglr.DataStore.prototype.documentCountsByUser = function(){ +DataStore.prototype.documentCountsByUser = function(){    var counts = {};    var self = this;    self.post([["GET", "$users"]], function(code, response){ @@ -224,7 +224,7 @@ nglr.DataStore.prototype.documentCountsByUser = function(){    return counts;  }; -nglr.DataStore.prototype.userDocumentIdsByEntity = function(user){ +DataStore.prototype.userDocumentIdsByEntity = function(user){    var ids = {};    var self = this;    self.post([["GET", "$users/" + user]], function(code, response){ @@ -235,19 +235,19 @@ nglr.DataStore.prototype.userDocumentIdsByEntity = function(user){    return ids;  }; -nglr.DataStore.NullEntity = function(){}; -nglr.DataStore.NullEntity.all = function(){return [];}; -nglr.DataStore.NullEntity.query = function(){return [];}; -nglr.DataStore.NullEntity.load = function(){return {};}; -nglr.DataStore.NullEntity.title = undefined; +DataStore.NullEntity = function(){}; +DataStore.NullEntity.all = function(){return [];}; +DataStore.NullEntity.query = function(){return [];}; +DataStore.NullEntity.load = function(){return {};}; +DataStore.NullEntity.title = undefined; -nglr.DataStore.prototype.entity = function(name, defaults){ +DataStore.prototype.entity = function(name, defaults){    if (!name) { -    return nglr.DataStore.NullEntity; +    return DataStore.NullEntity;    }    var self = this;    var entity =  function(initialState){ -    return new nglr.Model(entity, initialState); +    return new Model(entity, initialState);    };    // entity.name does not work as name seems to be reserved for functions    entity.title = name; @@ -275,7 +275,7 @@ nglr.DataStore.prototype.entity = function(name, defaults){    return entity;  }; -nglr.DataStore.prototype.join = function(join){ +DataStore.prototype.join = function(join){    var fn = function(){      throw "Joined entities can not be instantiated into a document.";    }; @@ -312,7 +312,7 @@ nglr.DataStore.prototype.join = function(join){          var row = {};          joinedResult.push(row);          row[baseName] = doc; -        var id = nglr.Scope.getter(row, nextJoinOn); +        var id = Scope.getter(row, nextJoinOn);          joinIds[id] = id;        });        nextJoin.join.loadMany(_.toArray(joinIds), function(result){ @@ -321,7 +321,7 @@ nglr.DataStore.prototype.join = function(join){            byId[doc.$id] = doc;          });          _(joinedResult).each(function(row){ -          var id = nglr.Scope.getter(row, nextJoinOn); +          var id = Scope.getter(row, nextJoinOn);            row[nextJoinName] = byId[id];          });        }); diff --git a/src/Filters.js b/src/Filters.js index f75f3603..dd4217be 100644 --- a/src/Filters.js +++ b/src/Filters.js @@ -60,11 +60,11 @@ angular.filter.date = function(amount) {  angular.filter.json = function(object) {    jQuery(this.element).addClass("ng-monospace"); -  return nglr.toJson(object, true); +  return toJson(object, true);  };  angular.filter.trackPackage = function(trackingNo, noMatch) { -  trackingNo = nglr.trim(trackingNo); +  trackingNo = trim(trackingNo);    var tNo = trackingNo.replace(/ /g, '');    var MATCHERS = angular.filter.trackPackage.MATCHERS;    for ( var i = 0; i < MATCHERS.length; i++) { @@ -77,7 +77,7 @@ angular.filter.trackPackage = function(trackingNo, noMatch) {          return new angular.filter.Meta({            text:text,            url:url, -          html: '<a href="' + nglr.escapeAttr(url) + '">' + text + '</a>', +          html: '<a href="' + escapeAttr(url) + '">' + text + '</a>',            trackingNo:trackingNo});        }      } @@ -115,7 +115,7 @@ angular.filter.link = function(obj, title) {      if (angular.validator.email(url) === null) {        url = "mailto:" + url;      } -    var html = '<a href="' + nglr.escapeHtml(url) + '">' + text + '</a>'; +    var html = '<a href="' + escapeHtml(url) + '">' + text + '</a>';      return new angular.filter.Meta({text:text, url:url, html:html});    }    return obj; diff --git a/src/JSON.js b/src/JSON.js index 2b6393bf..84c9a857 100644 --- a/src/JSON.js +++ b/src/JSON.js @@ -1,18 +1,18 @@ -nglr.array = [].constructor; +array = [].constructor; -nglr.toJson = function(obj, pretty){ +toJson = function(obj, pretty){    var buf = []; -  nglr.toJsonArray(buf, obj, pretty ? "\n  " : null); +  toJsonArray(buf, obj, pretty ? "\n  " : null);    return buf.join('');  }; -nglr.toPrettyJson = function(obj) { -  return nglr.toJson(obj, true); +toPrettyJson = function(obj) { +  return toJson(obj, true);  }; -nglr.fromJson = function(json) { +fromJson = function(json) {    try { -    var parser = new nglr.Parser(json, true); +    var parser = new Parser(json, true);      var expression =  parser.primary();      parser.assertAllConsumed();      return expression(); @@ -23,7 +23,7 @@ nglr.fromJson = function(json) {  }; -nglr.toJsonArray = function(buf, obj, pretty){ +toJsonArray = function(buf, obj, pretty){    var type = typeof obj;    if (obj === null) {      buf.push("null"); @@ -50,7 +50,7 @@ nglr.toJsonArray = function(buf, obj, pretty){          if (typeof item == 'function' || typeof item == 'undefined') {            buf.push("null");          } else { -          nglr.toJsonArray(buf, item, pretty); +          toJsonArray(buf, item, pretty);          }          sep = true;        } @@ -80,7 +80,7 @@ nglr.toJsonArray = function(buf, obj, pretty){              }              buf.push(angular.String.quote(key));              buf.push(":"); -            nglr.toJsonArray(buf, value, childPretty); +            toJsonArray(buf, value, childPretty);              comma = true;            }          } catch (e) { diff --git a/src/Loader.js b/src/Loader.js index eae6e4f5..dfaa355a 100644 --- a/src/Loader.js +++ b/src/Loader.js @@ -22,34 +22,37 @@ if (typeof Node == 'undefined') {    };  } -if (_.isUndefined(window.nglr))       nglr = {}; -if (_.isUndefined(window.angular))    angular = {}; -if (_.isUndefined(angular.validator)) angular.validator = {}; -if (_.isUndefined(angular.filter))    angular.filter = {}; -if (_.isUndefined(window.console)) +var callbacks = {}; + +if (!window.angular){   angular = {}; window['angular'] = angular; } +if (!angular.validator) angular.validator = {}; +if (!angular.filter)    angular.filter = {}; +if (!window.console)    window.console = {      log:function() {},      error:function() {}    }; -if (_.isUndefined(nglr.alert)) { -  nglr.alert = function(){console.log(arguments); window.alert.apply(window, arguments); }; +if (_.isUndefined(alert)) { +  alert = function(){console.log(arguments); window.alert.apply(window, arguments); };  } -nglr.consoleLog = function(level, objs) { +var consoleNode; + +consoleLog = function(level, objs) {    var log = document.createElement("div");    log.className = level;    var msg = "";    var sep = "";    for ( var i = 0; i < objs.length; i++) {      var obj = objs[i]; -    msg += sep + (typeof obj == 'string' ? obj : nglr.toJson(obj)); +    msg += sep + (typeof obj == 'string' ? obj : toJson(obj));      sep = " ";    }    log.appendChild(document.createTextNode(msg)); -  nglr.consoleNode.appendChild(log); +  consoleNode.appendChild(log);  }; -nglr.isNode = function(inp) { +isNode = function(inp) {    return inp &&        inp.tagName &&        inp.nodeName && @@ -57,7 +60,7 @@ nglr.isNode = function(inp) {        inp.removeAttribute;  }; -nglr.isLeafNode = function(node) { +isLeafNode = function(node) {    switch (node.nodeName) {    case "OPTION":    case "PRE": @@ -68,11 +71,11 @@ nglr.isLeafNode = function(node) {    }  }; -nglr.noop = function() { +noop = function() {  }; -nglr.setHtml = function(node, html) { -  if (nglr.isLeafNode(node)) { -    if (nglr.msie) { +setHtml = function(node, html) { +  if (isLeafNode(node)) { +    if (msie) {        node.innerText = html;      } else {        node.textContent = html; @@ -82,7 +85,7 @@ nglr.setHtml = function(node, html) {    }  }; -nglr.escapeHtml = function(html) { +escapeHtml = function(html) {    if (!html || !html.replace)      return html;    return html. @@ -91,14 +94,14 @@ nglr.escapeHtml = function(html) {        replace(/>/g, '>');  }; -nglr.escapeAttr = function(html) { +escapeAttr = function(html) {    if (!html || !html.replace)      return html;    return html.replace(/</g, '<').replace(/>/g, '>').replace(/\"/g,        '"');  }; -nglr.bind = function(_this, _function) { +bind = function(_this, _function) {    if (!_this)      throw "Missing this";    if (!_.isFunction(_function)) @@ -108,7 +111,7 @@ nglr.bind = function(_this, _function) {    };  }; -nglr.shiftBind = function(_this, _function) { +shiftBind = function(_this, _function) {    return function() {      var args = [ this ];      for ( var i = 0; i < arguments.length; i++) { @@ -118,7 +121,7 @@ nglr.shiftBind = function(_this, _function) {    };  }; -nglr.outerHTML = function(node) { +outerHTML = function(node) {    var temp = document.createElement('div');    temp.appendChild(node);    var outerHTML = temp.innerHTML; @@ -126,26 +129,26 @@ nglr.outerHTML = function(node) {    return outerHTML;  }; -nglr.trim = function(str) { +trim = function(str) {    return str.replace(/^ */, '').replace(/ *$/, '');  }; -nglr.toBoolean = function(value) { +toBoolean = function(value) {    var v = ("" + value).toLowerCase();    if (v == 'f' || v == '0' || v == 'false' || v == 'no')      value = false;    return !!value;  }; -nglr.merge = function(src, dst) { +merge = function(src, dst) {    for ( var key in src) {      var value = dst[key];      var type = typeof value;      if (type == 'undefined') { -      dst[key] = nglr.fromJson(nglr.toJson(src[key])); -    } else if (type == 'object' && value.constructor != nglr.array && +      dst[key] = fromJson(toJson(src[key])); +    } else if (type == 'object' && value.constructor != array &&          key.substring(0, 1) != "$") { -      nglr.merge(src[key], value); +      merge(src[key], value);      }    }  }; @@ -154,25 +157,25 @@ nglr.merge = function(src, dst) {  // Loader  // //////////////////////////// -nglr.Loader = function(document, head, config) { +Loader = function(document, head, config) {    this.document = jQuery(document);    this.head = jQuery(head);    this.config = config;    this.location = window.location;  }; -nglr.Loader.prototype.load = function() { +Loader.prototype.load = function() {    this.configureLogging();    this.loadCss('/stylesheets/jquery-ui/smoothness/jquery-ui-1.7.1.css'); -  this.loadCss('/stylesheets/nglr.css'); +  this.loadCss('/stylesheets/css');    console.log("Server: " + this.config.server); -  nglr.msie = jQuery.browser.msie; +  msie = jQuery.browser.msie;    this.configureJQueryPlugins();    this.computeConfiguration();    this.bindHtml();  }; -nglr.Loader.prototype.configureJQueryPlugins = function() { +Loader.prototype.configureJQueryPlugins = function() {    console.log('Loader.configureJQueryPlugins()');    jQuery.fn.removeNode = function() {      var node = this.get(0); @@ -189,15 +192,15 @@ nglr.Loader.prototype.configureJQueryPlugins = function() {      return null;    };    jQuery.fn.controller = function() { -    return this.data('controller') || nglr.NullController.instance; +    return this.data('controller') || NullController.instance;    };  }; -nglr.Loader.prototype.uid = function() { +Loader.prototype.uid = function() {    return "" + new Date().getTime();  }; -nglr.Loader.prototype.computeConfiguration = function() { +Loader.prototype.computeConfiguration = function() {    var config = this.config;    if (!config.database) {      var match = config.server.match(/https?:\/\/([\w]*)/); @@ -205,27 +208,27 @@ nglr.Loader.prototype.computeConfiguration = function() {    }  }; -nglr.Loader.prototype.bindHtml = function() { +Loader.prototype.bindHtml = function() {    console.log('Loader.bindHtml()'); -  var watcher = new nglr.UrlWatcher(this.location); +  var watcher = new UrlWatcher(this.location);    var document = this.document; -  var widgetFactory = new nglr.WidgetFactory(this.config.server, this.config.database); -  var binder = new nglr.Binder(document[0], widgetFactory, watcher, this.config); -  widgetFactory.onChangeListener = nglr.shiftBind(binder, binder.updateModel); -  var controlBar = new nglr.ControlBar(document.find('body'), this.config.server); +  var widgetFactory = new WidgetFactory(this.config.server, this.config.database); +  var binder = new Binder(document[0], widgetFactory, watcher, this.config); +  widgetFactory.onChangeListener = shiftBind(binder, binder.updateModel); +  var controlBar = new ControlBar(document.find('body'), this.config.server);    var onUpdate = function(){binder.updateView();};    var server = this.config.database=="$MEMORY" ? -      new nglr.FrameServer(this.window) : -      new nglr.Server(this.config.server, jQuery.getScript); -  server = new nglr.VisualServer(server, new nglr.Status(jQuery(document.body)), onUpdate); -  var users = new nglr.Users(server, controlBar); +      new FrameServer(this.window) : +      new Server(this.config.server, jQuery.getScript); +  server = new VisualServer(server, new Status(jQuery(document.body)), onUpdate); +  var users = new Users(server, controlBar);    var databasePath = '/data/' + this.config.database;    var post = function(request, callback){      server.request("POST", databasePath, request, callback);    }; -  var datastore = new nglr.DataStore(post, users, binder.anchor); +  var datastore = new DataStore(post, users, binder.anchor);    binder.updateListeners.push(function(){datastore.flush();}); -  var scope = new nglr.Scope( { +  var scope = new Scope( {      $anchor : binder.anchor,      $binder : binder,      $config : this.config, @@ -241,7 +244,7 @@ nglr.Loader.prototype.bindHtml = function() {    jQuery.each(["get", "set", "eval", "addWatchListener", "updateView"],      function(i, method){ -      angular[method] = nglr.bind(scope, scope[method]); +      angular[method] = bind(scope, scope[method]);      });    document.data('scope', scope); @@ -265,7 +268,7 @@ nglr.Loader.prototype.bindHtml = function() {    fetchCurrentUser();    console.log('PopUp.bind()'); -  new nglr.PopUp(document).bind(); +  new PopUp(document).bind();    console.log('$binder.parseAnchor()');    binder.parseAnchor(); @@ -276,16 +279,16 @@ nglr.Loader.prototype.bindHtml = function() {    console.log('$binder.updateView()');    binder.updateView(); -  watcher.listener = nglr.bind(binder, binder.onUrlChange, watcher); -  watcher.onUpdate = function(){nglr.alert("update");}; +  watcher.listener = bind(binder, binder.onUrlChange, watcher); +  watcher.onUpdate = function(){alert("update");};    watcher.watch();    document.find("body").show();    console.log('ready()');  }; -nglr.Loader.prototype.visualPost = function(delegate) { -  var status = new nglr.Status(jQuery(document.body)); +Loader.prototype.visualPost = function(delegate) { +  var status = new Status(jQuery(document.body));    return function(request, delegateCallback) {      status.beginRequest(request);      var callback = function() { @@ -293,14 +296,14 @@ nglr.Loader.prototype.visualPost = function(delegate) {        try {          delegateCallback.apply(this, arguments);        } catch (e) { -        nglr.alert(nglr.toJson(e)); +        alert(toJson(e));        }      };      delegate(request, callback);    };  }; -nglr.Loader.prototype.configureLogging = function() { +Loader.prototype.configureLogging = function() {    var url = window.location.href + '#';    url = url.split('#')[1];    var config = { @@ -312,19 +315,19 @@ nglr.Loader.prototype.configureLogging = function() {      config[part[0]] = part[1];    }    if (config.debug == 'console') { -    nglr.consoleNode = document.createElement("div"); -    nglr.consoleNode.id = 'ng-console'; -    document.getElementsByTagName('body')[0].appendChild(nglr.consoleNode); +    consoleNode = document.createElement("div"); +    consoleNode.id = 'ng-console'; +    document.getElementsByTagName('body')[0].appendChild(consoleNode);      console.log = function() { -      nglr.consoleLog('ng-console-info', arguments); +      consoleLog('ng-console-info', arguments);      };      console.error = function() { -      nglr.consoleLog('ng-console-error', arguments); +      consoleLog('ng-console-error', arguments);      };    }  }; -nglr.Loader.prototype.loadCss = function(css) { +Loader.prototype.loadCss = function(css) {    var cssTag = document.createElement('link');    cssTag.rel = "stylesheet";    cssTag.type = "text/css"; @@ -334,7 +337,7 @@ nglr.Loader.prototype.loadCss = function(css) {    this.head[0].appendChild(cssTag);  }; -nglr.UrlWatcher = function(location) { +UrlWatcher = function(location) {    this.location = location;    this.delay = 25;    this.setTimeout = function(fn, delay) { @@ -346,7 +349,7 @@ nglr.UrlWatcher = function(location) {    this.expectedUrl = location.href;  }; -nglr.UrlWatcher.prototype.watch = function() { +UrlWatcher.prototype.watch = function() {    var self = this;    var pull = function() {      if (self.expectedUrl !== self.location.href) { @@ -357,12 +360,12 @@ nglr.UrlWatcher.prototype.watch = function() {          }          self.location.href = self.expectedUrl;          var id = '_iframe_notify_' + notify[1]; -        var notifyFn = nglr[id]; -        delete nglr[id]; +        var notifyFn = callbacks[id]; +        delete callbacks[id];          try { -          (notifyFn||nglr.noop)(); +          (notifyFn||noop)();          } catch (e) { -          nglr.alert(e); +          alert(e);          }        } else {          self.listener(self.location.href); @@ -374,16 +377,16 @@ nglr.UrlWatcher.prototype.watch = function() {    pull();  }; -nglr.UrlWatcher.prototype.setUrl = function(url) { +UrlWatcher.prototype.setUrl = function(url) {    var existingURL = window.location.href;    if (!existingURL.match(/#/))      existingURL += '#';    if (existingURL != url)      window.location.href = url; -  self.existingURL = url; +  this.existingURL = url;  }; -nglr.UrlWatcher.prototype.getUrl = function() { +UrlWatcher.prototype.getUrl = function() {    return window.location.href;  }; @@ -394,7 +397,7 @@ angular['compile'] = function(root, config) {    };    //todo: don't load stylesheet by default    //todo: don't start watcher -  var loader = new nglr.Loader(root, jQuery("head"), _(defaults).extend(config)); +  var loader = new Loader(root, jQuery("head"), _(defaults).extend(config));    loader.load();    return jQuery(root).scope();  }; diff --git a/src/Model.js b/src/Model.js index 5e48251f..35f6a1c1 100644 --- a/src/Model.js +++ b/src/Model.js @@ -3,14 +3,14 @@  // Single $ is special and does not get searched  // Double $$ is special an is client only (does not get sent to server) -nglr.Model = function(entity, initial) { +Model = function(entity, initial) {    this.$$entity = entity;    this.$loadFrom(initial||{});    this.$entity = entity.title;    this.$migrate();  }; -nglr.Model.copyDirectFields = function(src, dst) { +Model.copyDirectFields = function(src, dst) {    if (src === dst || !src || !dst) return;    var isDataField = function(src, dst, field) {      return (field.substring(0,2) !== '$$') && @@ -27,39 +27,39 @@ nglr.Model.copyDirectFields = function(src, dst) {    }  }; -nglr.Model.prototype.$migrate = function() { -  nglr.merge(this.$$entity.defaults, this); +Model.prototype.$migrate = function() { +  merge(this.$$entity.defaults, this);    return this;  }; -nglr.Model.prototype.$merge = function(other) { -  nglr.merge(other, this); +Model.prototype.$merge = function(other) { +  merge(other, this);    return this;  }; -nglr.Model.prototype.$save = function(callback) { +Model.prototype.$save = function(callback) {    this.$$entity.datastore.save(this, callback === true ? undefined : callback);    if (callback === true) this.$$entity.datastore.flush();    return this;  }; -nglr.Model.prototype.$delete = function(callback) { +Model.prototype.$delete = function(callback) {    this.$$entity.datastore.remove(this, callback === true ? undefined : callback);    if (callback === true) this.$$entity.datastore.flush();    return this;  }; -nglr.Model.prototype.$loadById = function(id, callback) { +Model.prototype.$loadById = function(id, callback) {    this.$$entity.datastore.load(this, id, callback);    return this;  }; -nglr.Model.prototype.$loadFrom = function(other) { -  nglr.Model.copyDirectFields(other, this); +Model.prototype.$loadFrom = function(other) { +  Model.copyDirectFields(other, this);    return this;  }; -nglr.Model.prototype.$saveTo = function(other) { -  nglr.Model.copyDirectFields(this, other); +Model.prototype.$saveTo = function(other) { +  Model.copyDirectFields(this, other);    return this;  }; diff --git a/src/Parser.js b/src/Parser.js index 3d72bebf..b23215be 100644 --- a/src/Parser.js +++ b/src/Parser.js @@ -1,4 +1,4 @@ -nglr.Lexer = function(text, parsStrings){ +Lexer = function(text, parsStrings){    this.text = text;    // UTC dates have 20 characters, we send them through parser    this.dateParseLength = parsStrings ? 20 : -1; @@ -6,7 +6,7 @@ nglr.Lexer = function(text, parsStrings){    this.index = 0;  }; -nglr.Lexer.OPERATORS = { +Lexer.OPERATORS = {      'null':function(self){return null;},      'true':function(self){return true;},      'false':function(self){return false;}, @@ -31,7 +31,7 @@ nglr.Lexer.OPERATORS = {      '!':function(self, a){return !a;}  }; -nglr.Lexer.prototype.peek = function() { +Lexer.prototype.peek = function() {    if (this.index + 1 < this.text.length) {      return this.text.charAt(this.index + 1);    } else { @@ -39,9 +39,9 @@ nglr.Lexer.prototype.peek = function() {    }  }; -nglr.Lexer.prototype.parse = function() { +Lexer.prototype.parse = function() {    var tokens = this.tokens; -  var OPERATORS = nglr.Lexer.OPERATORS; +  var OPERATORS = Lexer.OPERATORS;    var canStartRegExp = true;    while (this.index < this.text.length) {      var ch = this.text.charAt(this.index); @@ -102,22 +102,22 @@ nglr.Lexer.prototype.parse = function() {    return tokens;  }; -nglr.Lexer.prototype.isNumber = function(ch) { +Lexer.prototype.isNumber = function(ch) {    return '0' <= ch && ch <= '9';  }; -nglr.Lexer.prototype.isWhitespace = function(ch) { +Lexer.prototype.isWhitespace = function(ch) {    return ch == ' ' || ch == '\r' || ch == '\t' ||           ch == '\n' || ch == '\v';  }; -nglr.Lexer.prototype.isIdent = function(ch) { +Lexer.prototype.isIdent = function(ch) {    return 'a' <= ch && ch <= 'z' ||           'A' <= ch && ch <= 'Z' ||           '_' == ch || ch == '$';  }; -nglr.Lexer.prototype.readNumber = function() { +Lexer.prototype.readNumber = function() {    var number = "";    var start = this.index;    while (this.index < this.text.length) { @@ -134,7 +134,7 @@ nglr.Lexer.prototype.readNumber = function() {      fn:function(){return number;}});  }; -nglr.Lexer.prototype.readIdent = function() { +Lexer.prototype.readIdent = function() {    var ident = "";    var start = this.index;    while (this.index < this.text.length) { @@ -146,7 +146,7 @@ nglr.Lexer.prototype.readIdent = function() {      }      this.index++;    } -  var fn = nglr.Lexer.OPERATORS[ident]; +  var fn = Lexer.OPERATORS[ident];    if (!fn) {      fn = function(self){        return self.scope.get(ident); @@ -155,8 +155,8 @@ nglr.Lexer.prototype.readIdent = function() {    }    this.tokens.push({index:start, text:ident, fn:fn});  }; -nglr.Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; -nglr.Lexer.prototype.readString = function(quote) { +Lexer.ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; +Lexer.prototype.readString = function(quote) {    var start = this.index;    var dateParseLength = this.dateParseLength;    this.index++; @@ -170,7 +170,7 @@ nglr.Lexer.prototype.readString = function(quote) {          this.index += 4;          string += String.fromCharCode(parseInt(hex, 16));        } else { -        var rep = nglr.Lexer.ESCAPE[ch]; +        var rep = Lexer.ESCAPE[ch];          if (rep) {            string += rep;          } else { @@ -198,7 +198,7 @@ nglr.Lexer.prototype.readString = function(quote) {        (start+1) + "' in expression '" + this.text + "'.";  }; -nglr.Lexer.prototype.readRegexp = function(quote) { +Lexer.prototype.readRegexp = function(quote) {    var start = this.index;    this.index++;    var regexp = ""; @@ -233,30 +233,30 @@ nglr.Lexer.prototype.readRegexp = function(quote) {  }; -nglr.Parser = function(text, parseStrings){ +Parser = function(text, parseStrings){    this.text = text; -  this.tokens = new nglr.Lexer(text, parseStrings).parse(); +  this.tokens = new Lexer(text, parseStrings).parse();    this.index = 0;  }; -nglr.Parser.ZERO = function(){ +Parser.ZERO = function(){    return 0;  }; -nglr.Parser.prototype.error = function(msg, token) { +Parser.prototype.error = function(msg, token) {    throw "Token '" + token.text +       "' is " + msg + " at column='" +       (token.index + 1) + "' of expression '" +       this.text + "' starting at '" + this.text.substring(token.index) + "'.";  }; -nglr.Parser.prototype.peekToken = function() { +Parser.prototype.peekToken = function() {    if (this.tokens.length === 0)       throw "Unexpected end of expression: " + this.text;    return this.tokens[0];  }; -nglr.Parser.prototype.peek = function(e1, e2, e3, e4) { +Parser.prototype.peek = function(e1, e2, e3, e4) {    var tokens = this.tokens;    if (tokens.length > 0) {      var token = tokens[0]; @@ -269,7 +269,7 @@ nglr.Parser.prototype.peek = function(e1, e2, e3, e4) {    return false;  }; -nglr.Parser.prototype.expect = function(e1, e2, e3, e4){ +Parser.prototype.expect = function(e1, e2, e3, e4){    var token = this.peek(e1, e2, e3, e4);    if (token) {      this.tokens.shift(); @@ -279,7 +279,7 @@ nglr.Parser.prototype.expect = function(e1, e2, e3, e4){    return false;  }; -nglr.Parser.prototype.consume = function(e1){ +Parser.prototype.consume = function(e1){    if (!this.expect(e1)) {      var token = this.peek();      throw "Expecting '" + e1 + "' at column '" + @@ -289,32 +289,32 @@ nglr.Parser.prototype.consume = function(e1){    }  }; -nglr.Parser.prototype._unary = function(fn, parse) { +Parser.prototype._unary = function(fn, parse) {    var right = parse.apply(this);    return function(self) {      return fn(self, right(self));    };  }; -nglr.Parser.prototype._binary = function(left, fn, parse) { +Parser.prototype._binary = function(left, fn, parse) {    var right = parse.apply(this);    return function(self) {      return fn(self, left(self), right(self));    };  }; -nglr.Parser.prototype.hasTokens = function () { +Parser.prototype.hasTokens = function () {    return this.tokens.length > 0;  }; -nglr.Parser.prototype.assertAllConsumed = function(){ +Parser.prototype.assertAllConsumed = function(){    if (this.tokens.length !== 0) {      throw "Did not understand '" + this.text.substring(this.tokens[0].index) +          "' while evaluating '" + this.text + "'.";    }  }; -nglr.Parser.prototype.statements = function(){ +Parser.prototype.statements = function(){    var statements = [];    while(true) {      if (this.tokens.length > 0 && !this.peek('}', ')', ';', ']')) @@ -333,7 +333,7 @@ nglr.Parser.prototype.statements = function(){    }  }; -nglr.Parser.prototype.filterChain = function(){ +Parser.prototype.filterChain = function(){    var left = this.expression();    var token;    while(true) { @@ -345,15 +345,15 @@ nglr.Parser.prototype.filterChain = function(){    }  }; -nglr.Parser.prototype.filter = function(){ +Parser.prototype.filter = function(){    return this._pipeFunction(angular.filter);  }; -nglr.Parser.prototype.validator = function(){ +Parser.prototype.validator = function(){    return this._pipeFunction(angular.validator);  }; -nglr.Parser.prototype._pipeFunction = function(fnScope){ +Parser.prototype._pipeFunction = function(fnScope){    var fn = this.functionIdent(fnScope);    var argsFn = [];    var token; @@ -375,11 +375,11 @@ nglr.Parser.prototype._pipeFunction = function(fnScope){    }  }; -nglr.Parser.prototype.expression = function(){ +Parser.prototype.expression = function(){    return this.throwStmt();  }; -nglr.Parser.prototype.throwStmt = function(){ +Parser.prototype.throwStmt = function(){    if (this.expect('throw')) {      var throwExp = this.assignment();      return function (self) { @@ -390,7 +390,7 @@ nglr.Parser.prototype.throwStmt = function(){    }  }; -nglr.Parser.prototype.assignment = function(){ +Parser.prototype.assignment = function(){    var left = this.logicalOR();    var token;    if (token = this.expect('=')) { @@ -406,7 +406,7 @@ nglr.Parser.prototype.assignment = function(){    }  }; -nglr.Parser.prototype.logicalOR = function(){ +Parser.prototype.logicalOR = function(){    var left = this.logicalAND();    var token;    while(true) { @@ -418,7 +418,7 @@ nglr.Parser.prototype.logicalOR = function(){    }  }; -nglr.Parser.prototype.logicalAND = function(){ +Parser.prototype.logicalAND = function(){    var left = this.negated();    var token;    while(true) { @@ -430,7 +430,7 @@ nglr.Parser.prototype.logicalAND = function(){    }  }; -nglr.Parser.prototype.negated = function(){ +Parser.prototype.negated = function(){    var token;    if (token = this.expect('!')) {      return this._unary(token.fn, this.equality); @@ -439,7 +439,7 @@ nglr.Parser.prototype.negated = function(){    }  }; -nglr.Parser.prototype.equality = function(){ +Parser.prototype.equality = function(){    var left = this.relational();    var token;    while(true) { @@ -451,7 +451,7 @@ nglr.Parser.prototype.equality = function(){    }  }; -nglr.Parser.prototype.relational = function(){ +Parser.prototype.relational = function(){    var left = this.additive();    var token;    while(true) { @@ -463,7 +463,7 @@ nglr.Parser.prototype.relational = function(){    }  }; -nglr.Parser.prototype.additive = function(){ +Parser.prototype.additive = function(){    var left = this.multiplicative();    var token;    while(token = this.expect('+','-')) { @@ -472,7 +472,7 @@ nglr.Parser.prototype.additive = function(){    return left;  }; -nglr.Parser.prototype.multiplicative = function(){ +Parser.prototype.multiplicative = function(){    var left = this.unary();    var token;    while(token = this.expect('*','/','%')) { @@ -481,18 +481,18 @@ nglr.Parser.prototype.multiplicative = function(){    return left;  }; -nglr.Parser.prototype.unary = function(){ +Parser.prototype.unary = function(){    var token;    if (this.expect('+')) {      return this.primary();    } else if (token = this.expect('-')) { -    return this._binary(nglr.Parser.ZERO, token.fn, this.multiplicative); +    return this._binary(Parser.ZERO, token.fn, this.multiplicative);    } else {     return this.primary();    }  }; -nglr.Parser.prototype.functionIdent = function(fnScope) { +Parser.prototype.functionIdent = function(fnScope) {    var token = this.expect();    var element = token.text.split('.');    var instance = fnScope; @@ -509,7 +509,7 @@ nglr.Parser.prototype.functionIdent = function(fnScope) {    return instance;  }; -nglr.Parser.prototype.primary = function() { +Parser.prototype.primary = function() {    var primary;    if (this.expect('(')) {      var expression = this.filterChain(); @@ -545,7 +545,7 @@ nglr.Parser.prototype.primary = function() {    return primary;  }; -nglr.Parser.prototype.closure = function(hasArgs) { +Parser.prototype.closure = function(hasArgs) {    var args = [];    if (hasArgs) {      if (!this.expect(')')) { @@ -561,7 +561,7 @@ nglr.Parser.prototype.closure = function(hasArgs) {    this.consume("}");    return function(self){      return function($){ -      var scope = new nglr.Scope(self.scope.state); +      var scope = new Scope(self.scope.state);        scope.set('$', $);        for ( var i = 0; i < args.length; i++) {          scope.set(args[i], arguments[i]); @@ -571,16 +571,16 @@ nglr.Parser.prototype.closure = function(hasArgs) {    };  }; -nglr.Parser.prototype.fieldAccess = function(object) { +Parser.prototype.fieldAccess = function(object) {    var field = this.expect().text;    var fn = function (self){ -    return nglr.Scope.getter(object(self), field); +    return Scope.getter(object(self), field);    };    fn.isAssignable = field;    return fn;  }; -nglr.Parser.prototype.objectIndex = function(obj) { +Parser.prototype.objectIndex = function(obj) {    var indexFn = this.expression();    this.consume(']');    if (this.expect('=')) { @@ -597,7 +597,7 @@ nglr.Parser.prototype.objectIndex = function(obj) {    }  }; -nglr.Parser.prototype.functionCall = function(fn) { +Parser.prototype.functionCall = function(fn) {    var argsFn = [];    if (this.peekToken().text != ')') {      do { @@ -620,7 +620,7 @@ nglr.Parser.prototype.functionCall = function(fn) {  };  // This is used with json array declaration -nglr.Parser.prototype.arrayDeclaration = function () { +Parser.prototype.arrayDeclaration = function () {    var elementFns = [];    if (this.peekToken().text != ']') {      do { @@ -637,7 +637,7 @@ nglr.Parser.prototype.arrayDeclaration = function () {    };  }; -nglr.Parser.prototype.object = function () { +Parser.prototype.object = function () {    var keyValues = [];    if (this.peekToken().text != '}') {      do { @@ -659,7 +659,7 @@ nglr.Parser.prototype.object = function () {    };  }; -nglr.Parser.prototype.entityDeclaration = function () { +Parser.prototype.entityDeclaration = function () {    var decl = [];    while(this.hasTokens()) {      decl.push(this.entityDecl()); @@ -676,7 +676,7 @@ nglr.Parser.prototype.entityDeclaration = function () {    };  }; -nglr.Parser.prototype.entityDecl = function () { +Parser.prototype.entityDecl = function () {    var entity = this.expect().text;    var instance;    var defaults; @@ -705,7 +705,7 @@ nglr.Parser.prototype.entityDecl = function () {    };  }; -nglr.Parser.prototype.watch = function () { +Parser.prototype.watch = function () {    var decl = [];    while(this.hasTokens()) {      decl.push(this.watchDecl()); @@ -722,7 +722,7 @@ nglr.Parser.prototype.watch = function () {    };  }; -nglr.Parser.prototype.watchDecl = function () { +Parser.prototype.watchDecl = function () {    var anchorName = this.expect().text;    this.consume(":");    var expression; diff --git a/src/Scope.js b/src/Scope.js index 45dd15a4..e3634cee 100644 --- a/src/Scope.js +++ b/src/Scope.js @@ -1,6 +1,6 @@  // Copyright (C) 2009 BRAT Tech LLC -nglr.Scope = function(initialState, name) { +Scope = function(initialState, name) {    this.widgets = [];    this.watchListeners = {};    this.name = name; @@ -14,9 +14,9 @@ nglr.Scope = function(initialState, name) {    }  }; -nglr.Scope.expressionCache = {}; +Scope.expressionCache = {}; -nglr.Scope.prototype.updateView = function() { +Scope.prototype.updateView = function() {    var self = this;    this.fireWatchers();    _.each(this.widgets, function(widget){ @@ -26,21 +26,21 @@ nglr.Scope.prototype.updateView = function() {    });  }; -nglr.Scope.prototype.addWidget = function(controller) { +Scope.prototype.addWidget = function(controller) {    if (controller) this.widgets.push(controller);  }; -nglr.Scope.prototype.isProperty = function(exp) { +Scope.prototype.isProperty = function(exp) {    for ( var i = 0; i < exp.length; i++) {      var ch = exp.charAt(i); -    if (ch!='.'  && !nglr.Lexer.prototype.isIdent(ch)) { +    if (ch!='.'  && !Lexer.prototype.isIdent(ch)) {        return false;      }    }    return true;  }; -nglr.Scope.getter = function(instance, path) { +Scope.getter = function(instance, path) {    if (!path) return instance;    var element = path.split('.');    var key; @@ -65,16 +65,16 @@ nglr.Scope.getter = function(instance, path) {      }    }    if (typeof instance === 'function' && !instance.$$factory) { -    return nglr.bind(lastInstance, instance); +    return bind(lastInstance, instance);    }    return instance;  }; -nglr.Scope.prototype.get = function(path) { -  return nglr.Scope.getter(this.state, path); +Scope.prototype.get = function(path) { +  return Scope.getter(this.state, path);  }; -nglr.Scope.prototype.set = function(path, value) { +Scope.prototype.set = function(path, value) {    var element = path.split('.');    var instance = this.state;    for ( var i = 0; element.length > 1; i++) { @@ -90,17 +90,17 @@ nglr.Scope.prototype.set = function(path, value) {    return value;  }; -nglr.Scope.prototype.setEval = function(expressionText, value) { -  this.eval(expressionText + "=" + nglr.toJson(value)); +Scope.prototype.setEval = function(expressionText, value) { +  this.eval(expressionText + "=" + toJson(value));  }; -nglr.Scope.prototype.eval = function(expressionText, context) { -  var expression = nglr.Scope.expressionCache[expressionText]; +Scope.prototype.eval = function(expressionText, context) { +  var expression = Scope.expressionCache[expressionText];    if (!expression) { -    var parser = new nglr.Parser(expressionText); +    var parser = new Parser(expressionText);      expression = parser.statements();      parser.assertAllConsumed(); -    nglr.Scope.expressionCache[expressionText] = expression; +    Scope.expressionCache[expressionText] = expression;    }    context = context || {};    context.scope = this; @@ -110,7 +110,7 @@ nglr.Scope.prototype.eval = function(expressionText, context) {  //TODO: Refactor. This function needs to be an execution closure for widgets  // move to widgets  // remove expression, just have inner closure. -nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) { +Scope.prototype.evalWidget = function(widget, expression, context, onSuccess, onFailure) {    try {      var value = this.eval(expression, context);      if (widget.hasError) { @@ -125,7 +125,7 @@ nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSucces      return true;    } catch (e){      console.error('Eval Widget Error:', e); -    var jsonError = nglr.toJson(e, true); +    var jsonError = toJson(e, true);      widget.hasError = true;      jQuery(widget.view).        addClass('ng-exception'). @@ -137,42 +137,42 @@ nglr.Scope.prototype.evalWidget = function(widget, expression, context, onSucces    }  }; -nglr.Scope.prototype.validate = function(expressionText, value) { -  var expression = nglr.Scope.expressionCache[expressionText]; +Scope.prototype.validate = function(expressionText, value) { +  var expression = Scope.expressionCache[expressionText];    if (!expression) { -    expression = new nglr.Parser(expressionText).validator(); -    nglr.Scope.expressionCache[expressionText] = expression; +    expression = new Parser(expressionText).validator(); +    Scope.expressionCache[expressionText] = expression;    }    var self = {scope:this};    return expression(self)(self, value);  }; -nglr.Scope.prototype.entity = function(entityDeclaration) { -  var expression = new nglr.Parser(entityDeclaration).entityDeclaration(); +Scope.prototype.entity = function(entityDeclaration) { +  var expression = new Parser(entityDeclaration).entityDeclaration();    return expression({scope:this});  }; -nglr.Scope.prototype.markInvalid = function(widget) { +Scope.prototype.markInvalid = function(widget) {    this.state.$invalidWidgets.push(widget);  }; -nglr.Scope.prototype.watch = function(declaration) { +Scope.prototype.watch = function(declaration) {    var self = this; -  new nglr.Parser(declaration).watch()({ +  new Parser(declaration).watch()({      scope:this,      addListener:function(watch, exp){        self.addWatchListener(watch, function(n,o){          try {            return exp({scope:self}, n, o);          } catch(e) { -          nglr.alert(e); +          alert(e);          }        });      }    });  }; -nglr.Scope.prototype.addWatchListener = function(watchExpression, listener) { +Scope.prototype.addWatchListener = function(watchExpression, listener) {    var watcher = this.watchListeners[watchExpression];    if (!watcher) {      watcher = {listeners:[], expression:watchExpression}; @@ -181,7 +181,7 @@ nglr.Scope.prototype.addWatchListener = function(watchExpression, listener) {    watcher.listeners.push(listener);  }; -nglr.Scope.prototype.fireWatchers = function() { +Scope.prototype.fireWatchers = function() {    var self = this;    var fired = false;    jQuery.each(this.watchListeners, function(name, watcher) { diff --git a/src/Server.js b/src/Server.js index 94b0cc10..d00f893b 100644 --- a/src/Server.js +++ b/src/Server.js @@ -1,6 +1,6 @@  // Copyright (C) 2008,2009 BRAT Tech LLC -nglr.Server = function(url, getScript) { +Server = function(url, getScript) {    this.url = url;    this.nextId = 0;    this.getScript = getScript; @@ -8,51 +8,51 @@ nglr.Server = function(url, getScript) {    this.maxSize = 1800;  }; -nglr.Server.prototype.base64url = function(txt) { +Server.prototype.base64url = function(txt) {    return Base64.encode(txt);  }; -nglr.Server.prototype.request = function(method, url, request, callback) { +Server.prototype.request = function(method, url, request, callback) {    var requestId = this.uuid + (this.nextId++); -  nglr[requestId] = function(response) { -    delete nglr[requestId]; +  callbacks[requestId] = function(response) { +    delete angular[requestId];      callback(200, response);    };    var payload = {u:url, m:method, p:request}; -  payload = this.base64url(nglr.toJson(payload)); +  payload = this.base64url(toJson(payload));    var totalPockets = Math.ceil(payload.length / this.maxSize);    var baseUrl = this.url + "/$/" + requestId +  "/" + totalPockets + "/";    for ( var pocketNo = 0; pocketNo < totalPockets; pocketNo++) {      var pocket = payload.substr(pocketNo * this.maxSize, this.maxSize); -    this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, nglr.noop); +    this.getScript(baseUrl + (pocketNo+1) + "?h=" + pocket, noop);    }  }; -nglr.FrameServer = function(frame) { +FrameServer = function(frame) {    this.frame = frame;  }; -nglr.FrameServer.PREFIX = "$DATASET:"; +FrameServer.PREFIX = "$DATASET:"; -nglr.FrameServer.prototype = { +FrameServer.prototype = {    read:function(){ -    this.data = nglr.fromJson(this.frame.name.substr(nglr.FrameServer.PREFIX.length)); +    this.data = fromJson(this.frame.name.substr(FrameServer.PREFIX.length));    },    write:function(){ -    this.frame.name = nglr.FrameServer.PREFIX +  nglr.toJson(this.data); +    this.frame.name = FrameServer.PREFIX +  toJson(this.data);    },     request: function(method, url, request, callback) { -    //alert(method + " " + url + " " + nglr.toJson(request) + " " + nglr.toJson(callback)); +    //alert(method + " " + url + " " + toJson(request) + " " + toJson(callback));    }  }; -nglr.VisualServer = function(delegate, status, update) { +VisualServer = function(delegate, status, update) {    this.delegate = delegate;    this.update = update;    this.status = status;  }; -nglr.VisualServer.prototype = { +VisualServer.prototype = {    request:function(method, url, request, callback) {      var self = this;      this.status.beginRequest(request); @@ -61,7 +61,7 @@ nglr.VisualServer.prototype = {        try {          callback.apply(this, arguments);        } catch (e) { -        nglr.alert(nglr.toJson(e)); +        alert(toJson(e));        }        self.update();      }); diff --git a/src/Users.js b/src/Users.js index c0c15848..d10b96df 100644 --- a/src/Users.js +++ b/src/Users.js @@ -1,10 +1,10 @@  // Copyright (C) 2008,2009 BRAT Tech LLC -nglr.Users = function(server, controlBar) { +Users = function(server, controlBar) {    this.server = server;    this.controlBar = controlBar;  }; -nglr.Users.prototype = { +Users.prototype = {    fetchCurrentUser:function(callback) {      var self = this;      this.server.request("GET", "/account.json", {}, function(code, response){ @@ -17,7 +17,7 @@ nglr.Users.prototype = {      var self = this;      this.controlBar.logout(function(){        delete self.current; -      (callback||nglr.noop)(); +      (callback||noop)();      });    }, @@ -25,7 +25,7 @@ nglr.Users.prototype = {      var self = this;      this.controlBar.login(function(){        self.fetchCurrentUser(function(){ -        (callback||nglr.noop)(); +        (callback||noop)();        });      });    }, diff --git a/src/Validators.js b/src/Validators.js index 94cb1d52..7cfaa2b4 100644 --- a/src/Validators.js +++ b/src/Validators.js @@ -72,7 +72,7 @@ angular.validator.url = function(value) {  angular.validator.json = function(value) {    try { -    nglr.fromJson(value); +    fromJson(value);      return null;    } catch (e) {      return e.toString(); diff --git a/src/Widgets.js b/src/Widgets.js index de74533a..3a0f2845 100644 --- a/src/Widgets.js +++ b/src/Widgets.js @@ -1,7 +1,7 @@  // Copyright (C) 2009 BRAT Tech LLC -nglr.WidgetFactory = function(serverUrl, database) { +WidgetFactory = function(serverUrl, database) {    this.nextUploadId = 0;    this.serverUrl = serverUrl;    this.database = database; @@ -9,7 +9,7 @@ nglr.WidgetFactory = function(serverUrl, database) {    this.onChangeListener = function(){};  }; -nglr.WidgetFactory.prototype.createController = function(input, scope) { +WidgetFactory.prototype.createController = function(input, scope) {    var controller;    var type = input.attr('type').toLowerCase();    var exp = input.attr('name'); @@ -17,22 +17,22 @@ nglr.WidgetFactory.prototype.createController = function(input, scope) {    var event = "change";    var bubbleEvent = true;    if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') { -    controller = new nglr.ButtonController(input[0], exp); +    controller = new ButtonController(input[0], exp);      event = "click";      bubbleEvent = false;    } else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') { -    controller = new nglr.TextController(input[0], exp); +    controller = new TextController(input[0], exp);      event = "keyup change";    } else if (type == 'checkbox') { -    controller = new nglr.CheckboxController(input[0], exp); +    controller = new CheckboxController(input[0], exp);      event = "click";    } else if (type == 'radio') { -    controller = new nglr.RadioController(input[0], exp); +    controller = new RadioController(input[0], exp);      event="click";    } else if (type == 'select-one') { -    controller = new nglr.SelectController(input[0], exp); +    controller = new SelectController(input[0], exp);    } else if (type == 'select-multiple') { -    controller = new nglr.MultiSelectController(input[0], exp); +    controller = new MultiSelectController(input[0], exp);    } else if (type == 'file') {      controller = this.createFileController(input, exp);    } else { @@ -54,9 +54,9 @@ nglr.WidgetFactory.prototype.createController = function(input, scope) {    return controller;  }; -nglr.WidgetFactory.prototype.createFileController = function(fileInput) { +WidgetFactory.prototype.createFileController = function(fileInput) {    var uploadId = '__uploadWidget_' + (this.nextUploadId++); -  var view = nglr.FileController.template(uploadId); +  var view = FileController.template(uploadId);    fileInput.after(view);    var att = {        data:this.serverUrl + "/admin/ServerAPI.swf", @@ -67,13 +67,13 @@ nglr.WidgetFactory.prototype.createFileController = function(fileInput) {        allowScriptAccess:"always"};    var swfNode = this.createSWF(att, par, uploadId);    fileInput.remove(); -  var cntl = new nglr.FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database); +  var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);    jQuery(swfNode).data('controller', cntl);    return cntl;  }; -nglr.WidgetFactory.prototype.createTextWidget = function(textInput) { -  var controller = new nglr.TextController(textInput); +WidgetFactory.prototype.createTextWidget = function(textInput) { +  var controller = new TextController(textInput);    controller.onChange(this.onChangeListener);    return controller;  }; @@ -82,7 +82,7 @@ nglr.WidgetFactory.prototype.createTextWidget = function(textInput) {  // FileController  /////////////////////// -nglr.FileController = function(view, scopeName, uploader, databaseUrl) { +FileController = function(view, scopeName, uploader, databaseUrl) {    this.view = view;    this.uploader = uploader;    this.scopeName = scopeName; @@ -91,13 +91,13 @@ nglr.FileController = function(view, scopeName, uploader, databaseUrl) {    this.lastValue = undefined;  }; -nglr.FileController.dispatchEvent = function(id, event, args) { +FileController.dispatchEvent = function(id, event, args) {    var object = document.getElementById(id);    var controller = jQuery(object).data("controller"); -  nglr.FileController.prototype['_on_' + event].apply(controller, args); +  FileController.prototype['_on_' + event].apply(controller, args);  }; -nglr.FileController.template = function(id) { +FileController.template = function(id) {    return jQuery('<span class="ng-upload-widget">' +        '<input type="checkbox" ng-non-bindable="true"/>' +        '<object id="' + id + '" />' + @@ -106,33 +106,33 @@ nglr.FileController.template = function(id) {      '</span>');  }; -nglr.FileController.prototype._on_cancel = function() { +FileController.prototype._on_cancel = function() {  }; -nglr.FileController.prototype._on_complete = function() { +FileController.prototype._on_complete = function() {  }; -nglr.FileController.prototype._on_httpStatus = function(status) { -  nglr.alert("httpStatus:" + this.scopeName + " status:" + status); +FileController.prototype._on_httpStatus = function(status) { +  alert("httpStatus:" + this.scopeName + " status:" + status);  }; -nglr.FileController.prototype._on_ioError = function() { -  nglr.alert("ioError:" + this.scopeName); +FileController.prototype._on_ioError = function() { +  alert("ioError:" + this.scopeName);  }; -nglr.FileController.prototype._on_open = function() { -  nglr.alert("open:" + this.scopeName); +FileController.prototype._on_open = function() { +  alert("open:" + this.scopeName);  }; -nglr.FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) { +FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) {  }; -nglr.FileController.prototype._on_securityError = function() { -  nglr.alert("securityError:" + this.scopeName); +FileController.prototype._on_securityError = function() { +  alert("securityError:" + this.scopeName);  }; -nglr.FileController.prototype._on_uploadCompleteData = function(data) { -  var value = nglr.fromJson(data); +FileController.prototype._on_uploadCompleteData = function(data) { +  var value = fromJson(data);    value.url = this.attachmentsPath + '/' + value.id + '/' + value.text;    this.view.find("input").attr('checked', true);    var scope = this.view.scope(); @@ -142,14 +142,14 @@ nglr.FileController.prototype._on_uploadCompleteData = function(data) {    scope.get('$binder').updateView();  }; -nglr.FileController.prototype._on_select = function(name, size, type) { +FileController.prototype._on_select = function(name, size, type) {    this.name = name;    this.view.find("a").text(name).attr('href', name);    this.view.find("span").text(angular.filter.bytes(size));    this.upload();  }; -nglr.FileController.prototype.updateModel = function(scope) { +FileController.prototype.updateModel = function(scope) {    var isChecked = this.view.find("input").attr('checked');    var value = isChecked ? this.value : null;    if (this.lastValue === value) { @@ -160,7 +160,7 @@ nglr.FileController.prototype.updateModel = function(scope) {    }  }; -nglr.FileController.prototype.updateView = function(scope) { +FileController.prototype.updateView = function(scope) {    var modelValue = scope.get(this.scopeName);    if (modelValue && this.value !== modelValue) {      this.value = modelValue; @@ -172,7 +172,7 @@ nglr.FileController.prototype.updateView = function(scope) {    this.view.find("input").attr('checked', !!modelValue);  }; -nglr.FileController.prototype.upload = function() { +FileController.prototype.upload = function() {    if (this.name) {      this.uploader.uploadFile(this.attachmentsPath);    } @@ -182,23 +182,23 @@ nglr.FileController.prototype.upload = function() {  ///////////////////////  // NullController  /////////////////////// -nglr.NullController = function(view) {this.view = view;}; -nglr.NullController.prototype.updateModel = function() { return true; }; -nglr.NullController.prototype.updateView = function() { }; -nglr.NullController.instance = new nglr.NullController(); +NullController = function(view) {this.view = view;}; +NullController.prototype.updateModel = function() { return true; }; +NullController.prototype.updateView = function() { }; +NullController.instance = new NullController();  ///////////////////////  // ButtonController  /////////////////////// -nglr.ButtonController = function(view) {this.view = view;}; -nglr.ButtonController.prototype.updateModel = function(scope) { return true; }; -nglr.ButtonController.prototype.updateView = function(scope) {}; +ButtonController = function(view) {this.view = view;}; +ButtonController.prototype.updateModel = function(scope) { return true; }; +ButtonController.prototype.updateView = function(scope) {};  ///////////////////////  // TextController  /////////////////////// -nglr.TextController = function(view, exp) { +TextController = function(view, exp) {    this.view = view;    this.exp = exp;    this.validator = view.getAttribute('ng-validate'); @@ -212,7 +212,7 @@ nglr.TextController = function(view, exp) {    }  }; -nglr.TextController.prototype.updateModel = function(scope) { +TextController.prototype.updateModel = function(scope) {    var value = this.view.value;    if (this.lastValue === value) {      return false; @@ -223,7 +223,7 @@ nglr.TextController.prototype.updateModel = function(scope) {    }  }; -nglr.TextController.prototype.updateView = function(scope) { +TextController.prototype.updateView = function(scope) {    var view = this.view;    var value = scope.get(this.exp);    if (typeof value === "undefined") { @@ -258,14 +258,14 @@ nglr.TextController.prototype.updateView = function(scope) {  ///////////////////////  // CheckboxController  /////////////////////// -nglr.CheckboxController = function(view, exp) { +CheckboxController = function(view, exp) {    this.view = view;    this.exp = exp;    this.lastValue = undefined;    this.initialValue = view.checked ? view.value : "";  }; -nglr.CheckboxController.prototype.updateModel = function(scope) { +CheckboxController.prototype.updateModel = function(scope) {    var input = this.view;    var value = input.checked ? input.value : '';    if (this.lastValue === value) { @@ -277,7 +277,7 @@ nglr.CheckboxController.prototype.updateModel = function(scope) {    }  }; -nglr.CheckboxController.prototype.updateView = function(scope) { +CheckboxController.prototype.updateView = function(scope) {    var input = this.view;    var value = scope.eval(this.exp);    if (typeof value === "undefined") { @@ -290,14 +290,14 @@ nglr.CheckboxController.prototype.updateView = function(scope) {  ///////////////////////  // SelectController  /////////////////////// -nglr.SelectController = function(view, exp) { +SelectController = function(view, exp) {    this.view = view;    this.exp = exp;    this.lastValue = undefined;    this.initialValue = view.value;  }; -nglr.SelectController.prototype.updateModel = function(scope) { +SelectController.prototype.updateModel = function(scope) {    var input = this.view;    if (input.selectedIndex < 0) {      scope.setEval(this.exp, null); @@ -313,7 +313,7 @@ nglr.SelectController.prototype.updateModel = function(scope) {    }  }; -nglr.SelectController.prototype.updateView = function(scope) { +SelectController.prototype.updateView = function(scope) {    var input = this.view;    var value = scope.get(this.exp);    if (typeof value === 'undefined') { @@ -329,14 +329,14 @@ nglr.SelectController.prototype.updateView = function(scope) {  ///////////////////////  // MultiSelectController  /////////////////////// -nglr.MultiSelectController = function(view, exp) { +MultiSelectController = function(view, exp) {    this.view = view;    this.exp = exp;    this.lastValue = undefined;    this.initialValue = this.selected();  }; -nglr.MultiSelectController.prototype.selected = function () { +MultiSelectController.prototype.selected = function () {    var value = [];    var options = this.view.options;    for ( var i = 0; i < options.length; i++) { @@ -348,7 +348,7 @@ nglr.MultiSelectController.prototype.selected = function () {    return value;  }; -nglr.MultiSelectController.prototype.updateModel = function(scope) { +MultiSelectController.prototype.updateModel = function(scope) {    var value = this.selected();    // TODO: This is wrong! no caching going on here as we are always comparing arrays    if (this.lastValue === value) { @@ -360,7 +360,7 @@ nglr.MultiSelectController.prototype.updateModel = function(scope) {    }  }; -nglr.MultiSelectController.prototype.updateView = function(scope) { +MultiSelectController.prototype.updateView = function(scope) {    var input = this.view;    var selected = scope.get(this.exp);    if (typeof selected === "undefined") { @@ -380,7 +380,7 @@ nglr.MultiSelectController.prototype.updateView = function(scope) {  ///////////////////////  // RadioController  /////////////////////// -nglr.RadioController = function(view, exp) { +RadioController = function(view, exp) {    this.view = view;    this.exp = exp;    this.lastChecked = undefined; @@ -389,7 +389,7 @@ nglr.RadioController = function(view, exp) {    this.initialValue = view.checked ? view.value : null;  }; -nglr.RadioController.prototype.updateModel = function(scope) { +RadioController.prototype.updateModel = function(scope) {    var input = this.view;    if (this.lastChecked) {      return false; @@ -401,7 +401,7 @@ nglr.RadioController.prototype.updateModel = function(scope) {    }  }; -nglr.RadioController.prototype.updateView = function(scope) { +RadioController.prototype.updateView = function(scope) {    var input = this.view;    var value = scope.get(this.exp);    if (this.initialValue && typeof value === "undefined") { @@ -417,25 +417,25 @@ nglr.RadioController.prototype.updateView = function(scope) {  ///////////////////////  //ElementController  /////////////////////// -nglr.BindUpdater = function(view, exp) { +BindUpdater = function(view, exp) {    this.view = view; -  this.exp = nglr.Binder.parseBindings(exp); +  this.exp = Binder.parseBindings(exp);    this.hasError = false;    this.scopeSelf = {element:view};  }; -nglr.BindUpdater.toText = function(obj) { -  var e = nglr.escapeHtml; +BindUpdater.toText = function(obj) { +  var e = escapeHtml;    switch(typeof obj) {      case "string":      case "boolean":      case "number":        return e(obj);      case "function": -      return nglr.BindUpdater.toText(obj()); +      return BindUpdater.toText(obj());      case "object": -      if (nglr.isNode(obj)) { -        return nglr.outerHTML(obj); +      if (isNode(obj)) { +        return outerHTML(obj);        } else if (obj instanceof angular.filter.Meta) {          switch(typeof obj.html) {            case "string": @@ -444,8 +444,8 @@ nglr.BindUpdater.toText = function(obj) {            case "function":              return obj.html();            case "object": -            if (nglr.isNode(obj.html)) -              return nglr.outerHTML(obj.html); +            if (isNode(obj.html)) +              return outerHTML(obj.html);            default:              break;          } @@ -461,43 +461,43 @@ nglr.BindUpdater.toText = function(obj) {        }        if (obj === null)          return ""; -      return e(nglr.toJson(obj, true)); +      return e(toJson(obj, true));      default:        return "";    }  }; -nglr.BindUpdater.prototype.updateModel = function(scope) {}; -nglr.BindUpdater.prototype.updateView = function(scope) { +BindUpdater.prototype.updateModel = function(scope) {}; +BindUpdater.prototype.updateView = function(scope) {    var html = [];    var parts = this.exp;    var length = parts.length;    for(var i=0; i<length; i++) {      var part = parts[i]; -    var binding = nglr.Binder.binding(part); +    var binding = Binder.binding(part);      if (binding) {        scope.evalWidget(this, binding, this.scopeSelf, function(value){ -        html.push(nglr.BindUpdater.toText(value)); +        html.push(BindUpdater.toText(value));        }, function(e, text){ -        nglr.setHtml(this.view, text); +        setHtml(this.view, text);        });        if (this.hasError) {          return;        }      } else { -      html.push(nglr.escapeHtml(part)); +      html.push(escapeHtml(part));      }    } -  nglr.setHtml(this.view, html.join('')); +  setHtml(this.view, html.join(''));  }; -nglr.BindAttrUpdater = function(view, attrs) { +BindAttrUpdater = function(view, attrs) {    this.view = view;    this.attrs = attrs;  }; -nglr.BindAttrUpdater.prototype.updateModel = function(scope) {}; -nglr.BindAttrUpdater.prototype.updateView = function(scope) { +BindAttrUpdater.prototype.updateModel = function(scope) {}; +BindAttrUpdater.prototype.updateView = function(scope) {    var jNode = jQuery(this.view);    var attributeTemplates = this.attrs;    if (this.hasError) { @@ -508,19 +508,19 @@ nglr.BindAttrUpdater.prototype.updateView = function(scope) {    }    var isImage = jNode.is('img');    for (var attrName in attributeTemplates) { -    var attributeTemplate = nglr.Binder.parseBindings(attributeTemplates[attrName]); +    var attributeTemplate = Binder.parseBindings(attributeTemplates[attrName]);      var attrValues = [];      for ( var i = 0; i < attributeTemplate.length; i++) { -      var binding = nglr.Binder.binding(attributeTemplate[i]); +      var binding = Binder.binding(attributeTemplate[i]);        if (binding) {          try {            var value = scope.eval(binding, {element:jNode[0], attrName:attrName}); -          if (value && (value.constructor !== nglr.array || value.length !== 0)) +          if (value && (value.constructor !== array || value.length !== 0))              attrValues.push(value);          } catch (e) {            this.hasError = true;            console.error('BindAttrUpdater', e); -          var jsonError = nglr.toJson(e, true); +          var jsonError = toJson(e, true);            attrValues.push('[' + jsonError + ']');            jNode.              addClass('ng-exception'). @@ -537,22 +537,22 @@ nglr.BindAttrUpdater.prototype.updateView = function(scope) {    }  }; -nglr.EvalUpdater = function(view, exp) { +EvalUpdater = function(view, exp) {    this.view = view;    this.exp = exp;    this.hasError = false;  }; -nglr.EvalUpdater.prototype.updateModel = function(scope) {}; -nglr.EvalUpdater.prototype.updateView = function(scope) { +EvalUpdater.prototype.updateModel = function(scope) {}; +EvalUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp);  }; -nglr.HideUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.HideUpdater.prototype.updateModel = function(scope) {}; -nglr.HideUpdater.prototype.updateView = function(scope) { +HideUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +HideUpdater.prototype.updateModel = function(scope) {}; +HideUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp, {}, function(hideValue){      var view = jQuery(this.view); -    if (nglr.toBoolean(hideValue)) { +    if (toBoolean(hideValue)) {        view.hide();      } else {        view.show(); @@ -560,12 +560,12 @@ nglr.HideUpdater.prototype.updateView = function(scope) {    });  }; -nglr.ShowUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ShowUpdater.prototype.updateModel = function(scope) {}; -nglr.ShowUpdater.prototype.updateView = function(scope) { +ShowUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ShowUpdater.prototype.updateModel = function(scope) {}; +ShowUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp, {}, function(hideValue){      var view = jQuery(this.view); -    if (nglr.toBoolean(hideValue)) { +    if (toBoolean(hideValue)) {        view.show();      } else {        view.hide(); @@ -573,9 +573,9 @@ nglr.ShowUpdater.prototype.updateView = function(scope) {    });  }; -nglr.ClassUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ClassUpdater.prototype.updateModel = function(scope) {}; -nglr.ClassUpdater.prototype.updateView = function(scope) { +ClassUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ClassUpdater.prototype.updateModel = function(scope) {}; +ClassUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp, {}, function(classValue){      if (classValue !== null && classValue !== undefined) {        this.view.className = classValue; @@ -583,27 +583,27 @@ nglr.ClassUpdater.prototype.updateView = function(scope) {    });  }; -nglr.ClassEvenUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ClassEvenUpdater.prototype.updateModel = function(scope) {}; -nglr.ClassEvenUpdater.prototype.updateView = function(scope) { +ClassEvenUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ClassEvenUpdater.prototype.updateModel = function(scope) {}; +ClassEvenUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp, {}, function(classValue){      var index = scope.get('$index');      jQuery(this.view).toggleClass(classValue, index % 2 === 1);    });  }; -nglr.ClassOddUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ClassOddUpdater.prototype.updateModel = function(scope) {}; -nglr.ClassOddUpdater.prototype.updateView = function(scope) { +ClassOddUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +ClassOddUpdater.prototype.updateModel = function(scope) {}; +ClassOddUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp, {}, function(classValue){      var index = scope.get('$index');      jQuery(this.view).toggleClass(classValue, index % 2 === 0);    });  }; -nglr.StyleUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.StyleUpdater.prototype.updateModel = function(scope) {}; -nglr.StyleUpdater.prototype.updateView = function(scope) { +StyleUpdater = function(view, exp) { this.view = view; this.exp = exp; }; +StyleUpdater.prototype.updateModel = function(scope) {}; +StyleUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.exp, {}, function(styleValue){      jQuery(this.view).attr('style', "").css(styleValue);    }); @@ -612,7 +612,7 @@ nglr.StyleUpdater.prototype.updateView = function(scope) {  ///////////////////////  // RepeaterUpdater  /////////////////////// -nglr.RepeaterUpdater = function(view, repeaterExpression, template, prefix) { +RepeaterUpdater = function(view, repeaterExpression, template, prefix) {    this.view = view;    this.template = template;    this.prefix = prefix; @@ -633,8 +633,8 @@ nglr.RepeaterUpdater = function(view, repeaterExpression, template, prefix) {    this.keyExp = match[2];  }; -nglr.RepeaterUpdater.prototype.updateModel = function(scope) {}; -nglr.RepeaterUpdater.prototype.updateView = function(scope) { +RepeaterUpdater.prototype.updateModel = function(scope) {}; +RepeaterUpdater.prototype.updateView = function(scope) {    scope.evalWidget(this, this.iteratorExp, {}, function(iterator){      var self = this;      if (!iterator) { @@ -660,7 +660,7 @@ nglr.RepeaterUpdater.prototype.updateView = function(scope) {          // grow children          var name = self.prefix +            valueExp + " in " + self.iteratorExp + "[" + i + "]"; -        var childScope = new nglr.Scope(scope.state, name); +        var childScope = new Scope(scope.state, name);          childScope.set('$index', i);          if (keyExp)            childScope.set(keyExp, key); @@ -696,22 +696,22 @@ nglr.RepeaterUpdater.prototype.updateView = function(scope) {  // PopUp  ////////////////////////////////// -nglr.PopUp = function(doc) { +PopUp = function(doc) {    this.doc = doc;  }; -nglr.PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup"; +PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup"; -nglr.PopUp.prototype.bind = function () { +PopUp.prototype.bind = function () {    var self = this;    this.doc.find('.ng-validation-error,.ng-exception'). -    live("mouseover", nglr.PopUp.onOver); +    live("mouseover", PopUp.onOver);  }; -nglr.PopUp.onOver = function(e) { -  nglr.PopUp.onOut(); +PopUp.onOver = function(e) { +  PopUp.onOut();    var jNode = jQuery(this); -  jNode.bind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut); +  jNode.bind(PopUp.OUT_EVENT, PopUp.onOut);    var position = jNode.position();    var de = document.documentElement;    var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; @@ -740,9 +740,9 @@ nglr.PopUp.onOver = function(e) {    return true;  }; -nglr.PopUp.onOut = function() { +PopUp.onOut = function() {    jQuery('#ng-callout'). -    unbind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut). +    unbind(PopUp.OUT_EVENT, PopUp.onOut).      remove();    return true;  }; @@ -752,21 +752,21 @@ nglr.PopUp.onOut = function() {  ////////////////////////////////// -nglr.Status = function(body) { -  this.loader = body.append(nglr.Status.DOM).find("#ng-loading"); +Status = function(body) { +  this.loader = body.append(Status.DOM).find("#ng-loading");    this.requestCount = 0;  }; -nglr.Status.DOM ='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>'; +Status.DOM ='<div id="ng-spacer"></div><div id="ng-loading">loading....</div>'; -nglr.Status.prototype.beginRequest = function () { +Status.prototype.beginRequest = function () {    if (this.requestCount === 0) {      this.loader.show();    }    this.requestCount++;  }; -nglr.Status.prototype.endRequest = function () { +Status.prototype.endRequest = function () {    this.requestCount--;    if (this.requestCount === 0) {      this.loader.hide("fold"); diff --git a/src/Widgets.js.orig b/src/Widgets.js.orig deleted file mode 100644 index df1d3e40..00000000 --- a/src/Widgets.js.orig +++ /dev/null @@ -1,764 +0,0 @@ -   // Copyright (C) 2009 BRAT Tech LLC - - -nglr.WidgetFactory = function(serverUrl) { -  this.nextUploadId = 0; -  this.serverUrl = serverUrl; -  this.createSWF = swfobject.createSWF; -  this.onChangeListener = function(){}; -}; - -nglr.WidgetFactory.prototype.createController = function(input, scope) { -  var controller; -  var type = input.attr('type').toLowerCase(); -  var exp = input.attr('name'); -  if (exp) exp = exp.split(':').pop(); -  var event = "change"; -  var bubbleEvent = true; -  if (type == 'button' || type == 'submit' || type == 'reset') { -    controller = new nglr.ButtonController(input[0], exp); -    event = "click"; -    bubbleEvent = false; -  } else if (type == 'text' || type == 'textarea') { -    controller = new nglr.TextController(input[0], exp); -    event = "keyup change"; -  } else if (type == 'checkbox') { -    controller = new nglr.CheckboxController(input[0], exp); -    event = "click"; -  } else if (type == 'radio') { -    controller = new nglr.RadioController(input[0], exp); -    event="click"; -  } else if (type == 'select-one') { -    controller = new nglr.SelectController(input[0], exp); -  } else if (type == 'select-multiple') { -    controller = new nglr.MultiSelectController(input[0], exp); -  } else if (type == 'file') { -    controller = this.createFileController(input, exp); -  } else { -    throw 'Unknown type: ' + type; -  } -  input.data('controller', controller); -  var binder = scope.get('$binder'); -  var action = function() { -    if (controller.updateModel(scope)) { -      var action = jQuery(controller.view).attr('ng-action') || ""; -      if (scope.evalWidget(controller, action)) { -        binder.updateView(scope); -      } -    } -    return bubbleEvent; -  }; -  jQuery(controller.view, ":input"). -    bind(event, action); -  return controller; -}; - -nglr.WidgetFactory.prototype.createFileController = function(fileInput) { -  var uploadId = '__uploadWidget_' + (this.nextUploadId++); -  var view = nglr.FileController.template(uploadId); -  fileInput.after(view); -  var att = { -      data:this.serverUrl + "/admin/ServerAPI.swf", -      width:"95", height:"20", align:"top", -      wmode:"transparent"}; -  var par = { -      flashvars:"uploadWidgetId=" + uploadId, -      allowScriptAccess:"always"}; -  var swfNode = this.createSWF(att, par, uploadId); -  fileInput.remove(); -  var cntl = new nglr.FileController(view, fileInput[0].name, swfNode, this.serverUrl); -  jQuery(swfNode).data('controller', cntl); -  return cntl; -}; - -nglr.WidgetFactory.prototype.createTextWidget = function(textInput) { -  var controller = new nglr.TextController(textInput); -  controller.onChange(this.onChangeListener); -  return controller; -}; - -///////////////////// -// FileController -/////////////////////// - -nglr.FileController = function(view, scopeName, uploader, serverUrl) { -  this.view = view; -  this.uploader = uploader; -  this.scopeName = scopeName; -  this.uploadUrl = serverUrl + '/upload'; -  this.attachmentBase = serverUrl + '/attachments'; -  this.value = null; -  this.lastValue = undefined; -}; - -nglr.FileController.dispatchEvent = function(id, event, args) { -  var object = document.getElementById(id); -  var controller = jQuery(object).data("controller"); -  nglr.FileController.prototype['_on_' + event].apply(controller, args); -}; - -nglr.FileController.template = function(id) { -  return jQuery('<span class="ng-upload-widget">' + -      '<input type="checkbox" ng-non-bindable="true"/>' + -      '<object id="' + id + '" />' + -      '<a></a>' + -      '<span/>' + -    '</span>'); -}; - -nglr.FileController.prototype._on_cancel = function() { -}; - -nglr.FileController.prototype._on_complete = function() { -}; - -nglr.FileController.prototype._on_httpStatus = function(status) { -  nglr.alert("httpStatus:" + this.scopeName + " status:" + status); -}; - -nglr.FileController.prototype._on_ioError = function() { -  nglr.alert("ioError:" + this.scopeName); -}; - -nglr.FileController.prototype._on_open = function() { -  nglr.alert("open:" + this.scopeName); -}; - -nglr.FileController.prototype._on_progress = function(bytesLoaded, bytesTotal) { -}; - -nglr.FileController.prototype._on_securityError = function() { -  nglr.alert("securityError:" + this.scopeName); -}; - -nglr.FileController.prototype._on_uploadCompleteData = function(data) { -  this.value = nglr.fromJson(data); -  this.value.url = this.attachmentBase + '/' + this.value.id + '/' + this.value.text; -  this.view.find("input").attr('checked', true); -  var scope = this.view.scope(); -  this.updateModel(scope); -  scope.get('$binder').updateView(); -}; - -nglr.FileController.prototype._on_select = function(name, size, type) { -  this.name = name; -  this.view.find("a").text(name).attr('href', name); -  this.view.find("span").text(filters.bytes(size)); -  this.upload(); -}; - -nglr.FileController.prototype.updateModel = function(scope) { -  var isChecked = this.view.find("input").attr('checked'); -  var value = isChecked ? this.value : null; -  if (this.lastValue === value) { -    return false; -  } else { -    scope.set(this.scopeName, value); -    return true; -  } -}; - -nglr.FileController.prototype.updateView = function(scope) { -  var modelValue = scope.get(this.scopeName); -  if (modelValue && this.value !== modelValue) { -    this.value = modelValue; -    this.view.find("a"). -    attr("href", this.value.url). -    text(this.value.name); -    this.view.find("span").text(filters.bytes(this.value.size)); -  } -  this.view.find("input").attr('checked', !!modelValue); -}; - -nglr.FileController.prototype.upload = function() { -  if (this.name) { -    this.uploader.uploadFile(this.uploadUrl); -  } -}; - - -/////////////////////// -// NullController -/////////////////////// -nglr.NullController = function(view) {this.view = view;}; -nglr.NullController.prototype.updateModel = function() { return true; }; -nglr.NullController.prototype.updateView = function() { }; -nglr.NullController.instance = new nglr.NullController(); - - -/////////////////////// -// ButtonController -/////////////////////// -nglr.ButtonController = function(view) {this.view = view;}; -nglr.ButtonController.prototype.updateModel = function(scope) { return true; }; -nglr.ButtonController.prototype.updateView = function(scope) {}; - -/////////////////////// -// TextController -/////////////////////// -nglr.TextController = function(view, exp) { -  this.view = view; -  this.exp = exp; -  this.validator = view.getAttribute('ng-validate'); -  this.required = typeof view.attributes['ng-required'] != "undefined"; -  this.lastErrorText = null; -  this.lastValue = undefined; -  this.initialValue = view.value; -  var widget = view.getAttribute('ng-widget'); -  if (widget === 'datepicker') { -    jQuery(view).datepicker(); -  } -}; - -nglr.TextController.prototype.updateModel = function(scope) { -  var value = this.view.value; -  if (this.lastValue === value) { -    return false; -  } else { -    scope.set(this.exp, value); -    this.lastValue = value; -    return true; -  } -}; - -nglr.TextController.prototype.updateView = function(scope) { -  var view = this.view; -  var value = scope.get(this.exp); -  if (typeof value === "undefined") { -    value = this.initialValue; -    scope.set(this.exp, value); -  } -  value = value ? value : ''; -  if (this.lastValue != value) { -    view.value = value; -    this.lastValue = value; -  } -  var isValidationError = false; -  view.removeAttribute('ng-error'); -  if (this.required) { -    isValidationError = !(value && value.length > 0); -  } -  var errorText = isValidationError ? "Required Value" : null; -  if (!isValidationError && this.validator && value) { -    errorText = scope.validate(this.validator, value); -    isValidationError = !!errorText; -  } -  if (this.lastErrorText !== errorText) { -    this.lastErrorText = isValidationError; -    if (errorText !== null) { -      view.setAttribute('ng-error', errorText); -      scope.markInvalid(this); -    } -    jQuery(view).toggleClass('ng-validation-error', isValidationError); -  } -}; - -/////////////////////// -// CheckboxController -/////////////////////// -nglr.CheckboxController = function(view, exp) { -  this.view = view; -  this.exp = exp; -  this.lastValue = undefined; -  this.initialValue = view.checked ? view.value : ""; -}; - -nglr.CheckboxController.prototype.updateModel = function(scope) { -  var input = this.view; -  var value = input.checked ? input.value : ''; -  if (this.lastValue === value) { -    return false; -  } else { -    scope.setEval(this.exp, value); -    this.lastValue = value; -    return true; -  } -}; - -nglr.CheckboxController.prototype.updateView = function(scope) { -  var input = this.view; -  var value = scope.eval(this.exp); -  if (typeof value === "undefined") { -    value = this.initialValue; -    scope.setEval(this.exp, value); -  } -  input.checked = input.value == (''+value); -}; - -/////////////////////// -// SelectController -/////////////////////// -nglr.SelectController = function(view, exp) { -  this.view = view; -  this.exp = exp; -  this.lastValue = undefined; -  this.initialValue = view.value; -}; - -nglr.SelectController.prototype.updateModel = function(scope) { -  var input = this.view; -  if (input.selectedIndex < 0) { -    scope.set(this.exp, null); -  } else { -    var value = this.view.value; -    if (this.lastValue === value) { -      return false; -    } else { -      scope.set(this.exp, value); -      this.lastValue = value; -      return true; -    } -  } -}; - -nglr.SelectController.prototype.updateView = function(scope) { -  var input = this.view; -  var value = scope.get(this.exp); -  if (typeof value === 'undefined') { -    value = this.initialValue; -    scope.set(this.exp, value); -  } -  if (value !== this.lastValue) { -    input.value = value ? value : ""; -    this.lastValue = value; -  } -}; - -/////////////////////// -// MultiSelectController -/////////////////////// -nglr.MultiSelectController = function(view, exp) { -  this.view = view; -  this.exp = exp; -  this.lastValue = undefined; -  this.initialValue = this.selected(); -}; - -nglr.MultiSelectController.prototype.selected = function () { -  var value = []; -  var options = this.view.options; -  for ( var i = 0; i < options.length; i++) { -    var option = options[i]; -    if (option.selected) { -      value.push(option.value); -    } -  } -  return value; -}; - -nglr.MultiSelectController.prototype.updateModel = function(scope) { -  var value = this.selected(); -  // TODO: This is wrong! no caching going on here as we are always comparing arrays -  if (this.lastValue === value) { -    return false; -  } else { -    scope.set(this.exp, value); -    this.lastValue = value; -    return true; -  } -}; - -nglr.MultiSelectController.prototype.updateView = function(scope) { -  var input = this.view; -  var selected = scope.get(this.exp); -  if (typeof selected === "undefined") { -    selected = this.initialValue; -    scope.set(this.exp, selected); -  } -  if (selected !== this.lastValue) { -    var options = input.options; -    for ( var i = 0; i < options.length; i++) { -      var option = options[i]; -      option.selected = selected.contains(option.value); -    } -    this.lastValue = selected; -  } -}; - -/////////////////////// -// RadioController -/////////////////////// -nglr.RadioController = function(view, exp) { -  this.view = view; -  this.exp = exp; -  this.lastChecked = undefined; -  this.lastValue = undefined; -  this.inputValue = view.value; -  this.initialValue = view.checked ? view.value : null; -}; - -nglr.RadioController.prototype.updateModel = function(scope) { -  var input = this.view; -  if (this.lastChecked) { -    return false; -  } else { -    input.checked = true; -    this.lastValue = scope.set(this.exp, this.inputValue); -    this.lastChecked = true; -    return true; -  } -}; - -nglr.RadioController.prototype.updateView = function(scope) { -  var input = this.view; -  var value = scope.get(this.exp); -  if (this.initialValue && typeof value === "undefined") { -    value = this.initialValue; -    scope.set(this.exp, value); -  } -  if (this.lastValue != value) { -    this.lastChecked = input.checked = this.inputValue == (''+value); -    this.lastValue = value; -  } -}; - -/////////////////////// -//ElementController -/////////////////////// -nglr.BindUpdater = function(view, exp) { -  this.view = view; -  this.exp = exp.parseBindings(); -  this.hasError = false; -  this.scopeSelf = {element:view}; -}; - -nglr.BindUpdater.toText = function(obj) { -  var e = nglr.escapeHtml; -  switch(typeof obj) { -    case "string": -    case "boolean": -    case "number": -      return e(obj); -    case "function": -      return nglr.BindUpdater.toText(obj()); -    case "object": -      if (nglr.isNode(obj)) { -        return nglr.outerHTML(obj); -      } else if (obj && obj.TAG === filters.Meta.TAG) { -        switch(typeof obj.html) { -          case "string": -          case "number": -            return obj.html; -          case "function": -            return obj.html(); -          default: -            break; -        } -        switch(typeof obj.text) { -          case "string": -          case "number": -            return e(obj.text); -          case "function": -            return e(obj.text()); -          default: -            break; -        } -      } -      if (obj === null) -        return ""; -      return e(nglr.toJson(obj, true)); -    default: -      return ""; -  } -}; - -nglr.BindUpdater.prototype.updateModel = function(scope) {}; -nglr.BindUpdater.prototype.updateView = function(scope) { -  var html = []; -  var parts = this.exp; -  var length = parts.length; -  for(var i=0; i<length; i++) { -    var part = parts[i]; -    var binding = part.binding(); -    if (binding) { -      scope.evalWidget(this, binding, this.scopeSelf, function(value){ -        html.push(nglr.BindUpdater.toText(value)); -      }, function(e, text){ -        nglr.setHtml(this.view, text); -      }); -      if (this.hasError) { -        return; -      } -    } else { -      html.push(nglr.escapeHtml(part)); -    } -  } -  nglr.setHtml(this.view, html.join('')); -}; - -nglr.BindAttrUpdater = function(view, attrs) { -  this.view = view; -  this.attrs = attrs; -}; - -nglr.BindAttrUpdater.prototype.updateModel = function(scope) {}; -nglr.BindAttrUpdater.prototype.updateView = function(scope) { -  var jNode = jQuery(this.view); -  var attributeTemplates = this.attrs; -  if (this.hasError) { -    this.hasError = false; -    jNode. -      removeClass('ng-exception'). -      removeAttr('ng-error'); -  } -  var isImage = jNode.is('img'); -  for (var attrName in attributeTemplates) { -    var attributeTemplate = attributeTemplates[attrName].parseBindings(); -    var attrValues = []; -    for ( var i = 0; i < attributeTemplate.length; i++) { -      var binding = attributeTemplate[i].binding(); -      if (binding) { -        try { -          var value = scope.eval(binding, {element:jNode[0], attrName:attrName}); -          if (value && (value.constructor !== nglr.array || value.length !== 0)) -            attrValues.push(value); -        } catch (e) { -          this.hasError = true; -          console.error('BindAttrUpdater', e); -          var jsonError = nglr.toJson(e, true); -          attrValues.push('[' + jsonError + ']'); -          jNode. -            addClass('ng-exception'). -            attr('ng-error', jsonError); -        } -      } else { -        attrValues.push(attributeTemplate[i]); -      } -    } -    var attrValue = attrValues.length ? attrValues.join('') : null; -    if(isImage && attrName == 'src' && !attrValue) -      attrValue = scope.get('config.server') + '/images/blank.gif'; -    jNode.attr(attrName, attrValue); -  } -}; - -nglr.EvalUpdater = function(view, exp) { -  this.view = view; -  this.exp = exp; -  this.hasError = false; -}; -nglr.EvalUpdater.prototype.updateModel = function(scope) {}; -nglr.EvalUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp); -}; - -nglr.HideUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.HideUpdater.prototype.updateModel = function(scope) {}; -nglr.HideUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp, {}, function(hideValue){ -    var view = jQuery(this.view); -    if (nglr.toBoolean(hideValue)) { -      view.hide(); -    } else { -      view.show(); -    } -  }); -}; - -nglr.ShowUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ShowUpdater.prototype.updateModel = function(scope) {}; -nglr.ShowUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp, {}, function(hideValue){ -    var view = jQuery(this.view); -    if (nglr.toBoolean(hideValue)) { -      view.show(); -    } else { -      view.hide(); -    } -  }); -}; - -nglr.ClassUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ClassUpdater.prototype.updateModel = function(scope) {}; -nglr.ClassUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp, {}, function(classValue){ -    if (classValue !== null && classValue !== undefined) { -      this.view.className = classValue; -    } -  }); -}; - -nglr.ClassEvenUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ClassEvenUpdater.prototype.updateModel = function(scope) {}; -nglr.ClassEvenUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp, {}, function(classValue){ -    var index = scope.get('$index'); -    jQuery(this.view).toggleClass(classValue, index % 2 === 1); -  }); -}; - -nglr.ClassOddUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.ClassOddUpdater.prototype.updateModel = function(scope) {}; -nglr.ClassOddUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp, {}, function(classValue){ -    var index = scope.get('$index'); -    jQuery(this.view).toggleClass(classValue, index % 2 === 0); -  }); -}; - -nglr.StyleUpdater = function(view, exp) { this.view = view; this.exp = exp; }; -nglr.StyleUpdater.prototype.updateModel = function(scope) {}; -nglr.StyleUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.exp, {}, function(styleValue){ -    jQuery(this.view).attr('style', "").css(styleValue); -  }); -}; - -/////////////////////// -// RepeaterUpdater -/////////////////////// -nglr.RepeaterUpdater = function(view, repeaterExpression, template, prefix) { -  this.view = view; -  this.template = template; -  this.prefix = prefix; -  this.children = []; -  var match = repeaterExpression.match(/^\s*(.+)\s+in\s+(.*)\s*$/); -  if (! match) { -    throw "Expected ng-repeat in form of 'item in collection' but got '" + repeaterExpression + "'."; -  } -  this.itemExp = match[1]; -  this.iteratorExp = match[2]; -}; - -nglr.RepeaterUpdater.prototype.updateModel = function(scope) {}; -nglr.RepeaterUpdater.prototype.updateView = function(scope) { -  scope.evalWidget(this, this.iteratorExp, {}, function(iterator){ -    if (!iterator) { -      iterator = []; -      if (scope.isProperty(this.iteratorExp)) { -        scope.set(this.iteratorExp, iterator); -      } -    } -    var iteratorLength = iterator.length; -    var childrenLength = this.children.length; -    var cursor = this.view; -    var time = 0; -    var child = null; -    var itemExp = this.itemExp; -    for ( var i = 0; i < iteratorLength; i++) { -      if (i < iteratorLength) { -        if (i < childrenLength) { // reuse children -          child = this.children[i]; -          child.scope.set(itemExp, iterator[i]); -        } else { // grow children -          var name = this.prefix + -          itemExp + " in " + this.iteratorExp + "[" + i + "]"; -          var childScope = new nglr.Scope(scope.state, name); -          childScope.set('$index', i); -          childScope.set(itemExp, iterator[i]); -          child = { scope:childScope, element:this.template(childScope, this.prefix, i) }; -          cursor.after(child.element); -          this.children.push(child); -        } -        cursor = child.element; -        var s = new Date().getTime(); -        child.scope.updateView(); -        time += new Date().getTime() - s; -      } -    } -    // shrink children -    for ( var r = childrenLength; r > iteratorLength; --r) { -      var unneeded = this.children.pop(); -      unneeded.element.removeNode(); -    } -    // Special case for option in select -    if (child && child.element[0].nodeName === "OPTION") { -      var select = jQuery(child.element[0].parentNode); -      var cntl = select.data('controller'); -      if (cntl) { -        cntl.lastValue = undefined; -        cntl.updateView(scope); -      } -    } -  }); -}; - -////////////////////////////////// -// PopUp -////////////////////////////////// - -nglr.PopUp = function(doc) { -  this.doc = doc; -}; - -nglr.PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup"; - -nglr.PopUp.prototype.bind = function () { -  var self = this; -  this.doc.find('.ng-validation-error,.ng-exception'). -    live("mouseover", nglr.PopUp.onOver); -}; - -nglr.PopUp.onOver = function(e) { -  nglr.PopUp.onOut(); -  var jNode = jQuery(this); -  jNode.bind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut); -  var position = jNode.position(); -  var de = document.documentElement; -  var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth; -  var hasArea = w - position.left; -  var width = 300; -  var title = jNode.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error..."; -  var msg = jNode.attr("ng-error"); - -  var x; -  var arrowPos = hasArea>(width+75) ? "left" : "right"; -  var tip = jQuery( -    "<div id='ng-callout' style='width:"+width+"px'>" + -      "<div class='ng-arrow-"+arrowPos+"'/>" + -      "<div class='ng-title'>"+title+"</div>" + -      "<div class='ng-content'>"+msg+"</div>" + -    "</div>"); -  jQuery("body").append(tip); -  if(arrowPos === 'left'){ -    x = position.left + this.offsetWidth + 11; -  }else{ -    x = position.left - (width + 15); -    tip.find('.ng-arrow-right').css({left:width+1}); -  } - -  tip.css({left: x+"px", top: (position.top - 3)+"px"}); -  return true; -}; - -nglr.PopUp.onOut = function() { -  jQuery('#ng-callout'). -    unbind(nglr.PopUp.OUT_EVENT, nglr.PopUp.onOut). -    remove(); -  return true; -}; - -////////////////////////////////// -// Status -////////////////////////////////// - -nglr.Status = function (body) { -  this.body = body; -  this.requestCount = 0; -}; -nglr.Status.ANGULAR = "<a class='ng-angular-logo' href='http://www.getangular.com'>&lt;angular/&gt;</a>™"; - -nglr.Status.prototype.beginRequest = function () { -  if (this.requestCount === 0) { -<<<<<<< HEAD:public/javascripts/nglr/Widgets.js -    this.dialogView = jQuery('<div class="ng-dialog" title="'+nglr.ControlBar.ANGULAR+' Server Communication:">Please Wait...<div/><div class="loader"></div></div>'); -======= -    this.dialogView = jQuery('<div title="'+nglr.Status.ANGULAR+' Server Communication:">Please Wait...<div/></div>'); -    this.progressWidget = this.dialogView.find("div"); -    this.progressWidget.progressbar({value:0}); ->>>>>>> master:public/javascripts/nglr/Widgets.js -    this.dialogView.dialog({bgiframe:true, minHeight:50, modal:true}); -    this.maxRequestCount = 0; -  } -  this.requestCount++; -  this.maxRequestCount++; -}; - -nglr.Status.prototype.endRequest = function () { -  this.requestCount--; -  if (this.requestCount === 0) { -    this.dialogView.dialog("destroy"); -    this.dialogView.remove(); -    this.dialogView = null; -  } -}; diff --git a/src/XSitePost.js b/src/XSitePost.js deleted file mode 100644 index 7d81e207..00000000 --- a/src/XSitePost.js +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2008,2009 BRAT Tech LLC - -if (typeof nglr == 'undefined') nglr = {}; - -if (typeof console == 'undefined') console = {}; -if (typeof console.log == 'undefined') -  console.log = function() {}; -if (typeof console.error == 'undefined') -  console.error = function() {}; - -nglr.XSitePost = function(baseUrl, window, prefix) { -  this.baseUrl = baseUrl; -  this.post = jQuery.post; -  this.window = window; -  this.inQueue = {}; -  this.outQueue = []; -  this.maxMsgSize = 100000; -  this.delay = 20; -  this.prefix = prefix; -  this.setTimeout=function(fn, delay){window.setTimeout(fn, delay);}; -}; - -nglr.XSitePost.prototype.init = function() { -  this.window.name = ''; -  this.response('ready', 'null'); -}; - -nglr.XSitePost.prototype.incomingFragment = function(fragment) { -  var parts = fragment.split(";"); -  this.incomingMsg(parts.shift(), 1*parts.shift(), 1*parts.shift(), parts.shift()); -}; - -nglr.XSitePost.prototype.incomingMsg = function(id, partNo, totalParts, msgPart) { -  var msg = this.inQueue[id]; -  if (!msg) { -    msg = {id:id, parts:[], count:0}; -    this.inQueue[id] = msg; -  } -  msg.parts[partNo] = msgPart; -  msg.count++; -  if (totalParts === msg.count) { -    delete this.inQueue[id]; -    var request = this.decodePost(msg.parts.join('')); -    var self = this; -    this.post(this.baseUrl + request.url, request.params, function(response, status){ -      self.response(id, response, status); -    }); -  } -}; - -nglr.XSitePost.prototype.response = function(id, response, status) { -  var start = 0; -  var end; -  var msg = Base64.encode(response); -  var msgLen = msg.length; -  var total = Math.ceil(msgLen / this.maxMsgSize); -  var part = 0; -  while (start < msgLen) { -    end = Math.min(msgLen, start + this.maxMsgSize); -    this.outQueue.push(id + ':'+part+':'+total+':' + msg.substring(start, end)); -    start = end; -    part++; -  } -}; - -nglr.XSitePost.prototype.decodePost = function(post) { -  var parts = post.split(':'); -  var url = Base64.decode(parts.shift()); -  var params = {}; -  while(parts.length !== 0) { -    var key = parts.shift(); -    var value = Base64.decode(parts.shift()); -    params[key] = value; -  } -  return {url:url, params:params}; -}; - -nglr.XSitePost.prototype.listen = function() { -  console.log("listen()"); -  var self = this; -  var window = this.window; -  var outQueue = this.outQueue; -  var setTimeout = this.setTimeout; -  var prefix = this.prefix; -  var prefixLen = prefix.length; -  var prefixRec = prefix + '>'; -  var prefixRecLen = prefixRec.length; -  window.name = prefix; -  var pull = function(){ -    var value = window.name; -    if (value == prefix && outQueue.length > 0) { -      window.name = prefix + '<' + outQueue.shift(); -    } else if (value.substr(0, prefixRecLen) == prefixRec) { -      self.incomingFragment(value.substr(prefixRecLen)); -      window.name = prefix; -    } -    setTimeout(pull, self.delay); -  }; -  pull(); -}; diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js index 8ac4f9f3..b13bbf34 100644 --- a/src/angular-bootstrap.js +++ b/src/angular-bootstrap.js @@ -80,9 +80,8 @@          doc = window.document.getElementById(id);        }      } -    var angular = window.angularFactory(scriptConfig);      if (scriptConfig.autoBind && doc) { -      window.angularScope = angular.compile(doc); +      window.angularScope = angular.compile(doc, scriptConfig);      }      if (typeof previousOnLoad === 'function') {        try { diff --git a/src/angular.prefix b/src/angular.prefix new file mode 100644 index 00000000..522c17bf --- /dev/null +++ b/src/angular.prefix @@ -0,0 +1,2 @@ + +(function(window, document){
\ No newline at end of file diff --git a/src/angular.suffix b/src/angular.suffix new file mode 100644 index 00000000..4b3cc37b --- /dev/null +++ b/src/angular.suffix @@ -0,0 +1 @@ +})(window, document);
\ No newline at end of file diff --git a/src/test/Runner.js b/src/test/Runner.js index c7dd431a..5840282e 100644 --- a/src/test/Runner.js +++ b/src/test/Runner.js @@ -1,11 +1,11 @@ -if (!nglr.test)        nglr.test = {}; +if (typeof test == 'undefined')        test = {}; -nglr.test.ScenarioRunner = function(scenarios, body) { +test.ScenarioRunner = function(scenarios, body) {    this.scenarios = scenarios;    this.body = body;  }; -nglr.test.ScenarioRunner.prototype = { +test.ScenarioRunner.prototype = {    run:function(){      this.setUpUI();      this.runScenarios(); @@ -25,22 +25,22 @@ nglr.test.ScenarioRunner.prototype = {      });    },    runScenarios:function(){ -    var runner = new nglr.test.Runner(this.console, this.testFrame); +    var runner = new test.Runner(this.console, this.testFrame);      _.stepper(this.scenarios, function(next, scenario, name){ -        new nglr.test.Scenario(name, scenario).run(runner, next); +        new test.Scenario(name, scenario).run(runner, next);        }, function(){        }      );    }  }; -nglr.test.Runner = function(console, frame){ +test.Runner = function(console, frame){    this.console = console;    this.current = null;    this.tests = [];    this.frame = frame;  }; -nglr.test.Runner.prototype = { +test.Runner.prototype = {    start:function(name){      var current = this.current = {        name:name, @@ -75,7 +75,7 @@ nglr.test.Runner.prototype = {      var buf = [];      for ( var i = 1; i < arguments.length; i++) {        var arg = arguments[i]; -      buf.push(typeof arg == "string" ?arg:nglr.toJson(arg)); +      buf.push(typeof arg == "string" ?arg:toJson(arg));      }      var log = jQuery('<div class="' + level + '"></div>');      log.text(buf.join(" ")); @@ -86,11 +86,11 @@ nglr.test.Runner.prototype = {    }  }; -nglr.test.Scenario = function(name, scenario){ +test.Scenario = function(name, scenario){    this.name = name;    this.scenario = scenario;  }; -nglr.test.Scenario.prototype = { +test.Scenario.prototype = {    run:function(runner, callback) {      var self = this;      _.stepper(this.scenario, function(next, steps, name){ @@ -115,7 +115,7 @@ nglr.test.Scenario.prototype = {    else if (step.When) fn = angular.test.WHEN[step.When];    else if (step.Then) fn = angular.test.THEN[step.Then];      return fn || function (){ -             throw "ERROR: Need Given/When/Then got: " + nglr.toJson(step); +             throw "ERROR: Need Given/When/Then got: " + toJson(step);             };    },    context: function(runner) { @@ -149,14 +149,14 @@ nglr.test.Scenario.prototype = {      callback();      return;    } -    runner.log("info", nglr.toJson(step)); +    runner.log("info", toJson(step));      var fn = this.verb(step);      var context = this.context(runner);      _.extend(context, step);      try {        (fn.call(context)||function(c){c();})(callback);      } catch (e) { -      runner.log("error", "ERROR: " + nglr.toJson(e)); +      runner.log("error", "ERROR: " + toJson(e));      }    }  }; diff --git a/src/test/Steps.js b/src/test/Steps.js index af4b84d6..cc9ff549 100644 --- a/src/test/Steps.js +++ b/src/test/Steps.js @@ -14,7 +14,7 @@ angular.test.GIVEN = {      };    },    dataset:function(){ -    this.frame.name="$DATASET:" + nglr.toJson({dataset:this.dataset}); +    this.frame.name="$DATASET:" + toJson({dataset:this.dataset});    }  };  angular.test.WHEN = { diff --git a/test/BinderTest.js b/test/BinderTest.js index d033996d..0ffd2120 100644 --- a/test/BinderTest.js +++ b/test/BinderTest.js @@ -3,10 +3,10 @@ BinderTest = TestCase('BinderTest');  function compile(content, initialScope, config) {    var h = html(content);    config = config || {autoSubmit:true}; -  var scope = new nglr.Scope(initialScope, "ROOT"); +  var scope = new Scope(initialScope, "ROOT");    h.data('scope', scope); -  var binder = new nglr.Binder(h[0], new nglr.WidgetFactory(), new MockUrlWatcher(), config); -  var datastore = new nglr.DataStore(); +  var binder = new Binder(h[0], new WidgetFactory(), new MockUrlWatcher(), config); +  var datastore = new DataStore();    scope.set("$datastore", datastore);    scope.set("$binder", binder);    scope.set("$anchor", binder.anchor); @@ -19,80 +19,79 @@ function compileToHtml(content) {    return compile(content).node.sortedHtml();  } -  BinderTest.prototype.testParseTextWithNoBindings = function(){ -  var parts = nglr.Binder.parseBindings("a"); +  var parts = Binder.parseBindings("a");    assertEquals(parts.length, 1);    assertEquals(parts[0], "a"); -  assertTrue(!nglr.Binder.binding(parts[0])); +  assertTrue(!Binder.binding(parts[0]));  };  BinderTest.prototype.testParseEmptyText = function(){ -  var parts = nglr.Binder.parseBindings(""); +  var parts = Binder.parseBindings("");    assertEquals(parts.length, 1);    assertEquals(parts[0], ""); -  assertTrue(!nglr.Binder.binding(parts[0])); +  assertTrue(!Binder.binding(parts[0]));  };  BinderTest.prototype.testParseInnerBinding = function(){ -  var parts = nglr.Binder.parseBindings("a{{b}}c"); +  var parts = Binder.parseBindings("a{{b}}c");    assertEquals(parts.length, 3);    assertEquals(parts[0], "a"); -  assertTrue(!nglr.Binder.binding(parts[0])); +  assertTrue(!Binder.binding(parts[0]));    assertEquals(parts[1], "{{b}}"); -  assertEquals(nglr.Binder.binding(parts[1]), "b"); +  assertEquals(Binder.binding(parts[1]), "b");    assertEquals(parts[2], "c"); -  assertTrue(!nglr.Binder.binding(parts[2])); +  assertTrue(!Binder.binding(parts[2]));  };  BinderTest.prototype.testParseEndingBinding = function(){ -  var parts = nglr.Binder.parseBindings("a{{b}}"); +  var parts = Binder.parseBindings("a{{b}}");    assertEquals(parts.length, 2);    assertEquals(parts[0], "a"); -  assertTrue(!nglr.Binder.binding(parts[0])); +  assertTrue(!Binder.binding(parts[0]));    assertEquals(parts[1], "{{b}}"); -  assertEquals(nglr.Binder.binding(parts[1]), "b"); +  assertEquals(Binder.binding(parts[1]), "b");  };  BinderTest.prototype.testParseBeggingBinding = function(){ -  var parts = nglr.Binder.parseBindings("{{b}}c"); +  var parts = Binder.parseBindings("{{b}}c");    assertEquals(parts.length, 2);    assertEquals(parts[0], "{{b}}"); -  assertEquals(nglr.Binder.binding(parts[0]), "b"); +  assertEquals(Binder.binding(parts[0]), "b");    assertEquals(parts[1], "c"); -  assertTrue(!nglr.Binder.binding(parts[1])); +  assertTrue(!Binder.binding(parts[1]));  };  BinderTest.prototype.testParseLoanBinding = function(){ -  var parts = nglr.Binder.parseBindings("{{b}}"); +  var parts = Binder.parseBindings("{{b}}");    assertEquals(parts.length, 1);    assertEquals(parts[0], "{{b}}"); -  assertEquals(nglr.Binder.binding(parts[0]), "b"); +  assertEquals(Binder.binding(parts[0]), "b");  };  BinderTest.prototype.testParseTwoBindings = function(){ -  var parts = nglr.Binder.parseBindings("{{b}}{{c}}"); +  var parts = Binder.parseBindings("{{b}}{{c}}");    assertEquals(parts.length, 2);    assertEquals(parts[0], "{{b}}"); -  assertEquals(nglr.Binder.binding(parts[0]), "b"); +  assertEquals(Binder.binding(parts[0]), "b");    assertEquals(parts[1], "{{c}}"); -  assertEquals(nglr.Binder.binding(parts[1]), "c"); +  assertEquals(Binder.binding(parts[1]), "c");  };  BinderTest.prototype.testParseTwoBindingsWithTextInMiddle = function(){ -  var parts = nglr.Binder.parseBindings("{{b}}x{{c}}"); +  var parts = Binder.parseBindings("{{b}}x{{c}}");    assertEquals(parts.length, 3);    assertEquals(parts[0], "{{b}}"); -  assertEquals(nglr.Binder.binding(parts[0]), "b"); +  assertEquals(Binder.binding(parts[0]), "b");    assertEquals(parts[1], "x"); -  assertTrue(!nglr.Binder.binding(parts[1])); +  assertTrue(!Binder.binding(parts[1]));    assertEquals(parts[2], "{{c}}"); -  assertEquals(nglr.Binder.binding(parts[2]), "c"); +  assertEquals(Binder.binding(parts[2]), "c");  };  BinderTest.prototype.testParseMultiline = function(){ -  var parts = nglr.Binder.parseBindings('"X\nY{{A\nB}}C\nD"'); -  assertTrue(!!nglr.Binder.binding('{{A\nB}}')); +  var parts = Binder.parseBindings('"X\nY{{A\nB}}C\nD"'); +  assertTrue(!!Binder.binding('{{A\nB}}'));    assertEquals(parts.length, 3);    assertEquals(parts[0], '"X\nY');    assertEquals(parts[1], '{{A\nB}}'); @@ -100,9 +99,9 @@ BinderTest.prototype.testParseMultiline = function(){  };  BinderTest.prototype.testHasBinding = function(){ -  assertTrue(nglr.Binder.hasBinding("{{a}}")); -  assertTrue(!nglr.Binder.hasBinding("a")); -  assertTrue(nglr.Binder.hasBinding("{{b}}x{{c}}")); +  assertTrue(Binder.hasBinding("{{a}}")); +  assertTrue(!Binder.hasBinding("a")); +  assertTrue(Binder.hasBinding("{{b}}x{{c}}"));  }; @@ -119,9 +118,9 @@ BinderTest.prototype.testChangingTextfieldUpdatesModel = function(){  BinderTest.prototype.testChangingTextareaUpdatesModel = function(){    var form = html('<textarea name="model.note">abc</textarea>'); -  var scope = new nglr.Scope({model:{}}); +  var scope = new Scope({model:{}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals(scope.get('model').note, 'abc'); @@ -130,9 +129,9 @@ BinderTest.prototype.testChangingTextareaUpdatesModel = function(){  BinderTest.prototype.testChangingRadioUpdatesModel = function(){    var form = html('<input type="radio" name="model.price" value="A" checked>' +          '<input type="radio" name="model.price" value="B">'); -  var scope = new nglr.Scope({model:{}}); +  var scope = new Scope({model:{}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals(scope.get('model').price, 'A'); @@ -140,9 +139,9 @@ BinderTest.prototype.testChangingRadioUpdatesModel = function(){  BinderTest.prototype.testChangingCheckboxUpdatesModel = function(){    var form = html('<input type="checkbox" name="model.price" value="A" checked>'); -  var scope = new nglr.Scope({model:{}}); +  var scope = new Scope({model:{}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals('A', scope.get('model').price); @@ -156,9 +155,9 @@ BinderTest.prototype.testBindUpdate = function() {  BinderTest.prototype.testChangingSelectNonSelectedUpdatesModel = function(){    var form = html('<select name="model.price"><option value="A">A</option><option value="B">B</option></select>'); -  var scope = new nglr.Scope({model:{}}); +  var scope = new Scope({model:{}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals('A', scope.get('model').price); @@ -170,9 +169,9 @@ BinderTest.prototype.testChangingMultiselectUpdatesModel = function(){            '<option value="B" selected>Extra padding</option>' +            '<option value="C">Expedite</option>' +            '</select>'); -  var scope = new nglr.Scope({Invoice:{}}); +  var scope = new Scope({Invoice:{}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher());    binder.compile();    binder.updateView();    assertJsonEquals(["A", "B"], scope.get('Invoice').options); @@ -180,9 +179,9 @@ BinderTest.prototype.testChangingMultiselectUpdatesModel = function(){  BinderTest.prototype.testChangingSelectSelectedUpdatesModel = function(){    var form = html('<select name="model.price"><option>A</option><option selected value="b">B</option></select>'); -  var scope = new nglr.Scope({model:{}}); +  var scope = new Scope({model:{}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals(scope.get('model').price, 'b'); @@ -190,18 +189,18 @@ BinderTest.prototype.testChangingSelectSelectedUpdatesModel = function(){  BinderTest.prototype.testExecuteInitialization = function() {    var form = html('<div ng-init="a=123">'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0)); +  var binder = new Binder(form.get(0));    binder.executeInit();    assertEquals(scope.get('a'), 123);  };  BinderTest.prototype.testExecuteInitializationStatements = function() {    var form = html('<div ng-init="a=123;b=345">'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0)); +  var binder = new Binder(form.get(0));    binder.executeInit();    assertEquals(scope.get('a'), 123);    assertEquals(scope.get('b'), 345); @@ -209,9 +208,9 @@ BinderTest.prototype.testExecuteInitializationStatements = function() {  BinderTest.prototype.testApplyTextBindings = function(){    var form = html('<div ng-bind="model.a">x</div>'); -  var scope = new nglr.Scope({model:{a:123}}); +  var scope = new Scope({model:{a:123}});    form.data('scope', scope); -  var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher()); +  var binder = new Binder(form.get(0), null, new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals('123', form.text()); @@ -224,15 +223,15 @@ BinderTest.prototype.testReplaceBindingInTextWithSpan = function() {  BinderTest.prototype.testReplaceBindingCreatesCorrectNumberOfWidgets = function() {    var h = html("space{{a}}<b>{{a}}a{{a}}</b>{{a}}"); -  h.data('scope', new nglr.Scope()); -  var binder = new nglr.Binder(h.get(0), new nglr.WidgetFactory()); +  h.data('scope', new Scope()); +  var binder = new Binder(h.get(0), new WidgetFactory());    binder.compile();    assertEquals(4, h.scope().widgets.length);  };  BinderTest.prototype.testBindingSpaceConfusesIE = function() { -  if (!nglr.msie) return; +  if (!msie) return;    var span = document.createElement("span");    span.innerHTML = ' ';    var nbsp = span.firstChild.nodeValue; @@ -246,30 +245,30 @@ BinderTest.prototype.testBindingSpaceConfusesIE = function() {  BinderTest.prototype.testBindingOfAttributes = function() {    var form = html("<a href='http://s/a{{b}}c' foo='x'></a>"); -  form.data('scope', new nglr.Scope()); -  var binder = new nglr.Binder(form.get(0)); +  form.data('scope', new Scope()); +  var binder = new Binder(form.get(0));    binder.compile();    var attrbinding = form.find("a").attr("ng-bind-attr"); -  var bindings = nglr.fromJson(attrbinding); +  var bindings = fromJson(attrbinding);    assertEquals("http://s/a{{b}}c", decodeURI(bindings.href));    assertTrue(!bindings.foo);  };  BinderTest.prototype.testMarkMultipleAttributes = function() {    var form = html("<a href='http://s/a{{b}}c' foo='{{d}}'></a>"); -  form.data('scope', new nglr.Scope()); -  var binder = new nglr.Binder(form.get(0)); +  form.data('scope', new Scope()); +  var binder = new Binder(form.get(0));    binder.compile();    var attrbinding = form.find("a").attr("ng-bind-attr"); -  var bindings = nglr.fromJson(attrbinding); +  var bindings = fromJson(attrbinding);    assertEquals(decodeURI(bindings.href), "http://s/a{{b}}c");    assertEquals(bindings.foo, "{{d}}");  };  BinderTest.prototype.testAttributesNoneBound = function() {    var form = html("<a href='abc' foo='def'></a>"); -  form.data('scope', new nglr.Scope()); -  var binder = new nglr.Binder(form.get(0)); +  form.data('scope', new Scope()); +  var binder = new Binder(form.get(0));    binder.compile();    var a = form.find("a");    assertEquals(a.get(0).nodeName, "A"); @@ -278,8 +277,8 @@ BinderTest.prototype.testAttributesNoneBound = function() {  BinderTest.prototype.testExistingAttrbindingIsAppended = function() {    var form = html("<a href='http://s/{{abc}}' ng-bind-attr='{\"b\":\"{{def}}\"}'></a>"); -  form.data('scope', new nglr.Scope()); -  var binder = new nglr.Binder(form.get(0)); +  form.data('scope', new Scope()); +  var binder = new Binder(form.get(0));    binder.compile();    var a = form.find("a");    assertEquals('{"b":"{{def}}","href":"http://s/{{abc}}"}', a.attr('ng-bind-attr')); @@ -287,8 +286,8 @@ BinderTest.prototype.testExistingAttrbindingIsAppended = function() {  BinderTest.prototype.testAttributesAreEvaluated = function(){    var form = html('<a ng-bind-attr=\'{"a":"a", "b":"a+b={{a+b}}"}\'></a>'); -  form.data('scope', new nglr.Scope({a:1, b:2})); -  var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher()); +  form.data('scope', new Scope({a:1, b:2})); +  var binder = new Binder(form.get(0), null, new MockUrlWatcher());    binder.compile();    binder.updateView();    var a = form.find("a"); @@ -305,8 +304,8 @@ BinderTest.prototype.testInputsAreUpdated = function(){            '<input name="A.checkbox" type="checkbox" value="c" />' +            '<input name="A.checkboxOff" type="checkbox" value="c" />' +            '<select name="A.select"><option>a</option><option value="S">b</option></select>'); -  var binder = new nglr.Binder(form.get(0), new nglr.WidgetFactory(), new MockUrlWatcher()); -  form.data('scope', new nglr.Scope({A:{text:"t1", textarea:"t2", radio:"r", checkbox:"c", select:"S"}})); +  var binder = new Binder(form.get(0), new WidgetFactory(), new MockUrlWatcher()); +  form.data('scope', new Scope({A:{text:"t1", textarea:"t2", radio:"r", checkbox:"c", select:"S"}}));    binder.compile();    binder.updateView();    assertEquals(form.find("input[type=text]").attr('value'), 't1'); @@ -349,7 +348,7 @@ BinderTest.prototype.testButtonElementActionExecutesInScope =  function(){  };  BinderTest.prototype.testParseEmptyAnchor = function(){ -  var binder = new nglr.Binder(null, null, new MockUrlWatcher()); +  var binder = new Binder(null, null, new MockUrlWatcher());    var anchor = binder.anchor;    binder.parseAnchor("a#x=1");    assertEquals(1, binder.anchor.x); @@ -360,7 +359,7 @@ BinderTest.prototype.testParseEmptyAnchor = function(){  };  BinderTest.prototype.testParseAnchor = function(){ -  var binder = new nglr.Binder(null, null, new MockUrlWatcher()); +  var binder = new Binder(null, null, new MockUrlWatcher());    binder.parseAnchor("a#x=1");    assertEquals(binder.anchor.x, "1");    binder.parseAnchor("a#a=b&c=%20&d"); @@ -371,7 +370,7 @@ BinderTest.prototype.testParseAnchor = function(){  };  BinderTest.prototype.testWriteAnchor = function(){ -  var binder = new nglr.Binder(null, null, new MockUrlWatcher()); +  var binder = new Binder(null, null, new MockUrlWatcher());    binder.urlWatcher.setUrl('a');    binder.anchor.a = 'b';    binder.anchor.c = ' '; @@ -381,9 +380,9 @@ BinderTest.prototype.testWriteAnchor = function(){  };  BinderTest.prototype.testWriteAnchorAsPartOfTheUpdateView = function(){ -  var binder = new nglr.Binder(html("<div/>")[0], null, new MockUrlWatcher()); +  var binder = new Binder(html("<div/>")[0], null, new MockUrlWatcher());    binder.urlWatcher.setUrl('a'); -  $(binder.doc).data('scope', new nglr.Scope()); +  $(binder.doc).data('scope', new Scope());    binder.anchor.a = 'b';    binder.updateView();    assertEquals(binder.urlWatcher.getUrl(), "a#a=b"); @@ -391,9 +390,9 @@ BinderTest.prototype.testWriteAnchorAsPartOfTheUpdateView = function(){  BinderTest.prototype.testRepeaterUpdateBindings = function(){    var form = html('<ul><LI ng-repeat="item in model.items" ng-bind="item.a"/></ul>'); -  var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher()); +  var binder = new Binder(form.get(0), null, new MockUrlWatcher());    var items = [{a:"A"}, {a:"B"}]; -  form.data('scope', new nglr.Scope({model:{items:items}})); +  form.data('scope', new Scope({model:{items:items}}));    binder.compile();    binder.updateView(); @@ -423,8 +422,8 @@ BinderTest.prototype.testRepeaterUpdateBindings = function(){  BinderTest.prototype.testRepeaterContentDoesNotBind = function(){    var form = html('<ul><LI ng-repeat="item in model.items"><span ng-bind="item.a"/></li></ul>'); -  form.data('scope', new nglr.Scope({model:{items:[{a:"A"}]}})); -  var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher()); +  form.data('scope', new Scope({model:{items:[{a:"A"}]}})); +  var binder = new Binder(form.get(0), null, new MockUrlWatcher());    binder.compile();    binder.updateView();    assertEquals('<ul>' + @@ -450,9 +449,9 @@ BinderTest.prototype.testRepeaterInputContentDoesNotBind =  function(){    var form =      html('<ul><LI repeater="item in model.items">' +            '<input type="text" name="item.a" value="OLD"/></li></ul>'); -  var binder = new nglr.Binder(form.get(0), null, new MockUrlWatcher()); +  var binder = new Binder(form.get(0), null, new MockUrlWatcher());    var items = [{a:"A"}]; -  form.data('scope', new nglr.Scope({model:{items:items}})); +  form.data('scope', new Scope({model:{items:items}}));    assertEquals(form.find(":input").attr("value"), "OLD");  }; @@ -492,9 +491,9 @@ BinderTest.prototype.testDoNotOverwriteCustomAction = function(){  BinderTest.prototype.testReplaceFileUploadWithSwf = function(){    expectAsserts(1);    var form = jQuery("body").append('<div id="testTag"><input type="file"></div>'); -  form.data('scope', new nglr.Scope()); +  form.data('scope', new Scope());    var factory = {}; -  var binder = new nglr.Binder(form.get(0), factory, new MockUrlWatcher()); +  var binder = new Binder(form.get(0), factory, new MockUrlWatcher());    factory.createController = function(node){      assertEquals(node.attr('type'), 'file');      return {updateModel:function(){}}; @@ -505,8 +504,8 @@ BinderTest.prototype.testReplaceFileUploadWithSwf = function(){  BinderTest.prototype.testRepeaterAdd = function(){    var doc = $('<div><input type="text" name="item.x" ng-repeat="item in items"></div>'); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); -  doc.data('scope', new nglr.Scope({items:[{x:'a'}, {x:'b'}], $binder:binder})); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher()); +  doc.data('scope', new Scope({items:[{x:'a'}, {x:'b'}], $binder:binder}));    binder.compile();    binder.updateView();    assertEquals('a', doc.find(':input')[0].value); @@ -520,16 +519,16 @@ BinderTest.prototype.testRepeaterAdd = function(){  BinderTest.prototype.testIfTextBindingThrowsErrorDecorateTheSpan = function(){    var doc = $('<div>{{error.throw()}}</div>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('error.throw', function(){throw "ErrorMsg1";});    binder.updateView();    var span = doc.find('span');    assertTrue(span.hasClass('ng-exception')); -  assertEquals('ErrorMsg1', nglr.fromJson(span.text())); +  assertEquals('ErrorMsg1', fromJson(span.text()));    assertEquals('"ErrorMsg1"', span.attr('ng-error'));    scope.set('error.throw', function(){throw "MyError";}); @@ -548,9 +547,9 @@ BinderTest.prototype.testIfTextBindingThrowsErrorDecorateTheSpan = function(){  BinderTest.prototype.testIfAttrBindingThrowsErrorDecorateTheSpan = function(){    var doc = $('<div attr="before {{error.throw()}} after"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('error.throw', function(){throw "ErrorMsg";}); @@ -570,9 +569,9 @@ BinderTest.prototype.testNestedRepeater = function() {    var doc = html('<div ng-repeat="m in model" name="{{m.name}}">' +                     '<ul name="{{i}}" ng-repeat="i in m.item"></ul>' +                   '</div>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('model', [{name:'a', item:['a1', 'a2']}, {name:'b', item:['b1', 'b2']}]); @@ -594,9 +593,9 @@ BinderTest.prototype.testNestedRepeater = function() {  BinderTest.prototype.testRadioButtonGetsPrefixed = function () {    var doc = html('<input ng-repeat="m in model" type="radio" name="m.a" value="on"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('model', ['a1', 'a2']); @@ -611,9 +610,9 @@ BinderTest.prototype.testRadioButtonGetsPrefixed = function () {  BinderTest.prototype.testHideBindingExpression = function() {    var doc = html('<div ng-hide="hidden == 3"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('hidden', 3); @@ -629,9 +628,9 @@ BinderTest.prototype.testHideBindingExpression = function() {  BinderTest.prototype.testHideBinding = function() {    var doc = html('<div ng-hide="hidden"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('hidden', 'true'); @@ -652,9 +651,9 @@ BinderTest.prototype.testHideBinding = function() {  BinderTest.prototype.testShowBinding = function() {    var doc = html('<div ng-show="show"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('show', 'true'); @@ -684,9 +683,9 @@ BinderTest.prototype.testBindClassUndefined = function() {  BinderTest.prototype.testBindClass = function() {    var doc = html('<div ng-class="class"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.set('class', 'testClass'); @@ -713,9 +712,9 @@ BinderTest.prototype.testBindClassEvenOdd = function() {  BinderTest.prototype.testBindStyle = function() {    var doc = html('<div ng-style="style"/>'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    doc.data('scope', scope); -  var binder = new nglr.Binder(doc[0], new nglr.WidgetFactory(), new MockUrlWatcher()); +  var binder = new Binder(doc[0], new WidgetFactory(), new MockUrlWatcher());    binder.compile();    scope.eval('style={color:"red"}'); @@ -734,7 +733,7 @@ BinderTest.prototype.testActionOnAHrefThrowsError = function(){    var state = compile('<a ng-action="throw {a:\'abc\', b:2};">Add Phone</a>', model);    var input = state.node.find('a');    input.click(); -  assertEquals('abc', nglr.fromJson(input.attr('ng-error')).a); +  assertEquals('abc', fromJson(input.attr('ng-error')).a);    assertNotNull(input.data('qtip'));    assertTrue("should have an error class", input.hasClass('ng-exception')); @@ -890,7 +889,7 @@ BinderTest.prototype.testItShouldCallListenersWhenAnchorChanges = function() {  };  BinderTest.prototype.testParseQueryString = function(){ -  var binder = new nglr.Binder(); +  var binder = new Binder();    assertJsonEquals({"a":"1"}, binder.parseQueryString("a=1"));    assertJsonEquals({"a":"1", "b":"two"}, binder.parseQueryString("a=1&b=two"));    assertJsonEquals({}, binder.parseQueryString("")); @@ -905,8 +904,8 @@ BinderTest.prototype.testParseQueryString = function(){  BinderTest.prototype.testSetBinderAnchorTriggersListeners = function(){    expectAsserts(2);    var doc = html("<div/>")[0]; -  var binder = new nglr.Binder(doc, null, new MockUrlWatcher()); -  var scope = new nglr.Scope({$binder:binder, $anchor:binder.anchor}); +  var binder = new Binder(doc, null, new MockUrlWatcher()); +  var scope = new Scope({$binder:binder, $anchor:binder.anchor});    jQuery(doc).data('scope', scope);    scope.addWatchListener("$anchor.name", function(newVal, oldVal) { diff --git a/test/ConsoleTest.js b/test/ConsoleTest.js index 56e223bd..f659752f 100644 --- a/test/ConsoleTest.js +++ b/test/ConsoleTest.js @@ -1,13 +1,12 @@  ConsoleTest = TestCase('ConsoleTest');  ConsoleTest.prototype.testConsoleWrite = function(){ -  var consoleNode = $("<div></div>")[0]; -  nglr.consoleNode = consoleNode; -  nglr.consoleLog("error", ["Hello", "world"]); +  consoleNode = $("<div></div>")[0]; +  consoleLog("error", ["Hello", "world"]);    assertEquals($(consoleNode)[0].nodeName, 'DIV');    assertEquals($(consoleNode).text(), 'Hello world');    assertEquals($('div', consoleNode)[0].className, 'error'); -  nglr.consoleLog("error",["Bye"]); +  consoleLog("error",["Bye"]);    assertEquals($(consoleNode).text(), 'Hello worldBye'); -  nglr.consoleNode = null; +  consoleNode = null;  };
\ No newline at end of file diff --git a/test/DataStoreTest.js b/test/DataStoreTest.js index 9fe6c3df..2dd4a582 100644 --- a/test/DataStoreTest.js +++ b/test/DataStoreTest.js @@ -11,14 +11,14 @@ DataStoreTest.prototype.testSavePostsToServer = function(){      assertEquals("123", posted.$id);      assertEquals("1", posted.$version);      assertFalse('function' == typeof posted.save); -    response = nglr.fromJson(nglr.toJson(posted)); +    response = fromJson(toJson(posted));      response.$entity = "abc";      response.$id = "123";      response.$version = "2";      callback(200, [response]);    };    var model; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    model = datastore.entity('abc', {name: "value"})();    model.$id = "123";    model.$version = "1"; @@ -44,7 +44,7 @@ DataStoreTest.prototype.testLoadGetsFromServer = function(){        response = [{$entity:'abc', $id:'1', $version:'2', key:"value"}];        callback(200, response);      }; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    var model = datastore.entity("abc", {merge:true})();    assertEquals(datastore.load(model, '1', function(obj){ @@ -72,14 +72,14 @@ DataStoreTest.prototype.testRemove = function(){      assertEquals("123", posted.$id);      assertEquals("1", posted.$version);      assertFalse('function' == typeof posted.save); -    response = nglr.fromJson(nglr.toJson(posted)); +    response = fromJson(toJson(posted));      response.$entity = "abc";      response.$id = "123";      response.$version = "2";      callback(200, [response]);    };    var model; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    model = datastore.entity('abc', {name: "value"})();    model.$id = "123";    model.$version = "1"; @@ -101,7 +101,7 @@ DataStoreTest.prototype.test401ResponseDoesNotCallCallback = function(){      callback(200, {$status_code: 401});    }; -  var datastore = new nglr.DataStore(post, {login:function(){ +  var datastore = new DataStore(post, {login:function(){      assertTrue(true);    }}); @@ -119,7 +119,7 @@ DataStoreTest.prototype.test403ResponseDoesNotCallCallback = function(){      callback(200, [{$status_code: 403}]);    }; -  var datastore = new nglr.DataStore(post, {notAuthorized:function(){ +  var datastore = new DataStore(post, {notAuthorized:function(){      assertTrue(true);    }}); @@ -136,14 +136,14 @@ DataStoreTest.prototype.testLoadCalledWithoutIdShouldBeNoop = function(){    var post = function(url, callback){      assertTrue(false);    }; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    var model = datastore.entity("abc")();    assertEquals(datastore.load(model, undefined), model);    assertEquals(model.$entity, "abc");  };  DataStoreTest.prototype.testEntityFactory = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var Recipe = ds.entity("Recipe", {a:1, b:2});    assertEquals(Recipe.title, "Recipe");    assertEquals(Recipe.defaults.a, 1); @@ -161,7 +161,7 @@ DataStoreTest.prototype.testEntityFactory = function(){  };  DataStoreTest.prototype.testEntityFactoryNoDefaults = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var Recipe = ds.entity("Recipe");    assertEquals(Recipe.title, "Recipe"); @@ -170,7 +170,7 @@ DataStoreTest.prototype.testEntityFactoryNoDefaults = function(){  };  DataStoreTest.prototype.testEntityFactoryWithInitialValues = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var Recipe = ds.entity("Recipe");    var recipe = Recipe({name: "name"}); @@ -178,7 +178,7 @@ DataStoreTest.prototype.testEntityFactoryWithInitialValues = function(){  };  DataStoreTest.prototype.testEntityLoad = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var Recipe = ds.entity("Recipe", {a:1, b:2});    ds.load = function(instance, id, callback){      callback.apply(instance); @@ -192,7 +192,7 @@ DataStoreTest.prototype.testEntityLoad = function(){  };  DataStoreTest.prototype.testSaveScope = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var log = "";    var Person = ds.entity("Person");    var person1 = Person({name:"A", $entity:"Person", $id:"1", $version:"1"}, ds); @@ -215,7 +215,7 @@ DataStoreTest.prototype.testSaveScope = function(){  };  DataStoreTest.prototype.testEntityLoadAllRows = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var Recipe = ds.entity("Recipe");    var list = [];    ds.loadAll = function(entity, callback){ @@ -236,7 +236,7 @@ DataStoreTest.prototype.testLoadAll = function(){      assertEquals("A", data[0][1]);      callback(200, [[{$entity:'A', $id:'1'},{$entity:'A', $id:'2'}]]);    }; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    var list = datastore.entity("A").all(function(){      assertTrue(true);    }); @@ -256,7 +256,7 @@ DataStoreTest.prototype.testQuery = function(){      callback(200, [[{$entity:"Employee", $id: "456", managerId: "123ABC"}]]);    }; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    var Employee = datastore.entity("Employee");    var list = Employee.query('managerId', "123abc", function(){      assertTrue(true); @@ -269,7 +269,7 @@ DataStoreTest.prototype.testQuery = function(){  DataStoreTest.prototype.testLoadingDocumentRefreshesExistingArrays = function() {    expectAsserts(12);    var post; -  var datastore = new nglr.DataStore(function(r, c){post(r,c);}); +  var datastore = new DataStore(function(r, c){post(r,c);});    var Book = datastore.entity('Book');    post = function(req, callback) {      callback(200, [[{$id:1, $entity:"Book", name:"Moby"}, @@ -285,7 +285,7 @@ DataStoreTest.prototype.testLoadingDocumentRefreshesExistingArrays = function()    assertEquals("Dick", queryBooks[1].name);    post = function(req, callback) { -    assertEquals('[["GET","Book/1"]]', nglr.toJson(req)); +    assertEquals('[["GET","Book/1"]]', toJson(req));      callback(200, [{$id:1, $entity:"Book", name:"Moby Dick"}]);    };    var book = Book.load(1); @@ -307,7 +307,7 @@ DataStoreTest.prototype.testLoadingDocumentRefreshesExistingArrays = function()  DataStoreTest.prototype.testEntityProperties = function() {    expectAsserts(2); -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var callback = {};    datastore._jsonRequest = function(request, callbackFn) { @@ -322,11 +322,11 @@ DataStoreTest.prototype.testEntityProperties = function() {  DataStoreTest.prototype.testLoadInstanceIsNotFromCache = function() {    var post; -  var datastore = new nglr.DataStore(function(r, c){post(r,c);}); +  var datastore = new DataStore(function(r, c){post(r,c);});    var Book = datastore.entity('Book');    post = function(req, callback) { -    assertEquals('[["GET","Book/1"]]', nglr.toJson(req)); +    assertEquals('[["GET","Book/1"]]', toJson(req));      callback(200, [{$id:1, $entity:"Book", name:"Moby Dick"}]);    };    var book = Book.load(1); @@ -336,14 +336,14 @@ DataStoreTest.prototype.testLoadInstanceIsNotFromCache = function() {  };  DataStoreTest.prototype.testLoadStarsIsNewDocument = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Book = datastore.entity('Book');    var book = Book.load('*');    assertEquals('Book', book.$entity);  };  DataStoreTest.prototype.testUndefinedEntityReturnsNullValueObject = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Entity = datastore.entity(undefined);    var all = Entity.all();    assertEquals(0, all.length); @@ -355,7 +355,7 @@ DataStoreTest.prototype.testFetchEntities = function(){      assertJsonEquals(["GET", "$entities"], data[0]);      callback(200, [{A:0, B:0}]);    }; -  var datastore = new nglr.DataStore(post); +  var datastore = new DataStore(post);    var entities = datastore.entities(function(){      assertTrue(true);    }); @@ -367,20 +367,20 @@ DataStoreTest.prototype.testFetchEntities = function(){  };  DataStoreTest.prototype.testItShouldMigrateSchema = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Entity = datastore.entity("Entity", {a:[], user:{name:"Misko", email:""}});    var doc = Entity().$loadFrom({b:'abc', user:{email:"misko@hevery.com"}});    assertFalse( -      nglr.toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}) == -      nglr.toJson(doc)); +      toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}) == +      toJson(doc));    doc.$migrate();    assertEquals( -      nglr.toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}), -      nglr.toJson(doc)); +      toJson({a:[], b:'abc', user:{name:"Misko", email:"misko@hevery.com"}}), +      toJson(doc));  };  DataStoreTest.prototype.testItShouldCollectRequestsForBulk = function() { -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var Book = ds.entity("Book");    var Library = ds.entity("Library");    Book.all(); @@ -391,7 +391,7 @@ DataStoreTest.prototype.testItShouldCollectRequestsForBulk = function() {  };  DataStoreTest.prototype.testEmptyFlushShouldDoNothing = function () { -  var ds = new nglr.DataStore(function(){ +  var ds = new DataStore(function(){      fail("expecting noop");    });    ds.flush(); @@ -400,17 +400,17 @@ DataStoreTest.prototype.testEmptyFlushShouldDoNothing = function () {  DataStoreTest.prototype.testFlushShouldCallAllCallbacks = function() {    var log = "";    function post(request, callback){ -    log += 'BulkRequest:' + nglr.toJson(request) + ';'; +    log += 'BulkRequest:' + toJson(request) + ';';      callback(200, [[{$id:'ABC'}], {$id:'XYZ'}]);    } -  var ds = new nglr.DataStore(post); +  var ds = new DataStore(post);    var Book = ds.entity("Book");    var Library = ds.entity("Library");    Book.all(function(instance){ -    log += nglr.toJson(instance) + ';'; +    log += toJson(instance) + ';';    });    Library.load("123", function(instance){ -    log += nglr.toJson(instance) + ';'; +    log += toJson(instance) + ';';    });    assertEquals("", log);    ds.flush(); @@ -421,7 +421,7 @@ DataStoreTest.prototype.testFlushShouldCallAllCallbacks = function() {  DataStoreTest.prototype.testSaveOnNotLoggedInRetriesAfterLoggin = function(){    var log = "";    var book; -  var ds = new nglr.DataStore(null, {login:function(c){c();}}); +  var ds = new DataStore(null, {login:function(c){c();}});    ds.post = function (request, callback){      assertJsonEquals([["POST", "", book]], request);      ds.post = function(request, callback){ @@ -439,7 +439,7 @@ DataStoreTest.prototype.testSaveOnNotLoggedInRetriesAfterLoggin = function(){  DataStoreTest.prototype.testItShouldRemoveItemFromCollectionWhenDeleted = function() {    expectAsserts(6); -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    ds.post = function(request, callback){      assertJsonEquals([["GET", "Book"]], request);      callback(200, [[{name:"Moby Dick", $id:123, $entity:'Book'}]]); @@ -462,7 +462,7 @@ DataStoreTest.prototype.testItShouldRemoveItemFromCollectionWhenDeleted = functi  DataStoreTest.prototype.testItShouldAddToAll = function() {    expectAsserts(8); -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    ds.post = function(request, callback){      assertJsonEquals([["GET", "Book"]], request);      callback(200, [[]]); @@ -490,7 +490,7 @@ DataStoreTest.prototype.testItShouldAddToAll = function() {  DataStoreTest.prototype.testItShouldReturnCreatedDocumentCountByUser = function(){    expectAsserts(2); -  var datastore = new nglr.DataStore( +  var datastore = new DataStore(        function(request, callback){          assertJsonEquals([["GET", "$users"]], request);          callback(200, [{misko:1, adam:1}]); @@ -502,7 +502,7 @@ DataStoreTest.prototype.testItShouldReturnCreatedDocumentCountByUser = function(  DataStoreTest.prototype.testItShouldReturnDocumentIdsForUeserByEntity = function(){    expectAsserts(2); -  var datastore = new nglr.DataStore( +  var datastore = new DataStore(        function(request, callback){          assertJsonEquals([["GET", "$users/misko@hevery.com"]], request);          callback(200, [{Book:["1"], Library:["2"]}]); @@ -514,7 +514,7 @@ DataStoreTest.prototype.testItShouldReturnDocumentIdsForUeserByEntity = function  DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){    expectAsserts(7);    var log = ""; -  var datastore = new nglr.DataStore( +  var datastore = new DataStore(        function(request, callback){          assertJsonEquals([["GET", "User/misko"]], request);          callback(200, [{$status_code:404}]); @@ -532,13 +532,13 @@ DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){  DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){    var log = ""; -  var datastore = new nglr.DataStore( +  var datastore = new DataStore(        function(request, callback){          assertJsonEquals([["GET", "User/misko"],["GET", "User/adam"]], request);          callback(200, [{$id:'misko'},{$id:'adam'}]);        });    var User = datastore.entity("User"); -  var users = User.loadMany(['misko', 'adam'], function(i){log+="cb "+nglr.toJson(i)+";";}); +  var users = User.loadMany(['misko', 'adam'], function(i){log+="cb "+toJson(i)+";";});    datastore.flush();    assertEquals("misko", users[0].$id);    assertEquals("adam", users[1].$id); @@ -546,7 +546,7 @@ DataStoreTest.prototype.testItShouldReturnNewInstanceOn404 = function(){  };  DataStoreTest.prototype.testItShouldCreateJoinAndQuery = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Invoice = datastore.entity("Invoice");    var Customer = datastore.entity("Customer");    var InvoiceWithCustomer = datastore.join({ @@ -568,7 +568,7 @@ DataStoreTest.prototype.testItShouldCreateJoinAndQuery = function() {  };  DataStoreTest.prototype.testItShouldThrowIfMoreThanOneEntityIsPrimary = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Invoice = datastore.entity("Invoice");    var Customer = datastore.entity("Customer");    assertThrows("Exactly one entity needs to be primary.", function(){ @@ -580,7 +580,7 @@ DataStoreTest.prototype.testItShouldThrowIfMoreThanOneEntityIsPrimary = function  };  DataStoreTest.prototype.testItShouldThrowIfLoopInReferences = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Invoice = datastore.entity("Invoice");    var Customer = datastore.entity("Customer");    assertThrows("Infinite loop in join: invoice -> customer", function(){ @@ -592,7 +592,7 @@ DataStoreTest.prototype.testItShouldThrowIfLoopInReferences = function() {  };  DataStoreTest.prototype.testItShouldThrowIfReferenceToNonExistantJoin = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Invoice = datastore.entity("Invoice");    var Customer = datastore.entity("Customer");    assertThrows("Named entity 'x' is undefined.", function(){ @@ -604,7 +604,7 @@ DataStoreTest.prototype.testItShouldThrowIfReferenceToNonExistantJoin = function  };  DataStoreTest.prototype.testItShouldThrowIfQueryOnNonPrimary = function() { -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var Invoice = datastore.entity("Invoice");    var Customer = datastore.entity("Customer");    var InvoiceWithCustomer = datastore.join({ diff --git a/test/EntityDeclarationTest.js b/test/EntityDeclarationTest.js index 5cab90f4..d64dd775 100644 --- a/test/EntityDeclarationTest.js +++ b/test/EntityDeclarationTest.js @@ -2,7 +2,7 @@ EntityDeclarationTest = TestCase('EntityDeclarationTest');  EntityDeclarationTest.prototype.testEntityTypeOnly = function(){    expectAsserts(2); -  var scope = new nglr.Scope({$datastore:{entity:function(name){ +  var scope = new Scope({$datastore:{entity:function(name){      assertEquals("Person", name);    }}});    var init = scope.entity("Person"); @@ -11,7 +11,7 @@ EntityDeclarationTest.prototype.testEntityTypeOnly = function(){  EntityDeclarationTest.prototype.testWithDefaults = function(){    expectAsserts(4); -  var scope = new nglr.Scope({$datastore:{entity:function(name, init){ +  var scope = new Scope({$datastore:{entity:function(name, init){      assertEquals("Person", name);      assertEquals("=a:", init.a);      assertEquals(0, init.b.length); @@ -22,7 +22,7 @@ EntityDeclarationTest.prototype.testWithDefaults = function(){  EntityDeclarationTest.prototype.testWithName = function(){    expectAsserts(2); -  var scope = new nglr.Scope({$datastore:{entity:function(name, init){ +  var scope = new Scope({$datastore:{entity:function(name, init){      assertEquals("Person", name);      return function (){ return {}; };    }}}); @@ -34,7 +34,7 @@ EntityDeclarationTest.prototype.testMultipleEntities = function(){    expectAsserts(3);    var expect = ['Person', 'Book'];    var i=0; -  var scope = new nglr.Scope({$datastore:{entity:function(name, init){ +  var scope = new Scope({$datastore:{entity:function(name, init){      assertEquals(expect[i], name);      i++;      return function (){ return {}; }; diff --git a/test/FileControllerTest.js b/test/FileControllerTest.js index ca5925e4..09eb6fc5 100644 --- a/test/FileControllerTest.js +++ b/test/FileControllerTest.js @@ -3,7 +3,7 @@ FileControllerTest = TestCase('FileControllerTest');  FileControllerTest.prototype.testOnSelectUpdateView = function(){    var view = jQuery('<span><a/><span/></span>');    var swf = {}; -  var controller = new nglr.FileController(view, null, swf); +  var controller = new FileController(view, null, swf);    swf.uploadFile = function(path){};    controller._on_select('A', 9, '9 bytes');    assertEquals(view.find('a').text(), "A"); @@ -11,14 +11,14 @@ FileControllerTest.prototype.testOnSelectUpdateView = function(){  };  FileControllerTest.prototype.testUpdateModelView = function(){ -  var view = nglr.FileController.template(''); +  var view = FileController.template('');    var input = $('<input name="value.input">');    var controller; -  var scope = new nglr.Scope({value:{}, $binder:{updateView:function(){ +  var scope = new Scope({value:{}, $binder:{updateView:function(){        controller.updateView(scope);      }}});    view.data('scope', scope); -  controller = new nglr.FileController(view, 'value.input', null, "http://server_base"); +  controller = new FileController(view, 'value.input', null, "http://server_base");    var value = '{"text":"A", "size":123, "id":"890"}';    controller._on_uploadCompleteData(value);    controller.updateView(scope); @@ -34,7 +34,7 @@ FileControllerTest.prototype.testUpdateModelView = function(){  FileControllerTest.prototype.testFileUpload = function(){    expectAsserts(1);    var swf = {}; -  var controller = new nglr.FileController(null, null, swf, "http://server_base"); +  var controller = new FileController(null, null, swf, "http://server_base");    swf.uploadFile = function(path){      assertEquals("http://server_base/_attachments", path);    }; @@ -47,16 +47,16 @@ FileControllerTest.prototype.testFileUploadNoFileIsNoop = function(){    var swf = {uploadFile:function(path){      fail();    }}; -  var controller = new nglr.FileController(null, swf); +  var controller = new FileController(null, swf);    controller.upload("basePath", null);  };  FileControllerTest.prototype.testRemoveAttachment = function(){ -  var doc = nglr.FileController.template(); +  var doc = FileController.template();    var input = $('<input name="file">'); -  var scope = new nglr.Scope(); +  var scope = new Scope();    input.data('scope', scope); -  var controller = new nglr.FileController(doc, 'file', null, null); +  var controller = new FileController(doc, 'file', null, null);    controller.updateView(scope);    assertEquals(false, doc.find('input').attr('checked')); @@ -75,10 +75,10 @@ FileControllerTest.prototype.testRemoveAttachment = function(){  };  FileControllerTest.prototype.testShouldEmptyOutOnUndefined = function () { -  var view = nglr.FileController.template('hello'); -  var controller = new nglr.FileController(view, 'abc', null, null); +  var view = FileController.template('hello'); +  var controller = new FileController(view, 'abc', null, null); -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('abc', {text: 'myname', url: 'myurl', size: 1234});    controller.updateView(scope); diff --git a/test/FiltersTest.js b/test/FiltersTest.js index 8943fdd4..c219f24f 100644 --- a/test/FiltersTest.js +++ b/test/FiltersTest.js @@ -3,7 +3,7 @@ FiltersTest = TestCase('FiltersTest');  FiltersTest.prototype.testCurrency = function(){    var html = $('<span/>');    var context = {element:html[0]}; -  var currency = nglr.bind(context, angular.filter.currency); +  var currency = bind(context, angular.filter.currency);    assertEquals(currency(0), '$0.00');    assertEquals(html.hasClass('ng-format-negative'), false); @@ -15,8 +15,8 @@ FiltersTest.prototype.testCurrency = function(){  FiltersTest.prototype.testFilterThisIsContext = function(){    expectAsserts(2); -  var scope = new nglr.Scope(); -  nglr.Scope.expressionCache = {}; +  var scope = new Scope(); +  Scope.expressionCache = {};    var context = {element:123};    angular.filter.testFn = function () {      assertEquals('Context not equal', this, context); @@ -28,7 +28,7 @@ FiltersTest.prototype.testFilterThisIsContext = function(){  FiltersTest.prototype.testNumberFormat = function(){    var context = {jqElement:$('<span/>')}; -  var number = nglr.bind(context, angular.filter.number); +  var number = bind(context, angular.filter.number);    assertEquals('0', number(0, 0));    assertEquals('0.00', number(0)); @@ -40,7 +40,7 @@ FiltersTest.prototype.testNumberFormat = function(){  };  FiltersTest.prototype.testJson = function () { -  assertEquals(nglr.toJson({a:"b"}, true), angular.filter.json({a:"b"})); +  assertEquals(toJson({a:"b"}, true), angular.filter.json({a:"b"}));  };  FiltersTest.prototype.testPackageTracking = function () { @@ -48,9 +48,9 @@ FiltersTest.prototype.testPackageTracking = function () {      var val = angular.filter.trackPackage(trackingNo, title);      assertNotNull("Did Not Match: " + trackingNo, val);      assertEquals(angular.filter.Meta.TAG, val.TAG); -    assertEquals(title + ": " + nglr.trim(trackingNo), val.text); +    assertEquals(title + ": " + trim(trackingNo), val.text);      assertNotNull(val.url); -    assertEquals(nglr.trim(trackingNo), val.trackingNo); +    assertEquals(trim(trackingNo), val.trackingNo);      assertEquals('<a href="' + val.url + '">' + val.text + '</a>', val.html);    };    assert('UPS', ' 1Z 999 999 99 9999 999 9 '); @@ -83,7 +83,7 @@ FiltersTest.prototype.testLink = function() {  };  FiltersTest.prototype.testBytes = function(){ -  var controller = new nglr.FileController(); +  var controller = new FileController();    assertEquals(angular.filter.bytes(123), '123 bytes');    assertEquals(angular.filter.bytes(1234), '1.2 KB');    assertEquals(angular.filter.bytes(1234567), '1.1 MB'); diff --git a/test/JsonTest.js b/test/JsonTest.js index 5c3644f5..cf49bec3 100644 --- a/test/JsonTest.js +++ b/test/JsonTest.js @@ -1,69 +1,69 @@  JsonTest = TestCase("JsonTest");  JsonTest.prototype.testPrimitives = function () { -  assertEquals("null", nglr.toJson(0/0)); -  assertEquals("null", nglr.toJson(null)); -  assertEquals("true", nglr.toJson(true)); -  assertEquals("false", nglr.toJson(false)); -  assertEquals("123.45", nglr.toJson(123.45)); -  assertEquals('"abc"', nglr.toJson("abc")); -  assertEquals('"a \\t \\n \\r b \\\\"', nglr.toJson("a \t \n \r b \\")); +  assertEquals("null", toJson(0/0)); +  assertEquals("null", toJson(null)); +  assertEquals("true", toJson(true)); +  assertEquals("false", toJson(false)); +  assertEquals("123.45", toJson(123.45)); +  assertEquals('"abc"', toJson("abc")); +  assertEquals('"a \\t \\n \\r b \\\\"', toJson("a \t \n \r b \\"));  };  JsonTest.prototype.testEscaping = function () { -  assertEquals("\"7\\\\\\\"7\"", nglr.toJson("7\\\"7")); +  assertEquals("\"7\\\\\\\"7\"", toJson("7\\\"7"));  };  JsonTest.prototype.testObjects = function () { -  assertEquals('{"a":1,"b":2}', nglr.toJson({a:1,b:2})); -  assertEquals('{"a":{"b":2}}', nglr.toJson({a:{b:2}})); -  assertEquals('{"a":{"b":{"c":0}}}', nglr.toJson({a:{b:{c:0}}})); -  assertEquals('{"a":{"b":null}}', nglr.toJson({a:{b:0/0}})); +  assertEquals('{"a":1,"b":2}', toJson({a:1,b:2})); +  assertEquals('{"a":{"b":2}}', toJson({a:{b:2}})); +  assertEquals('{"a":{"b":{"c":0}}}', toJson({a:{b:{c:0}}})); +  assertEquals('{"a":{"b":null}}', toJson({a:{b:0/0}}));  };  JsonTest.prototype.testObjectPretty = function () { -  assertEquals('{\n  "a":1,\n  "b":2}', nglr.toJson({a:1,b:2}, true)); -  assertEquals('{\n  "a":{\n    "b":2}}', nglr.toJson({a:{b:2}}, true)); +  assertEquals('{\n  "a":1,\n  "b":2}', toJson({a:1,b:2}, true)); +  assertEquals('{\n  "a":{\n    "b":2}}', toJson({a:{b:2}}, true));  };  JsonTest.prototype.testArray = function () { -  assertEquals('[]', nglr.toJson([])); -  assertEquals('[1,"b"]', nglr.toJson([1,"b"])); +  assertEquals('[]', toJson([])); +  assertEquals('[1,"b"]', toJson([1,"b"]));  };  JsonTest.prototype.testIgnoreFunctions = function () { -  assertEquals('[null,1]', nglr.toJson([function(){},1])); -  assertEquals('{}', nglr.toJson({a:function(){}})); +  assertEquals('[null,1]', toJson([function(){},1])); +  assertEquals('{}', toJson({a:function(){}}));  };  JsonTest.prototype.testParseNull = function () { -  assertNull(nglr.fromJson("null")); +  assertNull(fromJson("null"));  };  JsonTest.prototype.testParseBoolean = function () { -  assertTrue(nglr.fromJson("true")); -  assertFalse(nglr.fromJson("false")); +  assertTrue(fromJson("true")); +  assertFalse(fromJson("false"));  };  JsonTest.prototype.test$$isIgnored = function () { -  assertEquals("{}", nglr.toJson({$$:0})); +  assertEquals("{}", toJson({$$:0}));  };  JsonTest.prototype.testArrayWithEmptyItems = function () {    var a = [];    a[1] = "X"; -  assertEquals('[null,"X"]', nglr.toJson(a)); +  assertEquals('[null,"X"]', toJson(a));  };  JsonTest.prototype.testItShouldEscapeUnicode = function () {    assertEquals(1, "\u00a0".length); -  assertEquals(8, nglr.toJson("\u00a0").length); -  assertEquals(1, nglr.fromJson(nglr.toJson("\u00a0")).length); +  assertEquals(8, toJson("\u00a0").length); +  assertEquals(1, fromJson(toJson("\u00a0")).length);  };  JsonTest.prototype.testItShouldUTCDates = function() {    var date = angular.String.toDate("2009-10-09T01:02:03Z"); -  assertEquals('"2009-10-09T01:02:03Z"', nglr.toJson(date));   +  assertEquals('"2009-10-09T01:02:03Z"', toJson(date));      assertEquals(date.getTime(),  -      nglr.fromJson('"2009-10-09T01:02:03Z"').getTime());   +      fromJson('"2009-10-09T01:02:03Z"').getTime());    }; diff --git a/test/LoaderTest.js b/test/LoaderTest.js index 91a804a5..88ae3efa 100644 --- a/test/LoaderTest.js +++ b/test/LoaderTest.js @@ -3,7 +3,7 @@ LoaderTest = TestCase('LoaderTest');  LoaderTest.prototype.testLoadCss = function(){    if ($.browser.safari) return;    var head = jQuery('<head/>')[0]; -  var loader = new nglr.Loader(document, head, {}); +  var loader = new Loader(document, head, {});    var log = '';    loader.config.server = 'http://';    loader.loadCss('x'); @@ -11,15 +11,15 @@ LoaderTest.prototype.testLoadCss = function(){  };  LoaderTest.prototype.testDefaultDatabasePathFromSubdomain = function() { -  var loader = new nglr.Loader(null, null, {server:"http://account.getangular.com", database:"database"}); +  var loader = new Loader(null, null, {server:"http://account.getangular.com", database:"database"});    loader.computeConfiguration();    assertEquals("database", loader.config.database); -  loader = new nglr.Loader(null, null, {server:"http://account.getangular.com"}); +  loader = new Loader(null, null, {server:"http://account.getangular.com"});    loader.computeConfiguration();    assertEquals("account", loader.config.database); -  loader = new nglr.Loader(null, null, {server:"https://account.getangular.com"}); +  loader = new Loader(null, null, {server:"https://account.getangular.com"});    loader.computeConfiguration();    assertEquals("account", loader.config.database);  }; @@ -31,7 +31,7 @@ UrlWatcherTest = TestCase('UrlWatcherTest');  UrlWatcherTest.prototype.testUrlWatcher = function () {    expectAsserts(2);    var location = {href:"http://server", hash:""}; -  var watcher = new nglr.UrlWatcher(location); +  var watcher = new UrlWatcher(location);    watcher.delay = 1;    watcher.listener = function(url){      assertEquals('http://getangular.test', url); @@ -49,9 +49,9 @@ UrlWatcherTest.prototype.testUrlWatcher = function () {  UrlWatcherTest.prototype.testItShouldFireOnUpdateEventWhenSpecialURLSet = function(){    expectAsserts(2);    var location = {href:"http://server", hash:"#$iframe_notify=1234"}; -  var watcher = new nglr.UrlWatcher(location); -  nglr._iframe_notify_1234 = function () { -    assertEquals("undefined", typeof nglr._iframe_notify_1234); +  var watcher = new UrlWatcher(location); +  callbacks._iframe_notify_1234 = function () { +    assertEquals("undefined", typeof callbacks._iframe_notify_1234);      assertEquals("http://server2#", location.href);    };    watcher.delay = 1; @@ -66,5 +66,5 @@ UrlWatcherTest.prototype.testItShouldFireOnUpdateEventWhenSpecialURLSet = functi  FunctionTest = TestCase("FunctionTest");  FunctionTest.prototype.testEscapeHtml = function () { -  assertEquals("<div>&amp;</div>", nglr.escapeHtml('<div>&</div>')); +  assertEquals("<div>&amp;</div>", escapeHtml('<div>&</div>'));  };
\ No newline at end of file diff --git a/test/ModelTest.js b/test/ModelTest.js index 5d9119a1..dbd97778 100644 --- a/test/ModelTest.js +++ b/test/ModelTest.js @@ -1,7 +1,7 @@  ModelTest = TestCase('ModelTest');  ModelTest.prototype.testLoadSaveOperations = function(){ -  var m1 = new nglr.DataStore().entity('A')(); +  var m1 = new DataStore().entity('A')();    m1.a = 1;    var m2 =  {b:1}; @@ -13,7 +13,7 @@ ModelTest.prototype.testLoadSaveOperations = function(){  };  ModelTest.prototype.testLoadfromDoesNotClobberFunctions = function(){ -  var m1 = new nglr.DataStore().entity('A')(); +  var m1 = new DataStore().entity('A')();    m1.id = function(){return 'OK';};    m1.$loadFrom({id:null});    assertEquals(m1.id(), 'OK'); @@ -24,7 +24,7 @@ ModelTest.prototype.testLoadfromDoesNotClobberFunctions = function(){  };  ModelTest.prototype.testDataStoreDoesNotGetClobbered = function(){ -  var ds = new nglr.DataStore(); +  var ds = new DataStore();    var m = ds.entity('A')();    assertTrue(m.$$entity.datastore === ds);    m.$loadFrom({}); @@ -33,7 +33,7 @@ ModelTest.prototype.testDataStoreDoesNotGetClobbered = function(){  ModelTest.prototype.testManagedModelDelegatesMethodsToDataStore = function(){    expectAsserts(7); -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var model = datastore.entity("A", {a:1})();    var fn = {};    datastore.save = function(instance, callback) { @@ -56,7 +56,7 @@ ModelTest.prototype.testManagedModelDelegatesMethodsToDataStore = function(){  ModelTest.prototype.testManagedModelCanBeForcedToFlush = function(){    expectAsserts(6); -  var datastore = new nglr.DataStore(); +  var datastore = new DataStore();    var model = datastore.entity("A", {a:1})();    datastore.save = function(instance, callback) { @@ -77,7 +77,7 @@ ModelTest.prototype.testManagedModelCanBeForcedToFlush = function(){  ModelTest.prototype.testItShouldMakeDeepCopyOfInitialValues = function (){    var initial = {a:[]}; -  var entity = new nglr.DataStore().entity("A", initial); +  var entity = new DataStore().entity("A", initial);    var model = entity();    model.a.push(1);    assertEquals(0, entity().a.length); diff --git a/test/ParserTest.js b/test/ParserTest.js index 7fe8e6a4..058010f3 100644 --- a/test/ParserTest.js +++ b/test/ParserTest.js @@ -1,7 +1,7 @@  LexerTest = TestCase('LexerTest');  LexerTest.prototype.testTokenizeAString = function(){ -  var lexer = new nglr.Lexer("a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\""); +  var lexer = new Lexer("a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\"");    var tokens = lexer.parse();    var i = 0;    assertEquals(tokens[i].index, 0); @@ -54,7 +54,7 @@ LexerTest.prototype.testTokenizeAString = function(){  LexerTest.prototype.testTokenizeRegExp = function(){ -  var lexer = new nglr.Lexer("/r 1/"); +  var lexer = new Lexer("/r 1/");    var tokens = lexer.parse();    var i = 0;    assertEquals(tokens[i].index, 0); @@ -64,7 +64,7 @@ LexerTest.prototype.testTokenizeRegExp = function(){  LexerTest.prototype.testQuotedString = function(){    var str = "['\\'', \"\\\"\"]"; -  var lexer = new nglr.Lexer(str); +  var lexer = new Lexer(str);    var tokens = lexer.parse();    assertEquals(1, tokens[1].index); @@ -77,21 +77,21 @@ LexerTest.prototype.testQuotedString = function(){  LexerTest.prototype.testQuotedStringEscape = function(){    var str = '"\\"\\n\\f\\r\\t\\v\\u00A0"'; -  var lexer = new nglr.Lexer(str); +  var lexer = new Lexer(str);    var tokens = lexer.parse();    assertEquals('"\n\f\r\t\v\u00A0', tokens[0].text);  };  LexerTest.prototype.testTokenizeUnicode = function(){ -  var lexer = new nglr.Lexer('"\\u00A0"'); +  var lexer = new Lexer('"\\u00A0"');    var tokens = lexer.parse();    assertEquals(1, tokens.length);    assertEquals('\u00a0', tokens[0].text);  };  LexerTest.prototype.testTokenizeRegExpWithOptions = function(){ -  var lexer = new nglr.Lexer("/r/g"); +  var lexer = new Lexer("/r/g");    var tokens = lexer.parse();    var i = 0;    assertEquals(tokens[i].index, 0); @@ -101,7 +101,7 @@ LexerTest.prototype.testTokenizeRegExpWithOptions = function(){  };  LexerTest.prototype.testTokenizeRegExpWithEscape = function(){ -  var lexer = new nglr.Lexer("/\\/\\d/"); +  var lexer = new Lexer("/\\/\\d/");    var tokens = lexer.parse();    var i = 0;    assertEquals(tokens[i].index, 0); @@ -110,14 +110,14 @@ LexerTest.prototype.testTokenizeRegExpWithEscape = function(){  };  LexerTest.prototype.testIgnoreWhitespace = function(){ -  var lexer = new nglr.Lexer("a \t \n \r b"); +  var lexer = new Lexer("a \t \n \r b");    var tokens = lexer.parse();    assertEquals(tokens[0].text, 'a');    assertEquals(tokens[1].text, 'b');  };  LexerTest.prototype.testRelation = function(){ -  var lexer = new nglr.Lexer("! == != < > <= >="); +  var lexer = new Lexer("! == != < > <= >=");    var tokens = lexer.parse();    assertEquals(tokens[0].text, '!');    assertEquals(tokens[1].text, '=='); @@ -129,7 +129,7 @@ LexerTest.prototype.testRelation = function(){  };  LexerTest.prototype.testStatements = function(){ -  var lexer = new nglr.Lexer("a;b;"); +  var lexer = new Lexer("a;b;");    var tokens = lexer.parse();    assertEquals(tokens[0].text, 'a');    assertEquals(tokens[1].text, ';'); @@ -140,7 +140,7 @@ LexerTest.prototype.testStatements = function(){  ParserTest = TestCase('ParserTest');  ParserTest.prototype.testExpressions = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("-1"), -1);    assertEquals(scope.eval("1 + 2.5"), 3.5);    assertEquals(scope.eval("1 + -2.5"), -1.5); @@ -151,7 +151,7 @@ ParserTest.prototype.testExpressions = function(){  };  ParserTest.prototype.testComparison = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("false"), false);    assertEquals(scope.eval("!true"), false);    assertEquals(scope.eval("1==1"), true); @@ -163,14 +163,14 @@ ParserTest.prototype.testComparison = function(){  };  ParserTest.prototype.testLogical = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("0&&2"), 0&&2);    assertEquals(scope.eval("0||2"), 0||2);    assertEquals(scope.eval("0||1&&2"), 0||1&&2);  };  ParserTest.prototype.testString = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("'a' + 'b c'"), "ab c");  }; @@ -182,7 +182,7 @@ ParserTest.prototype.testFilters = function(){    angular.filter.upper = {_case:function(input) {      return input.toUpperCase();    }}; -  var scope = new nglr.Scope(); +  var scope = new Scope();    try {      scope.eval("1|nonExistant");      fail(); @@ -196,7 +196,7 @@ ParserTest.prototype.testFilters = function(){  };  ParserTest.prototype.testScopeAccess = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('a', 123);    scope.set('b.c', 456);    assertEquals(scope.eval("a", scope), 123); @@ -205,16 +205,16 @@ ParserTest.prototype.testScopeAccess = function(){  };  ParserTest.prototype.testGrouping = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("(1+2)*3"), (1+2)*3);  };  ParserTest.prototype.testAssignments = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("a=12"), 12);    assertEquals(scope.get("a"), 12); -  scope = new nglr.Scope(); +  scope = new Scope();    assertEquals(scope.eval("x.y.z=123;"), 123);    assertEquals(scope.get("x.y.z"), 123); @@ -224,13 +224,13 @@ ParserTest.prototype.testAssignments = function(){  };  ParserTest.prototype.testFunctionCallsNoArgs = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('const', function(a,b){return 123;});    assertEquals(scope.eval("const()"), 123);  };  ParserTest.prototype.testFunctionCalls = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('add', function(a,b){      return a+b;    }); @@ -238,7 +238,7 @@ ParserTest.prototype.testFunctionCalls = function(){  };  ParserTest.prototype.testCalculationBug = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('taxRate', 8);    scope.set('subTotal', 100);    assertEquals(scope.eval("taxRate / 100 * subTotal"), 8); @@ -246,7 +246,7 @@ ParserTest.prototype.testCalculationBug = function(){  };  ParserTest.prototype.testArray = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("[]").length, 0);    assertEquals(scope.eval("[1, 2]").length, 2);    assertEquals(scope.eval("[1, 2]")[0], 1); @@ -254,7 +254,7 @@ ParserTest.prototype.testArray = function(){  };  ParserTest.prototype.testArrayAccess = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("[1][0]"), 1);    assertEquals(scope.eval("[[1]][0][0]"), 1);    assertEquals(scope.eval("[].length"), 0); @@ -262,33 +262,33 @@ ParserTest.prototype.testArrayAccess = function(){  };  ParserTest.prototype.testObject = function(){ -  var scope = new nglr.Scope(); -  assertEquals(nglr.toJson(scope.eval("{}")), "{}"); -  assertEquals(nglr.toJson(scope.eval("{a:'b'}")), '{"a":"b"}'); -  assertEquals(nglr.toJson(scope.eval("{'a':'b'}")), '{"a":"b"}'); -  assertEquals(nglr.toJson(scope.eval("{\"a\":'b'}")), '{"a":"b"}'); +  var scope = new Scope(); +  assertEquals(toJson(scope.eval("{}")), "{}"); +  assertEquals(toJson(scope.eval("{a:'b'}")), '{"a":"b"}'); +  assertEquals(toJson(scope.eval("{'a':'b'}")), '{"a":"b"}'); +  assertEquals(toJson(scope.eval("{\"a\":'b'}")), '{"a":"b"}');  };  ParserTest.prototype.testObjectAccess = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals("WC", scope.eval("{false:'WC', true:'CC'}[false]"));  };  ParserTest.prototype.testJSON = function(){ -  var scope = new nglr.Scope(); -  assertEquals(nglr.toJson(scope.eval("[{}]")), "[{}]"); -  assertEquals(nglr.toJson(scope.eval("[{a:[]}, {b:1}]")), '[{"a":[]},{"b":1}]'); +  var scope = new Scope(); +  assertEquals(toJson(scope.eval("[{}]")), "[{}]"); +  assertEquals(toJson(scope.eval("[{a:[]}, {b:1}]")), '[{"a":[]},{"b":1}]');  };  ParserTest.prototype.testMultippleStatements = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(scope.eval("a=1;b=3;a+b"), 4);    assertEquals(scope.eval(";;1;;"), 1);  };  ParserTest.prototype.testParseThrow = function(){    expectAsserts(1); -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('e', 'abc');    try {      scope.eval("throw e"); @@ -298,7 +298,7 @@ ParserTest.prototype.testParseThrow = function(){  };  ParserTest.prototype.testMethodsGetDispatchedWithCorrectThis = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    var C = function (){      this.a=123;    }; @@ -310,7 +310,7 @@ ParserTest.prototype.testMethodsGetDispatchedWithCorrectThis = function(){    assertEquals(123, scope.eval("obj.getA()"));  };  ParserTest.prototype.testMethodsArgumentsGetCorrectThis = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    var C = function (){      this.a=123;    }; @@ -326,13 +326,13 @@ ParserTest.prototype.testMethodsArgumentsGetCorrectThis = function(){  };  ParserTest.prototype.testObjectPointsToScopeValue = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('a', "abc");    assertEquals("abc", scope.eval("{a:a}").a);  };  ParserTest.prototype.testFieldAccess = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    var fn = function(){        return {name:'misko'};      }; @@ -341,14 +341,14 @@ ParserTest.prototype.testFieldAccess = function(){  };  ParserTest.prototype.testArrayIndexBug = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('items', [{}, {name:'misko'}]);    assertEquals("misko", scope.eval('items[1].name'));  };  ParserTest.prototype.testArrayAssignment = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('items', []);    assertEquals("abc", scope.eval('items[1] = "abc"')); @@ -359,30 +359,30 @@ ParserTest.prototype.testArrayAssignment = function () {  };  ParserTest.prototype.testFiltersCanBeGrouped = function () { -  var scope = new nglr.Scope({name:'MISKO'}); +  var scope = new Scope({name:'MISKO'});    assertEquals('misko', scope.eval('n = (name|lowercase)'));    assertEquals('misko', scope.eval('n'));  };  ParserTest.prototype.testFiltersCanBeGrouped = function () { -  var scope = new nglr.Scope({name:'MISKO'}); +  var scope = new Scope({name:'MISKO'});    assertEquals('misko', scope.eval('n = (name|lowercase)'));    assertEquals('misko', scope.eval('n'));  };  ParserTest.prototype.testRemainder = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(1, scope.eval('1%2'));  };  ParserTest.prototype.testSumOfUndefinedIsNotUndefined = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(1, scope.eval('1+undefined'));    assertEquals(1, scope.eval('undefined+1'));  };  ParserTest.prototype.testMissingThrowsError = function() { -  var scope = new nglr.Scope(); +  var scope = new Scope();    try {      scope.eval('[].count(');      fail(); @@ -392,7 +392,7 @@ ParserTest.prototype.testMissingThrowsError = function() {  };  ParserTest.prototype.testItShouldParseOnChangeIntoHashSet = function () { -  var scope = new nglr.Scope({count:0}); +  var scope = new Scope({count:0});    scope.watch("$anchor.a:count=count+1;$anchor.a:count=count+20;b:count=count+300");    scope.watchListeners["$anchor.a"].listeners[0](); @@ -403,7 +403,7 @@ ParserTest.prototype.testItShouldParseOnChangeIntoHashSet = function () {    assertEquals(321, scope.get("count"));  };  ParserTest.prototype.testItShouldParseOnChangeBlockIntoHashSet = function () { -  var scope = new nglr.Scope({count:0}); +  var scope = new Scope({count:0});    var listeners = {a:[], b:[]};    scope.watch("a:{count=count+1;count=count+20;};b:count=count+300",         function(n, fn){listeners[n].push(fn);}); @@ -417,12 +417,12 @@ ParserTest.prototype.testItShouldParseOnChangeBlockIntoHashSet = function () {  };  ParserTest.prototype.testItShouldParseEmptyOnChangeAsNoop = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.watch("", function(){fail();});  };  ParserTest.prototype.testItShouldCreateClosureFunctionWithNoArguments = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    var fn = scope.eval("{:value}");    scope.set("value", 1);    assertEquals(1, fn()); @@ -433,7 +433,7 @@ ParserTest.prototype.testItShouldCreateClosureFunctionWithNoArguments = function  };  ParserTest.prototype.testItShouldCreateClosureFunctionWithArguments = function () { -  var scope = new nglr.Scope(); +  var scope = new Scope();    var fn = scope.eval("{(a):value+a}");    scope.set("value", 1);    assertEquals(11, fn(10)); @@ -444,14 +444,14 @@ ParserTest.prototype.testItShouldCreateClosureFunctionWithArguments = function (  };  ParserTest.prototype.testItShouldHaveDefaultArugument = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    var fn = scope.eval("{:$*2}");    assertEquals(4, fn(2));  };  ParserTest.prototype.testReturnFunctionsAreNotBound = function(){ -  var scope = new nglr.Scope(); -  scope.set("$datastore", new nglr.DataStore()); +  var scope = new Scope(); +  scope.set("$datastore", new DataStore());    scope.entity("Group");    var Group = scope.get("Group");    assertEquals("eval Group", "function", typeof scope.eval("Group")); diff --git a/test/ScopeTest.js b/test/ScopeTest.js index c66a2329..e1c5c8ce 100644 --- a/test/ScopeTest.js +++ b/test/ScopeTest.js @@ -23,13 +23,13 @@ ScopeTest.prototype.testNoScopeDoesNotCauseInfiniteRecursion = function(){  };  ScopeTest.prototype.testScopeEval = function(){ -  var scope = new nglr.Scope({b:345}); +  var scope = new Scope({b:345});    assertEquals(scope.eval('b = 123'), 123);    assertEquals(scope.get('b'), 123);  };  ScopeTest.prototype.testScopeFromPrototype = function(){ -  var scope = new nglr.Scope({b:123}); +  var scope = new Scope({b:123});    scope.eval('a = b');    scope.eval('b = 456');    assertEquals(scope.get('a'), 123); @@ -37,32 +37,32 @@ ScopeTest.prototype.testScopeFromPrototype = function(){  };  ScopeTest.prototype.testSetScopeGet = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('a', 987);    assertEquals(scope.get('a'), 987);    assertEquals(scope.eval('a'), 987);  };  ScopeTest.prototype.testGetChain = function(){ -  var scope = new nglr.Scope({a:{b:987}}); +  var scope = new Scope({a:{b:987}});    assertEquals(scope.get('a.b'), 987);    assertEquals(scope.eval('a.b'), 987);  };  ScopeTest.prototype.testGetUndefinedChain = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    assertEquals(typeof scope.get('a.b'),  'undefined');  };  ScopeTest.prototype.testSetChain = function(){ -  var scope = new nglr.Scope({a:{}}); +  var scope = new Scope({a:{}});    scope.set('a.b', 987);    assertEquals(scope.get('a.b'), 987);    assertEquals(scope.eval('a.b'), 987);  };  ScopeTest.prototype.testSetGetOnChain = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('a.b', 987);    assertEquals(scope.get('a.b'), 987);    assertEquals(scope.eval('a.b'), 987); @@ -70,7 +70,7 @@ ScopeTest.prototype.testSetGetOnChain = function(){  ScopeTest.prototype.testGlobalFunctionAccess =function(){    window['scopeAddTest'] = function (a, b) {return a+b;}; -  var scope = new nglr.Scope({window:window}); +  var scope = new Scope({window:window});    assertEquals(scope.eval('window.scopeAddTest(1,2)'), 3);    scope.set('add', function (a, b) {return a+b;}); @@ -82,7 +82,7 @@ ScopeTest.prototype.testGlobalFunctionAccess =function(){  ScopeTest.prototype.testValidationEval = function(){    expectAsserts(4); -  var scope = new nglr.Scope(); +  var scope = new Scope();    angular.validator.testValidator = function(value, expect){      assertEquals(scope, this.scope);      return value == expect ? null : "Error text"; @@ -96,7 +96,7 @@ ScopeTest.prototype.testValidationEval = function(){  ScopeTest.prototype.testCallingNonExistantMethodShouldProduceFriendlyException = function() {    expectAsserts(1); -  var scope = new nglr.Scope({obj:{}}); +  var scope = new Scope({obj:{}});    try {      scope.eval("obj.iDontExist()");      fail(); @@ -106,7 +106,7 @@ ScopeTest.prototype.testCallingNonExistantMethodShouldProduceFriendlyException =  };  ScopeTest.prototype.testAccessingWithInvalidPathShouldThrowError = function() { -  var scope = new nglr.Scope(); +  var scope = new Scope();    try {      scope.get('a.{{b}}');      fail(); @@ -116,25 +116,25 @@ ScopeTest.prototype.testAccessingWithInvalidPathShouldThrowError = function() {  };  ScopeTest.prototype.testItShouldHave$parent = function() { -  var parent = new nglr.Scope({}, "ROOT"); -  var child = new nglr.Scope(parent.state); +  var parent = new Scope({}, "ROOT"); +  var child = new Scope(parent.state);    assertSame("parent", child.state.$parent, parent.state);    assertSame("root", child.state.$root, parent.state);  };  ScopeTest.prototype.testItShouldHave$root = function() { -  var scope = new nglr.Scope({}, "ROOT"); +  var scope = new Scope({}, "ROOT");    assertSame(scope.state.$root, scope.state);  };  ScopeTest.prototype.testItShouldBuildPathOnUndefined = function(){ -  var scope = new nglr.Scope({}, "ROOT"); +  var scope = new Scope({}, "ROOT");    scope.setEval("a.$b.c", 1);    assertJsonEquals({$b:{c:1}}, scope.get("a"));  };  ScopeTest.prototype.testItShouldMapUnderscoreFunctions = function(){ -  var scope = new nglr.Scope({}, "ROOT"); +  var scope = new Scope({}, "ROOT");    scope.set("a", [1,2,3]);    assertEquals('function', typeof scope.get("a.$size"));    scope.eval("a.$includeIf(4,true)"); diff --git a/test/ServerTest.js b/test/ServerTest.js index d1f662f9..e367c90a 100644 --- a/test/ServerTest.js +++ b/test/ServerTest.js @@ -1,7 +1,7 @@  ServerTest = TestCase("ServerTest");  ServerTest.prototype.testBreakLargeRequestIntoPackets = function() {    var log = ""; -  var server = new nglr.Server("http://server", function(url){ +  var server = new Server("http://server", function(url){      log += "|" + url;    });    server.maxSize = 30; @@ -10,7 +10,7 @@ ServerTest.prototype.testBreakLargeRequestIntoPackets = function() {      assertEquals(200, code);      assertEquals("response", r);    }); -  nglr.uuid0("response"); +  callbacks.uuid0("response");    assertEquals(        "|http://server/$/uuid0/2/1?h=eyJtIjoiUE9TVCIsInAiOnt9LCJ1Ij" +        "|http://server/$/uuid0/2/2?h=oiL2RhdGEvZGF0YWJhc2UifQ==", @@ -18,7 +18,7 @@ ServerTest.prototype.testBreakLargeRequestIntoPackets = function() {  };  ServerTest.prototype.testItShouldEncodeUsingUrlRules = function() { -  var server = new nglr.Server("http://server"); +  var server = new Server("http://server");    assertEquals("fn5-fn5-", server.base64url("~~~~~~"));    assertEquals("fn5_fn5_", server.base64url("~~\u007f~~\u007f"));  }; @@ -28,13 +28,13 @@ FrameServerTest = TestCase("FrameServerTest");  FrameServerTest.prototype = {    testRead:function(){      var window = {name:'$DATASET:"MyData"'}; -    var server = new nglr.FrameServer(window); +    var server = new FrameServer(window);      server.read();      assertEquals("MyData", server.data);    },    testWrite:function(){      var window = {}; -    var server = new nglr.FrameServer(window); +    var server = new FrameServer(window);      server.data = "TestData"      server.write();      assertEquals('$DATASET:"TestData"', window.name); diff --git a/test/UsersTest.js b/test/UsersTest.js index c808885c..f0ff545a 100644 --- a/test/UsersTest.js +++ b/test/UsersTest.js @@ -10,10 +10,10 @@ UsersTest.prototype = {    testItShouldFetchCurrentUser:function(){      expectAsserts(5);      var user; -    var users = new nglr.Users({request:function(method, url, request, callback){ +    var users = new Users({request:function(method, url, request, callback){        assertEquals("GET", method);        assertEquals("/account.json", url); -      assertEquals("{}", nglr.toJson(request)); +      assertEquals("{}", toJson(request));        callback(200, {$status_code:200, user:{name:'misko'}});      }});      users.fetchCurrentUser(function(u){ diff --git a/test/WidgetsTest.js b/test/WidgetsTest.js index a245abda..fe20e664 100644 --- a/test/WidgetsTest.js +++ b/test/WidgetsTest.js @@ -2,8 +2,8 @@ WidgetTest = TestCase('WidgetTest');  WidgetTest.prototype.testRequired = function () {    var view = $('<input name="a" ng-required>'); -  var scope = new nglr.Scope({$invalidWidgets:[]}); -  var cntl = new nglr.TextController(view[0], 'a'); +  var scope = new Scope({$invalidWidgets:[]}); +  var cntl = new TextController(view[0], 'a');    cntl.updateView(scope);    assertTrue(view.hasClass('ng-validation-error'));    assertEquals("Required Value", view.attr('ng-error')); @@ -15,8 +15,8 @@ WidgetTest.prototype.testRequired = function () {  WidgetTest.prototype.testValidator = function () {    var view = $('<input name="a" ng-validate="testValidator:\'ABC\'">'); -  var scope = new nglr.Scope({$invalidWidgets:[]}); -  var cntl = new nglr.TextController(view[0], 'a'); +  var scope = new Scope({$invalidWidgets:[]}); +  var cntl = new TextController(view[0], 'a');    angular.validator.testValidator = function(value, expect){      return value == expect ? null : "Error text";    }; @@ -43,8 +43,8 @@ WidgetTest.prototype.testValidator = function () {  WidgetTest.prototype.testRequiredValidator = function () {    var view = $('<input name="a" ng-required ng-validate="testValidator:\'ABC\'">'); -  var scope = new nglr.Scope({$invalidWidgets:[]}); -  var cntl = new nglr.TextController(view[0], 'a'); +  var scope = new Scope({$invalidWidgets:[]}); +  var cntl = new TextController(view[0], 'a');    angular.validator.testValidator = function(value, expect){      return value == expect ? null : "Error text";    }; @@ -67,29 +67,29 @@ WidgetTest.prototype.testRequiredValidator = function () {    delete angular.validator['testValidator'];  }; -TextController = TestCase("TextController"); +TextControllerTest = TestCase("TextControllerTest"); -TextController.prototype.testDatePicker = function() { +TextControllerTest.prototype.testDatePicker = function() {    var input = $('<input type="text" ng-widget="datepicker">'); -  input.data('scope', new nglr.Scope()); +  input.data('scope', new Scope());    var body = $(document.body);    body.append(input); -  var binder = new nglr.Binder(input[0], new nglr.WidgetFactory()); +  var binder = new Binder(input[0], new WidgetFactory());    assertTrue('before', input.data('datepicker') === undefined);    binder.compile();    assertTrue('after', input.data('datepicker') !== null);    assertTrue(body.html(), input.hasClass('hasDatepicker'));  }; -RepeaterUpdater = TestCase("RepeaterUpdater"); +RepeaterUpdaterTest = TestCase("RepeaterUpdaterTest"); -RepeaterUpdater.prototype.testRemoveThenAdd = function() { +RepeaterUpdaterTest.prototype.testRemoveThenAdd = function() {    var view = $("<div><span/></div>");    var template = function () {      return $("<li/>");    }; -  var repeater = new nglr.RepeaterUpdater(view.find("span"), "a in b", template, ""); -  var scope = new nglr.Scope(); +  var repeater = new RepeaterUpdater(view.find("span"), "a in b", template, ""); +  var scope = new Scope();    scope.set('b', [1,2]);    repeater.updateView(scope); @@ -102,14 +102,14 @@ RepeaterUpdater.prototype.testRemoveThenAdd = function() {    assertEquals(1, view.find("li").size());  }; -RepeaterUpdater.prototype.testShouldBindWidgetOnRepeaterClone = function(){ +RepeaterUpdaterTest.prototype.testShouldBindWidgetOnRepeaterClone = function(){    //fail();  }; -RepeaterUpdater.prototype.testShouldThrowInformativeSyntaxError= function(){ +RepeaterUpdaterTest.prototype.testShouldThrowInformativeSyntaxError= function(){    expectAsserts(1);    try { -    var repeater = new nglr.RepeaterUpdater(null, "a=b"); +    var repeater = new RepeaterUpdater(null, "a=b");    } catch (e) {      assertEquals("Expected ng-repeat in form of 'item in collection' but got 'a=b'.", e);    } @@ -118,17 +118,17 @@ RepeaterUpdater.prototype.testShouldThrowInformativeSyntaxError= function(){  SelectControllerTest = TestCase("SelectControllerTest");  SelectControllerTest.prototype.testShouldUpdateModelNullOnNothingSelected = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    var view = {selectedIndex:-1, options:[]}; -  var cntl = new nglr.SelectController(view, 'abc'); +  var cntl = new SelectController(view, 'abc');    cntl.updateModel(scope);    assertNull(scope.get('abc'));  };  SelectControllerTest.prototype.testShouldUpdateModelWhenNothingSelected = function(){ -  var scope = new nglr.Scope(); +  var scope = new Scope();    var view = {value:'123'}; -  var cntl = new nglr.SelectController(view, 'abc'); +  var cntl = new SelectController(view, 'abc');    cntl.updateView(scope);    assertEquals("123", scope.get('abc'));  }; @@ -137,8 +137,8 @@ BindUpdaterTest = TestCase("BindUpdaterTest");  BindUpdaterTest.prototype.testShouldDisplayNothingForUndefined = function () {    var view = $('<span />'); -  var controller = new nglr.BindUpdater(view[0], "{{a}}"); -  var scope = new nglr.Scope(); +  var controller = new BindUpdater(view[0], "{{a}}"); +  var scope = new Scope();    scope.set('a', undefined);    controller.updateView(scope); @@ -151,20 +151,20 @@ BindUpdaterTest.prototype.testShouldDisplayNothingForUndefined = function () {  BindUpdaterTest.prototype.testShouldDisplayJsonForNonStrings = function () {    var view = $('<span />'); -  var controller = new nglr.BindUpdater(view[0], "{{obj}}"); +  var controller = new BindUpdater(view[0], "{{obj}}"); -  controller.updateView(new nglr.Scope({obj:[]})); +  controller.updateView(new Scope({obj:[]}));    assertEquals("[]", view.text()); -  controller.updateView(new nglr.Scope({obj:{text:'abc'}})); -  assertEquals('abc', nglr.fromJson(view.text()).text); +  controller.updateView(new Scope({obj:{text:'abc'}})); +  assertEquals('abc', fromJson(view.text()).text);  };  BindUpdaterTest.prototype.testShouldInsertHtmlNode = function () {    var view = $('<span />'); -  var controller = new nglr.BindUpdater(view[0], "<fake>&{{obj}}</fake>"); -  var scope = new nglr.Scope(); +  var controller = new BindUpdater(view[0], "<fake>&{{obj}}</fake>"); +  var scope = new Scope();    scope.set("obj", $('<div>myDiv</div>')[0]);    controller.updateView(scope); @@ -174,8 +174,8 @@ BindUpdaterTest.prototype.testShouldInsertHtmlNode = function () {  BindUpdaterTest.prototype.testShouldDisplayTextMethod = function () {    var view = $('<div />'); -  var controller = new nglr.BindUpdater(view[0], "{{obj}}"); -  var scope = new nglr.Scope(); +  var controller = new BindUpdater(view[0], "{{obj}}"); +  var scope = new Scope();    scope.set("obj", new angular.filter.Meta({text:function(){return "abc";}}));    controller.updateView(scope); @@ -187,13 +187,13 @@ BindUpdaterTest.prototype.testShouldDisplayTextMethod = function () {    scope.set("obj", {text:"123"});    controller.updateView(scope); -  assertEquals("123", nglr.fromJson(view.text()).text); +  assertEquals("123", fromJson(view.text()).text);  };  BindUpdaterTest.prototype.testShouldDisplayHtmlMethod = function () {    var view = $('<div />'); -  var controller = new nglr.BindUpdater(view[0], "{{obj}}"); -  var scope = new nglr.Scope(); +  var controller = new BindUpdater(view[0], "{{obj}}"); +  var scope = new Scope();    scope.set("obj", new angular.filter.Meta({html:function(){return "a<div>b</div>c";}}));    controller.updateView(scope); @@ -205,13 +205,13 @@ BindUpdaterTest.prototype.testShouldDisplayHtmlMethod = function () {    scope.set("obj", {html:"123"});    controller.updateView(scope); -  assertEquals("123", nglr.fromJson(view.text()).html); +  assertEquals("123", fromJson(view.text()).html);  };  BindUpdaterTest.prototype.testUdateBoolean = function() {    var view = $('<div />'); -  var controller = new nglr.BindUpdater(view[0], "{{true}}, {{false}}"); -  controller.updateView(new nglr.Scope()); +  var controller = new BindUpdater(view[0], "{{true}}, {{false}}"); +  controller.updateView(new Scope());    assertEquals('true, false', view.text());  }; @@ -219,9 +219,9 @@ BindAttrUpdaterTest = TestCase("BindAttrUpdaterTest");  BindAttrUpdaterTest.prototype.testShouldLoadBlankImageWhenBindingIsUndefined = function () {    var view = $('<img />'); -  var controller = new nglr.BindAttrUpdater(view[0], {src: '{{imageUrl}}'}); +  var controller = new BindAttrUpdater(view[0], {src: '{{imageUrl}}'}); -  var scope = new nglr.Scope(); +  var scope = new Scope();    scope.set('imageUrl', undefined);    scope.set('config.server', 'http://server'); @@ -229,16 +229,15 @@ BindAttrUpdaterTest.prototype.testShouldLoadBlankImageWhenBindingIsUndefined = f    assertEquals("http://server/images/blank.gif", view.attr('src'));  }; -RepeaterUpdaterTest = TestCase("RepeaterUpdaterTest");  RepeaterUpdaterTest.prototype.testShouldNotDieWhenRepeatExpressionIsNull = function() { -  var rep = new nglr.RepeaterUpdater(null, "$item in items", null, null); -  var scope = new nglr.Scope(); +  var rep = new RepeaterUpdater(null, "$item in items", null, null); +  var scope = new Scope();    scope.set('items', undefined);    rep.updateView(scope);  };  RepeaterUpdaterTest.prototype.testShouldIterateOverKeys = function() { -  var rep = new nglr.RepeaterUpdater(null, "($k,_v) in items", null, null); +  var rep = new RepeaterUpdater(null, "($k,_v) in items", null, null);    assertEquals("items", rep.iteratorExp);    assertEquals("_v", rep.valueExp);    assertEquals("$k", rep.keyExp); @@ -247,14 +246,14 @@ RepeaterUpdaterTest.prototype.testShouldIterateOverKeys = function() {  EvalUpdaterTest = TestCase("EvalUpdaterTest");  EvalUpdaterTest.prototype.testEvalThrowsException = function(){    var view = $('<div/>'); -  var eval = new nglr.EvalUpdater(view[0], 'undefined()'); +  var eval = new EvalUpdater(view[0], 'undefined()'); -  eval.updateView(new nglr.Scope()); +  eval.updateView(new Scope());    assertTrue(!!view.attr('ng-error'));    assertTrue(view.hasClass('ng-exception'));    eval.exp = "1"; -  eval.updateView(new nglr.Scope()); +  eval.updateView(new Scope());    assertFalse(!!view.attr('ng-error'));    assertFalse(view.hasClass('ng-exception'));  }; @@ -262,8 +261,8 @@ EvalUpdaterTest.prototype.testEvalThrowsException = function(){  RadioControllerTest = TestCase("RadioController");  RadioControllerTest.prototype.testItShouldTreatTrueStringAsBoolean = function () {    var view = $('<input type="radio" name="select" value="true"/>'); -  var radio = new nglr.RadioController(view[0], 'select'); -  var scope = new nglr.Scope({select:true}); +  var radio = new RadioController(view[0], 'select'); +  var scope = new Scope({select:true});    radio.updateView(scope);    assertTrue(view[0].checked);  }; diff --git a/test/XSitePostTest.js b/test/XSitePostTest.js deleted file mode 100644 index 8a3e4d6f..00000000 --- a/test/XSitePostTest.js +++ /dev/null @@ -1,47 +0,0 @@ -XSitePost = TestCase("XSitePost"); - -var e = function(text){ return Base64.encode(text); }; - -XSitePost.prototype.testMessageReceived = function () { -  expectAsserts(4); -  var xPost = new nglr.XSitePost(); -  xPost.baseUrl = "http://getangular.test"; -  xPost.post = function(url, request, callback){ -    assertEquals('http://getangular.test/url', url); -    assertEquals('abc', request.a); -    assertEquals('xyz', request.x); -  }; -  xPost.incomingFragment('#id;0;1;'+e('/url')+':a:'+e('abc')+':x:'+e('xyz')); -  assertEquals('{}', nglr.toJson(xPost.inQueue)); -}; - -XSitePost.prototype.testMessageReceivedInParts = function () { -  expectAsserts(5); -  var xPost = new nglr.XSitePost(); -  xPost.baseUrl = "http://getangular.test"; -  xPost.post = function(url, request, callback){ -    assertEquals('http://getangular.test/url', url); -    assertEquals('abc', request.a); -    assertEquals('xyz', request.x); -  }; -  xPost.incomingFragment('#id;1;2;:x:'+e('xyz')); -  assertNotSame('{}', nglr.toJson(xPost.inQueue)); -  xPost.incomingFragment('#id;0;2;'+e('/url')+':a:'+e('abc')); -  assertEquals('{}', nglr.toJson(xPost.inQueue)); -}; - -XSitePost.prototype.testPostResponsIsEnqueued = function () { -  var xPost = new nglr.XSitePost(); -  xPost.maxMsgSize = 11; -  xPost.response("id", "response", "status"); - -  assertEquals('["id:0:2:cmVzcG9uc2U","id:1:2:="]', -      nglr.toJson(xPost.outQueue)); -}; - -XSitePost.prototype.testPush = function () { -  var window = {}; -  var xPost = new nglr.XSitePost(window); -  xPost.response("id", "response", "status"); -  assertEquals('id:0:1:cmVzcG9uc2U=', xPost.outQueue[0]); -}; diff --git a/test/formsTest.js b/test/formsTest.js index 66c4ec69..ccade915 100644 --- a/test/formsTest.js +++ b/test/formsTest.js @@ -2,7 +2,7 @@ nglrTest = TestCase('nglrTest');  nglrTest.prototype.testShiftBind = function(){    expectAsserts(3); -  nglr.shiftBind('this', function(target, arg) { +  shiftBind('this', function(target, arg) {      assertEquals(this, 'this');      assertEquals(target, 'target');      assertEquals(arg, 'arg'); @@ -11,7 +11,7 @@ nglrTest.prototype.testShiftBind = function(){  nglrTest.prototype.testBind = function(){    expectAsserts(2); -  nglr.bind('this', function(arg) { +  bind('this', function(arg) {      assertEquals(this, 'this');      assertEquals(arg, 'arg');    }).apply('XXX', ['arg']); diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js index 13378d36..dde21846 100644 --- a/test/testabilityPatch.js +++ b/test/testabilityPatch.js @@ -6,8 +6,8 @@ HIDDEN = jQuery.browser.msie ?           ' style="display: none; "' :           ' style="display: none;"'; -nglr.msie = jQuery.browser.msie; -nglr.alert = function(msg) {jstestdriver.console.log("ALERT: " + msg);}; +msie = jQuery.browser.msie; +alert = function(msg) {jstestdriver.console.log("ALERT: " + msg);};  function noop(){} @@ -50,7 +50,7 @@ jQuery.fn.sortedHtml = function() {    var toString = function(index, node) {      node = node || this;      if (node.nodeName == "#text") { -      html += nglr.escapeHtml(node.nodeValue); +      html += escapeHtml(node.nodeValue);      } else {        html += '<' + node.nodeName.toLowerCase();        var attributes = node.attributes || []; @@ -89,14 +89,14 @@ jQuery.fn.sortedHtml = function() {  };  function encode64(obj){ -  return Base64.encode(nglr.toJson(obj)); +  return Base64.encode(toJson(obj));  }  function decode64(base64){ -  return nglr.fromJson(Base64.decode(base64)); +  return fromJson(Base64.decode(base64));  } -nglr.Loader.prototype.configureJQueryPlugins(); +Loader.prototype.configureJQueryPlugins();  function assertHidden(node) {    var display = node.css('display'); @@ -110,7 +110,7 @@ function assertVisible(node) {  }  function assertJsonEquals(expected, actual) { -  assertEquals(nglr.toJson(expected), nglr.toJson(actual)); +  assertEquals(toJson(expected), toJson(actual));  }  function assertUndefined(value) { @@ -118,7 +118,7 @@ function assertUndefined(value) {  }  function assertDefined(value) { -  assertTrue(nglr.toJson(value), !!value); +  assertTrue(toJson(value), !!value);  }  function assertThrows(error, fn){  | 
