aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Rakefile35
-rw-r--r--TODO.text2
-rw-r--r--angular-minified.js122
-rw-r--r--angular.js4732
-rw-r--r--jsTestDriver.conf3
-rw-r--r--lib/shrinksafe/js.jarbin756883 -> 0 bytes
-rw-r--r--lib/shrinksafe/shrinksafe.jarbin17685 -> 0 bytes
-rw-r--r--src/API.js8
-rw-r--r--src/Binder.js106
-rw-r--r--src/ControlBar.js22
-rw-r--r--src/DataStore.js72
-rw-r--r--src/Filters.js8
-rw-r--r--src/JSON.js20
-rw-r--r--src/Loader.js145
-rw-r--r--src/Model.js26
-rw-r--r--src/Parser.js116
-rw-r--r--src/Scope.js62
-rw-r--r--src/Server.js32
-rw-r--r--src/Users.js8
-rw-r--r--src/Validators.js2
-rw-r--r--src/Widgets.js244
-rw-r--r--src/Widgets.js.orig764
-rw-r--r--src/XSitePost.js100
-rw-r--r--src/angular-bootstrap.js3
-rw-r--r--src/angular.prefix2
-rw-r--r--src/angular.suffix1
-rw-r--r--src/test/Runner.js26
-rw-r--r--src/test/Steps.js2
-rw-r--r--test/BinderTest.js209
-rw-r--r--test/ConsoleTest.js9
-rw-r--r--test/DataStoreTest.js96
-rw-r--r--test/EntityDeclarationTest.js8
-rw-r--r--test/FileControllerTest.js24
-rw-r--r--test/FiltersTest.js16
-rw-r--r--test/JsonTest.js54
-rw-r--r--test/LoaderTest.js18
-rw-r--r--test/ModelTest.js12
-rw-r--r--test/ParserTest.js108
-rw-r--r--test/ScopeTest.js32
-rw-r--r--test/ServerTest.js10
-rw-r--r--test/UsersTest.js4
-rw-r--r--test/WidgetsTest.js95
-rw-r--r--test/XSitePostTest.js47
-rw-r--r--test/formsTest.js4
-rw-r--r--test/testabilityPatch.js16
45 files changed, 5514 insertions, 1911 deletions
diff --git a/Rakefile b/Rakefile
index 56482e39..a4823809 100644
--- a/Rakefile
+++ b/Rakefile
@@ -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
diff --git a/TODO.text b/TODO.text
index fab19695..d4d013a5 100644
--- a/TODO.text
+++ b/TODO.text
@@ -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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};escapeAttr=function(a){if(!a||!a.replace)return a;return a.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;")};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="&nbsp;"+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>&lt;angular/&gt;</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);
diff --git a/angular.js b/angular.js
index 2ac33572..0e1527f2 100644
--- a/angular.js
+++ b/angular.js
@@ -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,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};
-nglr.escapeAttr=function(b){if(!b||!b.replace)return b;return b.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;")};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="&nbsp;"+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>&lt;angular/&gt;</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, '&amp;').
+ replace(/</g, '&lt;').
+ replace(/>/g, '&gt;');
+};
+
+escapeAttr = function(html) {
+ if (!html || !html.replace)
+ return html;
+ return html.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g,
+ '&quot;');
+};
+
+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 = '&nbsp;' + 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>&lt;angular/&gt;</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
deleted file mode 100644
index c081d16b..00000000
--- a/lib/shrinksafe/js.jar
+++ /dev/null
Binary files differ
diff --git a/lib/shrinksafe/shrinksafe.jar b/lib/shrinksafe/shrinksafe.jar
deleted file mode 100644
index eeb7b14e..00000000
--- a/lib/shrinksafe/shrinksafe.jar
+++ /dev/null
Binary files differ
diff --git a/src/API.js b/src/API.js
index c51fe01d..6fb6e8fc 100644
--- a/src/API.js
+++ b/src/API.js
@@ -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 = '&nbsp;' + 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>&lt;angular/&gt;</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, '&gt;');
};
-nglr.escapeAttr = function(html) {
+escapeAttr = function(html) {
if (!html || !html.replace)
return html;
return html.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g,
'&quot;');
};
-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 = "&lt;a class='ng-angular-logo' href='http://www.getangular.com'&gt;&amp;lt;angular/&amp;gt;&lt;/a&gt;&trade;";
-
-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 = '&nbsp;';
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("&lt;div&gt;&amp;amp;&lt;/div&gt;", nglr.escapeHtml('<div>&amp;</div>'));
+ assertEquals("&lt;div&gt;&amp;amp;&lt;/div&gt;", escapeHtml('<div>&amp;</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){