| author | ymh <ymh.work@gmail.com> |
| Mon, 20 Aug 2012 16:07:15 +0200 | |
| changeset 22 | 948283342245 |
| parent 21 | b43dd87f7ffa |
| child 23 | 70c8af9b44ec |
--- a/server/pom.xml Fri Aug 17 18:36:12 2012 +0200 +++ b/server/pom.xml Mon Aug 20 16:07:15 2012 +0200 @@ -98,7 +98,12 @@ <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.8.0</version> - </dependency> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <version>1.6.6</version> + </dependency> </dependencies> <organization> <name>IRI</name>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,20 @@ +package org.iri_research.renkan.coweb; + +import java.util.Map; + +import org.coweb.DefaultSessionModerator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RenkanSessionModerator extends DefaultSessionModerator { + + private final Logger logger = LoggerFactory.getLogger(RenkanSessionModerator.class); + + @Override + public boolean onSync(Map<String, Object> data) { + + this.logger.debug("Debugging onSync : " + data.toString()); + return super.onSync(data); + } + +}
--- a/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java Fri Aug 17 18:36:12 2012 +0200 +++ b/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java Mon Aug 20 16:07:15 2012 +0200 @@ -18,6 +18,8 @@ import javax.ws.rs.core.UriInfo; import org.iri_research.renkan.db.MongoConnectionManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.mongodb.BasicDBObject; import com.mongodb.DB; @@ -32,6 +34,8 @@ @Path("projects") public class ProjectsResource { + private Logger logger = LoggerFactory.getLogger(ProjectsResource.class); + @Context private UriInfo uriInfo; @@ -56,7 +60,9 @@ @Path("{id : [a-zA-Z\\-0-9]+}") @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") public String getProject(@PathParam("id") String projectId) { - + + this.logger.debug("GetProject : id " + projectId); + DBCollection projectCollection = this.getCollection(); DBObject project = projectCollection.findOne(projectId); @@ -194,7 +200,6 @@ } @POST - @Path("") @Consumes(MediaType.APPLICATION_JSON) public Response postProject(String projectContent) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/resources/_firebug/LICENSE Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,37 @@ +License Disclaimer: + +All contents of this directory are Copyright (c) the Dojo Foundation, with the +following exceptions: +------------------------------------------------------------------------------- + +firebug.html, firebug.js, errIcon.png, infoIcon.png, warningIcon.png: + * Copyright (c) 2006-2007, Joe Hewitt, All rights reserved. + Distributed under the terms of the BSD License (see below) + +------------------------------------------------------------------------------- + +Copyright (c) 2006-2007, Joe Hewitt +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Dojo Foundation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/resources/_firebug/firebug.css Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,208 @@ +.firebug { + margin: 0; + background:#fff; + font-family: Lucida Grande, Tahoma, sans-serif; + font-size: 11px; + overflow: hidden; + border: 1px solid black; + position: relative; +} +.firebug a { + text-decoration: none; +} +.firebug a:hover { + text-decoration: underline; +} +.firebug a:visited{ + color:#0000FF; +} +.firebug #firebugToolbar { + height: 18px; + line-height:18px; + border-top: 1px solid ThreeDHighlight; + border-bottom: 1px solid ThreeDShadow; + padding: 2px 6px; + + background:#f0f0f0; +} +.firebug #firebugLog, .firebug #objectLog { + overflow: auto; + position: absolute; + left: 0; + width: 100%; +} +#objectLog{ + overflow:scroll; + height:258px; +} +.firebug #firebugCommandLine { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 18px; + border: none; + border-top: 1px solid ThreeDShadow; +} +.firebug .logRow { + position: relative; + border-bottom: 1px solid #D7D7D7; + padding: 2px 4px 1px 6px; + background-color: #FFFFFF; +} +.firebug .logRow-command { + font-family: Monaco, monospace; + color: blue; +} +.firebug .objectBox-null { + padding: 0 2px; + border: 1px solid #666666; + background-color: #888888; + color: #FFFFFF; +} +.firebug .objectBox-string { + font-family: Monaco, monospace; + color: red; + white-space: pre; +} +.firebug .objectBox-number { + color: #000088; +} +.firebug .objectBox-function { + font-family: Monaco, monospace; + color: DarkGreen; +} +.firebug .objectBox-object { + color: DarkGreen; + font-weight: bold; +} +.firebug .logRow-info, +.firebug .logRow-error, +.firebug .logRow-warning + { + background: #00FFFF no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} +.firebug .logRow-info { + background: #FFF url(infoIcon.png) no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} +.firebug .logRow-warning { + + background: #00FFFF url(warningIcon.png) no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} +.firebug .logRow-error { + background: LightYellow url(errorIcon.png) no-repeat 2px 2px; + padding-left: 20px; + padding-bottom: 3px; +} +.firebug .errorMessage { + vertical-align: top; + color: #FF0000; +} +.firebug .objectBox-sourceLink { + position: absolute; + right: 4px; + top: 2px; + padding-left: 8px; + font-family: Lucida Grande, sans-serif; + font-weight: bold; + color: #0000FF; +} +.firebug .logRow-group { + background: #EEEEEE; + border-bottom: none; +} +.firebug .logGroup { + background: #EEEEEE; +} +.firebug .logGroupBox { + margin-left: 24px; + border-top: 1px solid #D7D7D7; + border-left: 1px solid #D7D7D7; +} +.firebug .selectorTag, +.firebug .selectorId, +.firebug .selectorClass { + font-family: Monaco, monospace; + font-weight: normal; +} +.firebug .selectorTag { + color: #0000FF; +} +.firebug .selectorId { + color: DarkBlue; +} +.firebug .selectorClass { + color: red; +} +.firebug .objectBox-element { + font-family: Monaco, monospace; + color: #000088; +} +.firebug .nodeChildren { + margin-left: 16px; +} +.firebug .nodeTag { + color: blue; +} +.firebug .nodeValue { + color: #FF0000; + font-weight: normal; +} +.firebug .nodeText, +.firebug .nodeComment { + margin: 0 2px; + vertical-align: top; +} +.firebug .nodeText { + color: #333333; +} +.firebug .nodeComment { + color: DarkGreen; +} +.firebug .propertyNameCell { + vertical-align: top; +} +.firebug .propertyName { + font-weight: bold; +} +#firebugToolbar ul.tabs{ + margin:0 !important; + padding:0; +} +#firebugToolbar ul.tabs li{ + list-style:none; + background:transparent url(tab_lft_norm.png) no-repeat left; + line-height:18px; + float:left; + margin-left:5px; +} +#firebugToolbar ul.tabs li.right{ + float:right; + margin-right:5px; + margin-left:0; +} +#firebugToolbar ul.tabs li.gap{ + margin-left:20px; +} +#firebugToolbar .tabs a{ + text-decoration:none; + background:transparent url(tab_rgt_norm.png) no-repeat right; + line-height:18px; + padding:3px 9px 4px 0px; + margin-left:9px; + color:#333333; +} +#firebugToolbar .tabs li:hover{ + background:transparent url(tab_lft_over.png) no-repeat left; +} +#firebugToolbar .tabs a:hover{ + text-decoration:none; + background:transparent url(tab_rgt_over.png) no-repeat right; + color:#FFFFFF; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/resources/_firebug/firebug.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,898 @@ +/* + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +//>>built +define("dojo/_firebug/firebug",["../_base/kernel","require","../_base/html","../sniff","../_base/array","../_base/lang","../_base/event","../_base/unload"],function(_1,_2,_3,_4){ +var _5=(/Trident/.test(window.navigator.userAgent)); +if(_5){ +var _6=["log","info","debug","warn","error"]; +for(var i=0;i<_6.length;i++){ +var m=_6[i]; +if(!console[m]||console[m]._fake){ +continue; +} +var n="_"+_6[i]; +console[n]=console[m]; +console[m]=(function(){ +var _7=n; +return function(){ +console[_7](Array.prototype.join.call(arguments," ")); +}; +})(); +} +try{ +console.clear(); +} +catch(e){ +} +} +if(_4("ff")||_4("chrome")||_4("safari")||_5||window.firebug||(typeof console!="undefined"&&console.firebug)||_1.config.useCustomLogger||_4("air")){ +return; +} +try{ +if(window!=window.parent){ +if(window.parent["console"]){ +window.console=window.parent.console; +} +return; +} +} +catch(e){ +} +var _8=document; +var _9=window; +var _a=0; +var _b=null; +var _c=null; +var _d=null; +var _e=null; +var _f=null; +var _10=null; +var _11=false; +var _12=[]; +var _13=[]; +var _14={}; +var _15={}; +var _16=null; +var _17; +var _18; +var _19=false; +var _1a=null; +var _1b=document.createElement("div"); +var _1c; +var _1d; +window.console={_connects:[],log:function(){ +_1e(arguments,""); +},debug:function(){ +_1e(arguments,"debug"); +},info:function(){ +_1e(arguments,"info"); +},warn:function(){ +_1e(arguments,"warning"); +},error:function(){ +_1e(arguments,"error"); +},assert:function(_1f,_20){ +if(!_1f){ +var _21=[]; +for(var i=1;i<arguments.length;++i){ +_21.push(arguments[i]); +} +_1e(_21.length?_21:["Assertion Failure"],"error"); +throw _20?_20:"Assertion Failure"; +} +},dir:function(obj){ +var str=_22(obj); +str=str.replace(/\n/g,"<br />"); +str=str.replace(/\t/g," "); +_23([str],"dir"); +},dirxml:function(_24){ +var _25=[]; +_26(_24,_25); +_23(_25,"dirxml"); +},group:function(){ +_23(arguments,"group",_27); +},groupEnd:function(){ +_23(arguments,"",_28); +},time:function(_29){ +_14[_29]=new Date().getTime(); +},timeEnd:function(_2a){ +if(_2a in _14){ +var _2b=(new Date()).getTime()-_14[_2a]; +_1e([_2a+":",_2b+"ms"]); +delete _14[_2a]; +} +},count:function(_2c){ +if(!_15[_2c]){ +_15[_2c]=0; +} +_15[_2c]++; +_1e([_2c+": "+_15[_2c]]); +},trace:function(_2d){ +var _2e=_2d||3; +var f=console.trace.caller; +for(var i=0;i<_2e;i++){ +var _2f=f.toString(); +var _30=[]; +for(var a=0;a<f.arguments.length;a++){ +_30.push(f.arguments[a]); +} +if(f.arguments.length){ +}else{ +} +f=f.caller; +} +},profile:function(){ +this.warn(["profile() not supported."]); +},profileEnd:function(){ +},clear:function(){ +if(_c){ +while(_c.childNodes.length){ +_1.destroy(_c.firstChild); +} +} +_1.forEach(this._connects,_1.disconnect); +},open:function(){ +_31(true); +},close:function(){ +if(_11){ +_31(); +} +},_restoreBorder:function(){ +if(_1c){ +_1c.style.border=_1d; +} +},openDomInspector:function(){ +_19=true; +_c.style.display="none"; +_16.style.display="block"; +_d.style.display="none"; +document.body.style.cursor="pointer"; +_17=_1.connect(document,"mousemove",function(evt){ +if(!_19){ +return; +} +if(!_1a){ +_1a=setTimeout(function(){ +_1a=null; +},50); +}else{ +return; +} +var _32=evt.target; +if(_32&&(_1c!==_32)){ +var _33=true; +console._restoreBorder(); +var _34=[]; +_26(_32,_34); +_16.innerHTML=_34.join(""); +_1c=_32; +_1d=_1c.style.border; +_1c.style.border="#0000FF 1px solid"; +} +}); +setTimeout(function(){ +_18=_1.connect(document,"click",function(evt){ +document.body.style.cursor=""; +_19=!_19; +_1.disconnect(_18); +}); +},30); +},_closeDomInspector:function(){ +document.body.style.cursor=""; +_1.disconnect(_17); +_1.disconnect(_18); +_19=false; +console._restoreBorder(); +},openConsole:function(){ +_c.style.display="block"; +_16.style.display="none"; +_d.style.display="none"; +console._closeDomInspector(); +},openObjectInspector:function(){ +_c.style.display="none"; +_16.style.display="none"; +_d.style.display="block"; +console._closeDomInspector(); +},recss:function(){ +var i,a,s; +a=document.getElementsByTagName("link"); +for(i=0;i<a.length;i++){ +s=a[i]; +if(s.rel.toLowerCase().indexOf("stylesheet")>=0&&s.href){ +var h=s.href.replace(/(&|%5C?)forceReload=\d+/,""); +s.href=h+(h.indexOf("?")>=0?"&":"?")+"forceReload="+new Date().valueOf(); +} +} +}}; +function _31(_35){ +_11=_35||!_11; +if(_b){ +_b.style.display=_11?"block":"none"; +} +}; +function _36(){ +_31(true); +if(_f){ +_f.focus(); +} +}; +function _37(x,y,w,h){ +var win=window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0"); +if(!win){ +var msg="Firebug Lite could not open a pop-up window, most likely because of a blocker.\n"+"Either enable pop-ups for this domain, or change the djConfig to popup=false."; +alert(msg); +} +_38(win); +var _39=win.document; +var _3a="<html style=\"height:100%;\"><head><title>Firebug Lite</title></head>\n"+"<body bgColor=\"#ccc\" style=\"height:97%;\" onresize=\"opener.onFirebugResize()\">\n"+"<div id=\"fb\"></div>"+"</body></html>"; +_39.write(_3a); +_39.close(); +return win; +}; +function _38(wn){ +var d=new Date(); +d.setTime(d.getTime()+(60*24*60*60*1000)); +d=d.toUTCString(); +var dc=wn.document,_3b; +if(wn.innerWidth){ +_3b=function(){ +return {w:wn.innerWidth,h:wn.innerHeight}; +}; +}else{ +if(dc.documentElement&&dc.documentElement.clientWidth){ +_3b=function(){ +return {w:dc.documentElement.clientWidth,h:dc.documentElement.clientHeight}; +}; +}else{ +if(dc.body){ +_3b=function(){ +return {w:dc.body.clientWidth,h:dc.body.clientHeight}; +}; +} +} +} +window.onFirebugResize=function(){ +_49(_3b().h); +clearInterval(wn._firebugWin_resize); +wn._firebugWin_resize=setTimeout(function(){ +var x=wn.screenLeft,y=wn.screenTop,w=wn.outerWidth||wn.document.body.offsetWidth,h=wn.outerHeight||wn.document.body.offsetHeight; +document.cookie="_firebugPosition="+[x,y,w,h].join(",")+"; expires="+d+"; path=/"; +},5000); +}; +}; +function _3c(){ +if(_b){ +return; +} +_31(true); +if(_1.config.popup){ +var _3d="100%"; +var _3e=document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/); +var p=_3e?_3e[1].split(","):[2,2,320,480]; +_9=_37(p[0],p[1],p[2],p[3]); +_8=_9.document; +_1.config.debugContainerId="fb"; +_9.console=window.console; +_9.dojo=window.dojo; +}else{ +_8=document; +_3d=(_1.config.debugHeight||300)+"px"; +} +var _3f=_8.createElement("link"); +_3f.href=_2.toUrl("./firebug.css"); +_3f.rel="stylesheet"; +_3f.type="text/css"; +var _40=_8.getElementsByTagName("head"); +if(_40){ +_40=_40[0]; +} +if(!_40){ +_40=_8.getElementsByTagName("html")[0]; +} +if(_4("ie")){ +window.setTimeout(function(){ +_40.appendChild(_3f); +},0); +}else{ +_40.appendChild(_3f); +} +if(_1.config.debugContainerId){ +_b=_8.getElementById(_1.config.debugContainerId); +} +if(!_b){ +_b=_8.createElement("div"); +_8.body.appendChild(_b); +} +_b.className+=" firebug"; +_b.id="firebug"; +_b.style.height=_3d; +_b.style.display=(_11?"block":"none"); +var _41=function(_42,_43,_44,_45){ +return "<li class=\""+_45+"\"><a href=\"javascript:void(0);\" onclick=\"console."+_44+"(); return false;\" title=\""+_43+"\">"+_42+"</a></li>"; +}; +_b.innerHTML="<div id=\"firebugToolbar\">"+" <ul id=\"fireBugTabs\" class=\"tabs\">"+_41("Clear","Remove All Console Logs","clear","")+_41("ReCSS","Refresh CSS without reloading page","recss","")+_41("Console","Show Console Logs","openConsole","gap")+_41("DOM","Show DOM Inspector","openDomInspector","")+_41("Object","Show Object Inspector","openObjectInspector","")+((_1.config.popup)?"":_41("Close","Close the console","close","gap"))+"\t</ul>"+"</div>"+"<input type=\"text\" id=\"firebugCommandLine\" />"+"<div id=\"firebugLog\"></div>"+"<div id=\"objectLog\" style=\"display:none;\">Click on an object in the Log display</div>"+"<div id=\"domInspect\" style=\"display:none;\">Hover over HTML elements in the main page. Click to hold selection.</div>"; +_10=_8.getElementById("firebugToolbar"); +_f=_8.getElementById("firebugCommandLine"); +_46(_f,"keydown",_47); +_46(_8,_4("ie")||_4("safari")?"keydown":"keypress",_48); +_c=_8.getElementById("firebugLog"); +_d=_8.getElementById("objectLog"); +_16=_8.getElementById("domInspect"); +_e=_8.getElementById("fireBugTabs"); +_49(); +_4a(); +}; +_1.addOnLoad(_3c); +function _4b(){ +_8=null; +if(_9.console){ +_9.console.clear(); +} +_9=null; +_b=null; +_c=null; +_d=null; +_16=null; +_f=null; +_12=[]; +_13=[]; +_14={}; +}; +function _4c(){ +var _4d=_f.value; +_f.value=""; +_23(["> ",_4d],"command"); +var _4e; +try{ +_4e=eval(_4d); +} +catch(e){ +} +}; +function _49(h){ +var _4f=25; +var _50=h?h-(_4f+_f.offsetHeight+25+(h*0.01))+"px":(_b.offsetHeight-_4f-_f.offsetHeight)+"px"; +_c.style.top=_4f+"px"; +_c.style.height=_50; +_d.style.height=_50; +_d.style.top=_4f+"px"; +_16.style.height=_50; +_16.style.top=_4f+"px"; +_f.style.bottom=0; +_1.addOnWindowUnload(_4b); +}; +function _23(_51,_52,_53){ +if(_c){ +_54(_51,_52,_53); +}else{ +_12.push([_51,_52,_53]); +} +}; +function _4a(){ +var _55=_12; +_12=[]; +for(var i=0;i<_55.length;++i){ +_54(_55[i][0],_55[i][1],_55[i][2]); +} +}; +function _54(_56,_57,_58){ +var _59=_c.scrollTop+_c.offsetHeight>=_c.scrollHeight; +_58=_58||_5a; +_58(_56,_57); +if(_59){ +_c.scrollTop=_c.scrollHeight-_c.offsetHeight; +} +}; +function _5b(row){ +var _5c=_13.length?_13[_13.length-1]:_c; +_5c.appendChild(row); +}; +function _5a(_5d,_5e){ +var row=_c.ownerDocument.createElement("div"); +row.className="logRow"+(_5e?" logRow-"+_5e:""); +row.innerHTML=_5d.join(""); +_5b(row); +}; +function _27(_5f,_60){ +_1e(_5f,_60); +var _61=_c.ownerDocument.createElement("div"); +_61.className="logGroupBox"; +_5b(_61); +_13.push(_61); +}; +function _28(){ +_13.pop(); +}; +function _1e(_62,_63){ +var _64=[]; +var _65=_62[0]; +var _66=0; +if(typeof (_65)!="string"){ +_65=""; +_66=-1; +} +var _67=_68(_65); +for(var i=0;i<_67.length;++i){ +var _69=_67[i]; +if(_69&&typeof _69=="object"){ +_69.appender(_62[++_66],_64); +}else{ +_6a(_69,_64); +} +} +var ids=[]; +var obs=[]; +for(i=_66+1;i<_62.length;++i){ +_6a(" ",_64); +var _6b=_62[i]; +if(_6b===undefined||_6b===null){ +_6c(_6b,_64); +}else{ +if(typeof (_6b)=="string"){ +_6a(_6b,_64); +}else{ +if(_6b instanceof Date){ +_6a(_6b.toString(),_64); +}else{ +if(_6b.nodeType==9){ +_6a("[ XmlDoc ]",_64); +}else{ +var id="_a"+_a++; +ids.push(id); +obs.push(_6b); +var str="<a id=\""+id+"\" href=\"javascript:void(0);\">"+_6d(_6b)+"</a>"; +_6e(str,_64); +} +} +} +} +} +_23(_64,_63); +for(i=0;i<ids.length;i++){ +var btn=_8.getElementById(ids[i]); +if(!btn){ +continue; +} +btn.obj=obs[i]; +_9.console._connects.push(_1.connect(btn,"onclick",function(){ +console.openObjectInspector(); +try{ +_22(this.obj); +} +catch(e){ +this.obj=e; +} +_d.innerHTML="<pre>"+_22(this.obj)+"</pre>"; +})); +} +}; +function _68(_6f){ +var _70=[]; +var reg=/((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/; +var _71={s:_6a,d:_72,i:_72,f:_73}; +for(var m=reg.exec(_6f);m;m=reg.exec(_6f)){ +var _74=m[8]?m[8]:m[5]; +var _75=_74 in _71?_71[_74]:_76; +var _77=m[3]?parseInt(m[3]):(m[4]=="."?-1:0); +_70.push(_6f.substr(0,m[0][0]=="%"?m.index:m.index+1)); +_70.push({appender:_75,precision:_77}); +_6f=_6f.substr(m.index+m[0].length); +} +_70.push(_6f); +return _70; +}; +function _78(_79){ +function _7a(ch){ +switch(ch){ +case "<": +return "<"; +case ">": +return ">"; +case "&": +return "&"; +case "'": +return "'"; +case "\"": +return """; +} +return "?"; +}; +return String(_79).replace(/[<>&"']/g,_7a); +}; +function _7b(_7c){ +try{ +return _7c+""; +} +catch(e){ +return null; +} +}; +function _6e(_7d,_7e){ +_7e.push(_7b(_7d)); +}; +function _6a(_7f,_80){ +_80.push(_78(_7b(_7f))); +}; +function _6c(_81,_82){ +_82.push("<span class=\"objectBox-null\">",_78(_7b(_81)),"</span>"); +}; +function _83(_84,_85){ +_85.push("<span class=\"objectBox-string\">"",_78(_7b(_84)),""</span>"); +}; +function _72(_86,_87){ +_87.push("<span class=\"objectBox-number\">",_78(_7b(_86)),"</span>"); +}; +function _73(_88,_89){ +_89.push("<span class=\"objectBox-number\">",_78(_7b(_88)),"</span>"); +}; +function _8a(_8b,_8c){ +_8c.push("<span class=\"objectBox-function\">",_6d(_8b),"</span>"); +}; +function _76(_8d,_8e){ +try{ +if(_8d===undefined){ +_6c("undefined",_8e); +}else{ +if(_8d===null){ +_6c("null",_8e); +}else{ +if(typeof _8d=="string"){ +_83(_8d,_8e); +}else{ +if(typeof _8d=="number"){ +_72(_8d,_8e); +}else{ +if(typeof _8d=="function"){ +_8a(_8d,_8e); +}else{ +if(_8d.nodeType==1){ +_8f(_8d,_8e); +}else{ +if(typeof _8d=="object"){ +_90(_8d,_8e); +}else{ +_6a(_8d,_8e); +} +} +} +} +} +} +} +} +catch(e){ +} +}; +function _90(_91,_92){ +var _93=_7b(_91); +var _94=/\[object (.*?)\]/; +var m=_94.exec(_93); +_92.push("<span class=\"objectBox-object\">",m?m[1]:_93,"</span>"); +}; +function _8f(_95,_96){ +_96.push("<span class=\"objectBox-selector\">"); +_96.push("<span class=\"selectorTag\">",_78(_95.nodeName.toLowerCase()),"</span>"); +if(_95.id){ +_96.push("<span class=\"selectorId\">#",_78(_95.id),"</span>"); +} +if(_95.className){ +_96.push("<span class=\"selectorClass\">.",_78(_95.className),"</span>"); +} +_96.push("</span>"); +}; +function _26(_97,_98){ +if(_97.nodeType==1){ +_98.push("<div class=\"objectBox-element\">","<<span class=\"nodeTag\">",_97.nodeName.toLowerCase(),"</span>"); +for(var i=0;i<_97.attributes.length;++i){ +var _99=_97.attributes[i]; +if(!_99.specified){ +continue; +} +_98.push(" <span class=\"nodeName\">",_99.nodeName.toLowerCase(),"</span>="<span class=\"nodeValue\">",_78(_99.nodeValue),"</span>""); +} +if(_97.firstChild){ +_98.push("></div><div class=\"nodeChildren\">"); +for(var _9a=_97.firstChild;_9a;_9a=_9a.nextSibling){ +_26(_9a,_98); +} +_98.push("</div><div class=\"objectBox-element\"></<span class=\"nodeTag\">",_97.nodeName.toLowerCase(),"></span></div>"); +}else{ +_98.push("/></div>"); +} +}else{ +if(_97.nodeType==3){ +_98.push("<div class=\"nodeText\">",_78(_97.nodeValue),"</div>"); +} +} +}; +function _46(_9b,_9c,_9d){ +if(document.all){ +_9b.attachEvent("on"+_9c,_9d); +}else{ +_9b.addEventListener(_9c,_9d,false); +} +}; +function _9e(_9f,_a0,_a1){ +if(document.all){ +_9f.detachEvent("on"+_a0,_a1); +}else{ +_9f.removeEventListener(_a0,_a1,false); +} +}; +function _a2(_a3){ +if(document.all){ +_a3.cancelBubble=true; +}else{ +_a3.stopPropagation(); +} +}; +function _a4(msg,_a5,_a6){ +var _a7=_a5.lastIndexOf("/"); +var _a8=_a7==-1?_a5:_a5.substr(_a7+1); +var _a9=["<span class=\"errorMessage\">",msg,"</span>","<div class=\"objectBox-sourceLink\">",_a8," (line ",_a6,")</div>"]; +_23(_a9,"error"); +}; +var _aa=new Date().getTime(); +function _48(_ab){ +var _ac=(new Date()).getTime(); +if(_ac>_aa+200){ +_ab=_1.fixEvent(_ab); +var _ad=_1.keys; +var ekc=_ab.keyCode; +_aa=_ac; +if(ekc==_ad.F12){ +_31(); +}else{ +if((ekc==_ad.NUMPAD_ENTER||ekc==76)&&_ab.shiftKey&&(_ab.metaKey||_ab.ctrlKey)){ +_36(); +}else{ +return; +} +} +_a2(_ab); +} +}; +function _47(e){ +var dk=_1.keys; +if(e.keyCode==13&&_f.value){ +_ae(_f.value); +_4c(); +}else{ +if(e.keyCode==27){ +_f.value=""; +}else{ +if(e.keyCode==dk.UP_ARROW||e.charCode==dk.UP_ARROW){ +_af("older"); +}else{ +if(e.keyCode==dk.DOWN_ARROW||e.charCode==dk.DOWN_ARROW){ +_af("newer"); +}else{ +if(e.keyCode==dk.HOME||e.charCode==dk.HOME){ +_b0=1; +_af("older"); +}else{ +if(e.keyCode==dk.END||e.charCode==dk.END){ +_b0=999999; +_af("newer"); +} +} +} +} +} +} +}; +var _b0=-1; +var _b1=null; +function _ae(_b2){ +var _b3=_b4("firebug_history"); +_b3=(_b3)?_1.fromJson(_b3):[]; +var pos=_1.indexOf(_b3,_b2); +if(pos!=-1){ +_b3.splice(pos,1); +} +_b3.push(_b2); +_b4("firebug_history",_1.toJson(_b3),30); +while(_b3.length&&!_b4("firebug_history")){ +_b3.shift(); +_b4("firebug_history",_1.toJson(_b3),30); +} +_b1=null; +_b0=-1; +}; +function _af(_b5){ +var _b6=_b4("firebug_history"); +_b6=(_b6)?_1.fromJson(_b6):[]; +if(!_b6.length){ +return; +} +if(_b1===null){ +_b1=_f.value; +} +if(_b0==-1){ +_b0=_b6.length; +} +if(_b5=="older"){ +--_b0; +if(_b0<0){ +_b0=0; +} +}else{ +if(_b5=="newer"){ +++_b0; +if(_b0>_b6.length){ +_b0=_b6.length; +} +} +} +if(_b0==_b6.length){ +_f.value=_b1; +_b1=null; +}else{ +_f.value=_b6[_b0]; +} +}; +function _b4(_b7,_b8){ +var c=document.cookie; +if(arguments.length==1){ +var _b9=c.match(new RegExp("(?:^|; )"+_b7+"=([^;]*)")); +return _b9?decodeURIComponent(_b9[1]):undefined; +}else{ +var d=new Date(); +d.setMonth(d.getMonth()+1); +document.cookie=_b7+"="+encodeURIComponent(_b8)+((d.toUtcString)?"; expires="+d.toUTCString():""); +} +}; +function _ba(it){ +return it&&it instanceof Array||typeof it=="array"; +}; +function _bb(o){ +var cnt=0; +for(var nm in o){ +cnt++; +} +return cnt; +}; +function _22(o,i,txt,_bc){ +var ind=" \t"; +txt=txt||""; +i=i||ind; +_bc=_bc||[]; +var _bd; +if(o&&o.nodeType==1){ +var _be=[]; +_26(o,_be); +return _be.join(""); +} +var br=",\n",cnt=0,_bf=_bb(o); +if(o instanceof Date){ +return i+o.toString()+br; +} +looking: +for(var nm in o){ +cnt++; +if(cnt==_bf){ +br="\n"; +} +if(o[nm]===window||o[nm]===document){ +}else{ +if(o[nm]===null){ +txt+=i+nm+" : NULL"+br; +}else{ +if(o[nm]&&o[nm].nodeType){ +if(o[nm].nodeType==1){ +}else{ +if(o[nm].nodeType==3){ +txt+=i+nm+" : [ TextNode "+o[nm].data+" ]"+br; +} +} +}else{ +if(typeof o[nm]=="object"&&(o[nm] instanceof String||o[nm] instanceof Number||o[nm] instanceof Boolean)){ +txt+=i+nm+" : "+o[nm]+","+br; +}else{ +if(o[nm] instanceof Date){ +txt+=i+nm+" : "+o[nm].toString()+br; +}else{ +if(typeof (o[nm])=="object"&&o[nm]){ +for(var j=0,_c0;_c0=_bc[j];j++){ +if(o[nm]===_c0){ +txt+=i+nm+" : RECURSION"+br; +continue looking; +} +} +_bc.push(o[nm]); +_bd=(_ba(o[nm]))?["[","]"]:["{","}"]; +txt+=i+nm+" : "+_bd[0]+"\n"; +txt+=_22(o[nm],i+ind,"",_bc); +txt+=i+_bd[1]+br; +}else{ +if(typeof o[nm]=="undefined"){ +txt+=i+nm+" : undefined"+br; +}else{ +if(nm=="toString"&&typeof o[nm]=="function"){ +var _c1=o[nm](); +if(typeof _c1=="string"&&_c1.match(/function ?(.*?)\(/)){ +_c1=_78(_6d(o[nm])); +} +txt+=i+nm+" : "+_c1+br; +}else{ +txt+=i+nm+" : "+_78(_6d(o[nm]))+br; +} +} +} +} +} +} +} +} +} +return txt; +}; +function _6d(obj){ +var _c2=(obj instanceof Error); +if(obj.nodeType==1){ +return _78("< "+obj.tagName.toLowerCase()+" id=\""+obj.id+"\" />"); +} +if(obj.nodeType==3){ +return _78("[TextNode: \""+obj.nodeValue+"\"]"); +} +var nm=(obj&&(obj.id||obj.name||obj.ObjectID||obj.widgetId)); +if(!_c2&&nm){ +return "{"+nm+"}"; +} +var _c3=2; +var _c4=4; +var cnt=0; +if(_c2){ +nm="[ Error: "+(obj.message||obj.description||obj)+" ]"; +}else{ +if(_ba(obj)){ +nm="["+obj.slice(0,_c4).join(","); +if(obj.length>_c4){ +nm+=" ... ("+obj.length+" items)"; +} +nm+="]"; +}else{ +if(typeof obj=="function"){ +nm=obj+""; +var reg=/function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/; +var m=reg.exec(nm); +if(m){ +if(!m[1]){ +m[1]="function"; +} +nm=m[1]+m[2]; +}else{ +nm="function()"; +} +}else{ +if(typeof obj!="object"||typeof obj=="string"){ +nm=obj+""; +}else{ +nm="{"; +for(var i in obj){ +cnt++; +if(cnt>_c3){ +break; +} +nm+=i+":"+_78(obj[i])+" "; +} +nm+="}"; +} +} +} +} +return nm; +}; +_46(document,_4("ie")||_4("safari")?"keydown":"keypress",_48); +if((document.documentElement.getAttribute("debug")=="true")||(_1.config.isDebug)){ +_31(true); +} +_1.addOnWindowUnload(function(){ +_9e(document,_4("ie")||_4("safari")?"keydown":"keypress",_48); +window.onFirebugResize=null; +window.console=null; +}); +});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/resources/_firebug/firebug.js.uncompressed.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,1191 @@ +define("dojo/_firebug/firebug", [ + "../_base/kernel", + "require", + "../_base/html", + "../sniff", + "../_base/array", + "../_base/lang", + "../_base/event", + "../_base/unload"], function(dojo, require, html, has){ + + // module: + // dojo/_firebug/firebug + // summary: + // Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox + // description: + // Opens a console for logging, debugging, and error messages. + // Contains partial functionality to Firebug. See function list below. + // + // NOTE: + // Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug. + // Firebug Lite is included in Dojo by permission from Joe Hewitt + // If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug + // functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html + // + // NOTE: + // To test Firebug Lite in Firefox: + // + // - FF2: set "console = null" before loading dojo and set djConfig.isDebug=true + // - FF3: disable Firebug and set djConfig.isDebug=true + // + // example: + // Supports inline objects in object inspector window (only simple trace of dom nodes, however) + // | console.log("my object", {foo:"bar"}) + // example: + // Option for console to open in popup window + // | var djConfig = {isDebug: true, popup:true }; + // example: + // Option for console height (ignored for popup) + // | var djConfig = {isDebug: true, debugHeight:100 } + + + var isNewIE = (/Trident/.test(window.navigator.userAgent)); + if(isNewIE){ + // Fixing IE's console + // IE doesn't insert space between arguments. How annoying. + var calls = ["log", "info", "debug", "warn", "error"]; + for(var i=0;i<calls.length;i++){ + var m = calls[i]; + if(!console[m] ||console[m]._fake){ + // IE9 doesn't have console.debug method, a fake one is added later + continue; + } + var n = "_"+calls[i]; + console[n] = console[m]; + console[m] = (function(){ + var type = n; + return function(){ + console[type](Array.prototype.join.call(arguments, " ")); + }; + })(); + } + // clear the console on load. This is more than a convenience - too many logs crashes it. + // If closed it throws an error + try{ console.clear(); }catch(e){} + } + + if( + has("ff") || // Firefox has Firebug + has("chrome") || // Chrome 3+ has a console + has("safari") || // Safari 4 has a console + isNewIE || // Has the new IE console + window.firebug || // Testing for mozilla firebug lite + (typeof console != "undefined" && console.firebug) || //The firebug console + dojo.config.useCustomLogger || // Allow custom loggers + has("air") // isDebug triggers AIRInsector, not Firebug + ){ + return; + } + + // don't build firebug in iframes + try{ + if(window != window.parent){ + // but if we've got a parent logger, connect to it + if(window.parent["console"]){ + window.console = window.parent.console; + } + return; + } + }catch(e){/*squelch*/} + + // *************************************************************************** + // Placing these variables before the functions that use them to avoid a + // shrinksafe bug where variable renaming does not happen correctly otherwise. + + // most of the objects in this script are run anonomously + var _firebugDoc = document; + var _firebugWin = window; + var __consoleAnchorId__ = 0; + + var consoleFrame = null; + var consoleBody = null; + var consoleObjectInspector = null; + var fireBugTabs = null; + var commandLine = null; + var consoleToolbar = null; + + var frameVisible = false; + var messageQueue = []; + var groupStack = []; + var timeMap = {}; + var countMap = {}; + + var consoleDomInspector = null; + var _inspectionMoveConnection; + var _inspectionClickConnection; + var _inspectionEnabled = false; + var _inspectionTimer = null; + var _inspectTempNode = document.createElement("div"); + + + var _inspectCurrentNode; + var _restoreBorderStyle; + + // *************************************************************************** + + window.console = { + _connects: [], + log: function(){ + // summary: + // Sends arguments to console. + logFormatted(arguments, ""); + }, + + debug: function(){ + // summary: + // Sends arguments to console. Missing finctionality to show script line of trace. + logFormatted(arguments, "debug"); + }, + + info: function(){ + // summary: + // Sends arguments to console, highlighted with (I) icon. + logFormatted(arguments, "info"); + }, + + warn: function(){ + // summary: + // Sends warning arguments to console, highlighted with (!) icon and blue style. + logFormatted(arguments, "warning"); + }, + + error: function(){ + // summary: + // Sends error arguments (object) to console, highlighted with (X) icon and yellow style + // NEW: error object now displays in object inspector + logFormatted(arguments, "error"); + }, + + assert: function(truth, message){ + // summary: + // Tests for true. Throws exception if false. + if(!truth){ + var args = []; + for(var i = 1; i < arguments.length; ++i){ + args.push(arguments[i]); + } + + logFormatted(args.length ? args : ["Assertion Failure"], "error"); + throw message ? message : "Assertion Failure"; + } + }, + + dir: function(obj){ + var str = printObject( obj ); + str = str.replace(/\n/g, "<br />"); + str = str.replace(/\t/g, " "); + logRow([str], "dir"); + }, + + dirxml: function(node){ + var html = []; + appendNode(node, html); + logRow(html, "dirxml"); + }, + + group: function(){ + // summary: + // collects log messages into a group, starting with this call and ending with + // groupEnd(). Missing collapse functionality + logRow(arguments, "group", pushGroup); + }, + + groupEnd: function(){ + // summary: + // Closes group. See above + logRow(arguments, "", popGroup); + }, + + time: function(name){ + // summary: + // Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title); + // example: + // | console.time("load"); + // | console.time("myFunction"); + // | console.timeEnd("load"); + // | console.timeEnd("myFunction"); + timeMap[name] = new Date().getTime(); + }, + + timeEnd: function(name){ + // summary: + // See above. + if(name in timeMap){ + var delta = (new Date()).getTime() - timeMap[name]; + logFormatted([name+ ":", delta+"ms"]); + delete timeMap[name]; + } + }, + + count: function(name){ + // summary: + // Not supported + if(!countMap[name]) countMap[name] = 0; + countMap[name]++; + logFormatted([name+": "+countMap[name]]); + }, + + trace: function(_value){ + var stackAmt = _value || 3; + var f = console.trace.caller; //function that called trace + console.log(">>> console.trace(stack)"); + for(var i=0;i<stackAmt;i++){ + var func = f.toString(); + var args=[]; + for (var a = 0; a < f.arguments.length; a++){ + args.push(f.arguments[a]); + } + if(f.arguments.length){ + console.dir({"function":func, "arguments":args}); + }else{ + console.dir({"function":func}); + } + + f = f.caller; + } + }, + + profile: function(){ + // summary: + // Not supported + this.warn(["profile() not supported."]); + }, + + profileEnd: function(){ }, + + clear: function(){ + // summary: + // Clears message console. Do not call this directly + if(consoleBody){ + while(consoleBody.childNodes.length){ + dojo.destroy(consoleBody.firstChild); + } + } + dojo.forEach(this._connects,dojo.disconnect); + }, + + open: function(){ + // summary: + // Opens message console. Do not call this directly + toggleConsole(true); + }, + + close: function(){ + // summary: + // Closes message console. Do not call this directly + if(frameVisible){ + toggleConsole(); + } + }, + _restoreBorder: function(){ + if(_inspectCurrentNode){ + _inspectCurrentNode.style.border = _restoreBorderStyle; + } + }, + openDomInspector: function(){ + _inspectionEnabled = true; + consoleBody.style.display = "none"; + consoleDomInspector.style.display = "block"; + consoleObjectInspector.style.display = "none"; + document.body.style.cursor = "pointer"; + _inspectionMoveConnection = dojo.connect(document, "mousemove", function(evt){ + if(!_inspectionEnabled){ return; } + if(!_inspectionTimer){ + _inspectionTimer = setTimeout(function(){ _inspectionTimer = null; }, 50); + }else{ + return; + } + var node = evt.target; + if(node && (_inspectCurrentNode !== node)){ + var parent = true; + + console._restoreBorder(); + var html = []; + appendNode(node, html); + consoleDomInspector.innerHTML = html.join(""); + + _inspectCurrentNode = node; + _restoreBorderStyle = _inspectCurrentNode.style.border; + _inspectCurrentNode.style.border = "#0000FF 1px solid"; + } + }); + setTimeout(function(){ + _inspectionClickConnection = dojo.connect(document, "click", function(evt){ + document.body.style.cursor = ""; + _inspectionEnabled = !_inspectionEnabled; + dojo.disconnect(_inspectionClickConnection); + // console._restoreBorder(); + }); + }, 30); + }, + _closeDomInspector: function(){ + document.body.style.cursor = ""; + dojo.disconnect(_inspectionMoveConnection); + dojo.disconnect(_inspectionClickConnection); + _inspectionEnabled = false; + console._restoreBorder(); + }, + openConsole:function(){ + // summary: + // Closes object inspector and opens message console. Do not call this directly + consoleBody.style.display = "block"; + consoleDomInspector.style.display = "none"; + consoleObjectInspector.style.display = "none"; + console._closeDomInspector(); + }, + openObjectInspector:function(){ + consoleBody.style.display = "none"; + consoleDomInspector.style.display = "none"; + consoleObjectInspector.style.display = "block"; + console._closeDomInspector(); + }, + recss: function(){ + // this is placed in dojo since the console is most likely + // in another window and dojo is easilly accessible + var i,a,s;a=document.getElementsByTagName('link'); + for(i=0;i<a.length;i++){ + s=a[i]; + if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href){ + var h=s.href.replace(/(&|%5C?)forceReload=\d+/,''); + s.href=h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+new Date().valueOf(); + } + } + } + }; + + // *************************************************************************** + + function toggleConsole(forceOpen){ + frameVisible = forceOpen || !frameVisible; + if(consoleFrame){ + consoleFrame.style.display = frameVisible ? "block" : "none"; + } + } + + function focusCommandLine(){ + toggleConsole(true); + if(commandLine){ + commandLine.focus(); + } + } + + function openWin(x,y,w,h){ + var win = window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0"); + if(!win){ + var msg = "Firebug Lite could not open a pop-up window, most likely because of a blocker.\n" + + "Either enable pop-ups for this domain, or change the djConfig to popup=false."; + alert(msg); + } + createResizeHandler(win); + var newDoc=win.document; + //Safari needs an HTML height + var HTMLstring= '<html style="height:100%;"><head><title>Firebug Lite</title></head>\n' + + '<body bgColor="#ccc" style="height:97%;" onresize="opener.onFirebugResize()">\n' + + '<div id="fb"></div>' + + '</body></html>'; + + newDoc.write(HTMLstring); + newDoc.close(); + return win; + } + + function createResizeHandler(wn){ + // summary: + // Creates handle for onresize window. Called from script in popup's body tag (so that it will work with IE). + // + + var d = new Date(); + d.setTime(d.getTime()+(60*24*60*60*1000)); // 60 days + d = d.toUTCString(); + + var dc = wn.document, + getViewport; + + if (wn.innerWidth){ + getViewport = function(){ + return{w:wn.innerWidth, h:wn.innerHeight}; + }; + }else if (dc.documentElement && dc.documentElement.clientWidth){ + getViewport = function(){ + return{w:dc.documentElement.clientWidth, h:dc.documentElement.clientHeight}; + }; + }else if (dc.body){ + getViewport = function(){ + return{w:dc.body.clientWidth, h:dc.body.clientHeight}; + }; + } + + + window.onFirebugResize = function(){ + + //resize the height of the console log body + layout(getViewport().h); + + clearInterval(wn._firebugWin_resize); + wn._firebugWin_resize = setTimeout(function(){ + var x = wn.screenLeft, + y = wn.screenTop, + w = wn.outerWidth || wn.document.body.offsetWidth, + h = wn.outerHeight || wn.document.body.offsetHeight; + + document.cookie = "_firebugPosition=" + [x,y,w,h].join(",") + "; expires="+d+"; path=/"; + + }, 5000); //can't capture window.onMove - long timeout gives better chance of capturing a resize, then the move + + }; + } + + + /*****************************************************************************/ + + + function createFrame(){ + if(consoleFrame){ + return; + } + toggleConsole(true); + if(dojo.config.popup){ + var containerHeight = "100%"; + var cookieMatch = document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/); + var p = cookieMatch ? cookieMatch[1].split(",") : [2,2,320,480]; + + _firebugWin = openWin(p[0],p[1],p[2],p[3]); // global + _firebugDoc = _firebugWin.document; // global + + dojo.config.debugContainerId = 'fb'; + + // connecting popup + _firebugWin.console = window.console; + _firebugWin.dojo = window.dojo; + }else{ + _firebugDoc = document; + containerHeight = (dojo.config.debugHeight || 300) + "px"; + } + + var styleElement = _firebugDoc.createElement("link"); + styleElement.href = require.toUrl("./firebug.css"); + styleElement.rel = "stylesheet"; + styleElement.type = "text/css"; + var styleParent = _firebugDoc.getElementsByTagName("head"); + if(styleParent){ + styleParent = styleParent[0]; + } + if(!styleParent){ + styleParent = _firebugDoc.getElementsByTagName("html")[0]; + } + if(has("ie")){ + window.setTimeout(function(){ styleParent.appendChild(styleElement); }, 0); + }else{ + styleParent.appendChild(styleElement); + } + + if(dojo.config.debugContainerId){ + consoleFrame = _firebugDoc.getElementById(dojo.config.debugContainerId); + } + if(!consoleFrame){ + consoleFrame = _firebugDoc.createElement("div"); + _firebugDoc.body.appendChild(consoleFrame); + } + consoleFrame.className += " firebug"; + consoleFrame.id = "firebug"; + consoleFrame.style.height = containerHeight; + consoleFrame.style.display = (frameVisible ? "block" : "none"); + + var buildLink = function(label, title, method, _class){ + return '<li class="'+_class+'"><a href="javascript:void(0);" onclick="console.'+ method +'(); return false;" title="'+title+'">'+label+'</a></li>'; + }; + consoleFrame.innerHTML = + '<div id="firebugToolbar">' + + ' <ul id="fireBugTabs" class="tabs">' + + + buildLink("Clear", "Remove All Console Logs", "clear", "") + + buildLink("ReCSS", "Refresh CSS without reloading page", "recss", "") + + + buildLink("Console", "Show Console Logs", "openConsole", "gap") + + buildLink("DOM", "Show DOM Inspector", "openDomInspector", "") + + buildLink("Object", "Show Object Inspector", "openObjectInspector", "") + + ((dojo.config.popup) ? "" : buildLink("Close", "Close the console", "close", "gap")) + + + ' </ul>' + + '</div>' + + '<input type="text" id="firebugCommandLine" />' + + '<div id="firebugLog"></div>' + + '<div id="objectLog" style="display:none;">Click on an object in the Log display</div>' + + '<div id="domInspect" style="display:none;">Hover over HTML elements in the main page. Click to hold selection.</div>'; + + + consoleToolbar = _firebugDoc.getElementById("firebugToolbar"); + + commandLine = _firebugDoc.getElementById("firebugCommandLine"); + addEvent(commandLine, "keydown", onCommandLineKeyDown); + + addEvent(_firebugDoc, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown); + + consoleBody = _firebugDoc.getElementById("firebugLog"); + consoleObjectInspector = _firebugDoc.getElementById("objectLog"); + consoleDomInspector = _firebugDoc.getElementById("domInspect"); + fireBugTabs = _firebugDoc.getElementById("fireBugTabs"); + layout(); + flush(); + } + + dojo.addOnLoad(createFrame); + + function clearFrame(){ + _firebugDoc = null; + + if(_firebugWin.console){ + _firebugWin.console.clear(); + } + _firebugWin = null; + consoleFrame = null; + consoleBody = null; + consoleObjectInspector = null; + consoleDomInspector = null; + commandLine = null; + messageQueue = []; + groupStack = []; + timeMap = {}; + } + + + function evalCommandLine(){ + var text = commandLine.value; + commandLine.value = ""; + + logRow(["> ", text], "command"); + + var value; + try{ + value = eval(text); + }catch(e){ + console.debug(e); // put exception on the console + } + + console.log(value); + } + + function layout(h){ + var tHeight = 25; //consoleToolbar.offsetHeight; // tab style not ready on load - throws off layout + var height = h ? + h - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" : + (consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px"; + + consoleBody.style.top = tHeight + "px"; + consoleBody.style.height = height; + consoleObjectInspector.style.height = height; + consoleObjectInspector.style.top = tHeight + "px"; + consoleDomInspector.style.height = height; + consoleDomInspector.style.top = tHeight + "px"; + commandLine.style.bottom = 0; + + dojo.addOnWindowUnload(clearFrame); + } + + function logRow(message, className, handler){ + if(consoleBody){ + writeMessage(message, className, handler); + }else{ + messageQueue.push([message, className, handler]); + } + } + + function flush(){ + var queue = messageQueue; + messageQueue = []; + + for(var i = 0; i < queue.length; ++i){ + writeMessage(queue[i][0], queue[i][1], queue[i][2]); + } + } + + function writeMessage(message, className, handler){ + var isScrolledToBottom = + consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight; + + handler = handler||writeRow; + + handler(message, className); + + if(isScrolledToBottom){ + consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight; + } + } + + function appendRow(row){ + var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody; + container.appendChild(row); + } + + function writeRow(message, className){ + var row = consoleBody.ownerDocument.createElement("div"); + row.className = "logRow" + (className ? " logRow-"+className : ""); + row.innerHTML = message.join(""); + appendRow(row); + } + + function pushGroup(message, className){ + logFormatted(message, className); + + //var groupRow = consoleBody.ownerDocument.createElement("div"); + //groupRow.className = "logGroup"; + var groupRowBox = consoleBody.ownerDocument.createElement("div"); + groupRowBox.className = "logGroupBox"; + //groupRow.appendChild(groupRowBox); + appendRow(groupRowBox); + groupStack.push(groupRowBox); + } + + function popGroup(){ + groupStack.pop(); + } + + // *************************************************************************** + + function logFormatted(objects, className){ + var html = []; + + var format = objects[0]; + var objIndex = 0; + + if(typeof(format) != "string"){ + format = ""; + objIndex = -1; + } + + var parts = parseFormat(format); + + for(var i = 0; i < parts.length; ++i){ + var part = parts[i]; + if(part && typeof part == "object"){ + part.appender(objects[++objIndex], html); + }else{ + appendText(part, html); + } + } + + + var ids = []; + var obs = []; + for(i = objIndex+1; i < objects.length; ++i){ + appendText(" ", html); + + var object = objects[i]; + if(object === undefined || object === null ){ + appendNull(object, html); + + }else if(typeof(object) == "string"){ + appendText(object, html); + + }else if(object instanceof Date){ + appendText(object.toString(), html); + + }else if(object.nodeType == 9){ + appendText("[ XmlDoc ]", html); + + }else{ + // Create link for object inspector + // need to create an ID for this link, since it is currently text + var id = "_a" + __consoleAnchorId__++; + ids.push(id); + // need to save the object, so the arrays line up + obs.push(object); + var str = '<a id="'+id+'" href="javascript:void(0);">'+getObjectAbbr(object)+'</a>'; + + appendLink( str , html); + } + } + + logRow(html, className); + + // Now that the row is inserted in the DOM, loop through all of the links that were just created + for(i=0; i<ids.length; i++){ + var btn = _firebugDoc.getElementById(ids[i]); + if(!btn){ continue; } + + // store the object in the dom btn for reference later + // avoid parsing these objects unless necessary + btn.obj = obs[i]; + + _firebugWin.console._connects.push(dojo.connect(btn, "onclick", function(){ + + console.openObjectInspector(); + + try{ + printObject(this.obj); + }catch(e){ + this.obj = e; + } + consoleObjectInspector.innerHTML = "<pre>" + printObject( this.obj ) + "</pre>"; + })); + } + } + + function parseFormat(format){ + var parts = []; + + var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/; + var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat}; + + for(var m = reg.exec(format); m; m = reg.exec(format)){ + var type = m[8] ? m[8] : m[5]; + var appender = type in appenderMap ? appenderMap[type] : appendObject; + var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0); + + parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1)); + parts.push({appender: appender, precision: precision}); + + format = format.substr(m.index+m[0].length); + } + + parts.push(format); + + return parts; + } + + function escapeHTML(value){ + function replaceChars(ch){ + switch(ch){ + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "'": + return "'"; + case '"': + return """; + } + return "?"; + } + return String(value).replace(/[<>&"']/g, replaceChars); + } + + function objectToString(object){ + try{ + return object+""; + }catch(e){ + return null; + } + } + + // *************************************************************************** + function appendLink(object, html){ + // needed for object links - no HTML escaping + html.push( objectToString(object) ); + } + + function appendText(object, html){ + html.push(escapeHTML(objectToString(object))); + } + + function appendNull(object, html){ + html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>'); + } + + function appendString(object, html){ + html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)), + '"</span>'); + } + + function appendInteger(object, html){ + html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>'); + } + + function appendFloat(object, html){ + html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>'); + } + + function appendFunction(object, html){ + html.push('<span class="objectBox-function">', getObjectAbbr(object), '</span>'); + } + + function appendObject(object, html){ + try{ + if(object === undefined){ + appendNull("undefined", html); + }else if(object === null){ + appendNull("null", html); + }else if(typeof object == "string"){ + appendString(object, html); + }else if(typeof object == "number"){ + appendInteger(object, html); + }else if(typeof object == "function"){ + appendFunction(object, html); + }else if(object.nodeType == 1){ + appendSelector(object, html); + }else if(typeof object == "object"){ + appendObjectFormatted(object, html); + }else{ + appendText(object, html); + } + }catch(e){ + /* squelch */ + } + } + + function appendObjectFormatted(object, html){ + var text = objectToString(object); + var reObject = /\[object (.*?)\]/; + + var m = reObject.exec(text); + html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>'); + } + + function appendSelector(object, html){ + html.push('<span class="objectBox-selector">'); + + html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>'); + if(object.id){ + html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>'); + } + if(object.className){ + html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>'); + } + + html.push('</span>'); + } + + function appendNode(node, html){ + if(node.nodeType == 1){ + html.push( + '<div class="objectBox-element">', + '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>'); + + for(var i = 0; i < node.attributes.length; ++i){ + var attr = node.attributes[i]; + if(!attr.specified){ continue; } + + html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(), + '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue), + '</span>"'); + } + + if(node.firstChild){ + html.push('></div><div class="nodeChildren">'); + + for(var child = node.firstChild; child; child = child.nextSibling){ + appendNode(child, html); + } + + html.push('</div><div class="objectBox-element"></<span class="nodeTag">', + node.nodeName.toLowerCase(), '></span></div>'); + }else{ + html.push('/></div>'); + } + }else if (node.nodeType == 3){ + html.push('<div class="nodeText">', escapeHTML(node.nodeValue), + '</div>'); + } + } + + // *************************************************************************** + + function addEvent(object, name, handler){ + if(document.all){ + object.attachEvent("on"+name, handler); + }else{ + object.addEventListener(name, handler, false); + } + } + + function removeEvent(object, name, handler){ + if(document.all){ + object.detachEvent("on"+name, handler); + }else{ + object.removeEventListener(name, handler, false); + } + } + + function cancelEvent(event){ + if(document.all){ + event.cancelBubble = true; + }else{ + event.stopPropagation(); + } + } + + function onError(msg, href, lineNo){ + var lastSlash = href.lastIndexOf("/"); + var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1); + + var html = [ + '<span class="errorMessage">', msg, '</span>', + '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>' + ]; + + logRow(html, "error"); + } + + + //After converting to div instead of iframe, now getting two keydowns right away in IE 6. + //Make sure there is a little bit of delay. + var onKeyDownTime = new Date().getTime(); + + function onKeyDown(event){ + var timestamp = (new Date()).getTime(); + if(timestamp > onKeyDownTime + 200){ + event = dojo.fixEvent(event); + var keys = dojo.keys; + var ekc = event.keyCode; + onKeyDownTime = timestamp; + if(ekc == keys.F12){ + toggleConsole(); + }else if( + (ekc == keys.NUMPAD_ENTER || ekc == 76) && + event.shiftKey && + (event.metaKey || event.ctrlKey) + ){ + focusCommandLine(); + }else{ + return; + } + cancelEvent(event); + } + } + + function onCommandLineKeyDown(e){ + var dk = dojo.keys; + if(e.keyCode == 13 && commandLine.value){ + addToHistory(commandLine.value); + evalCommandLine(); + }else if(e.keyCode == 27){ + commandLine.value = ""; + }else if(e.keyCode == dk.UP_ARROW || e.charCode == dk.UP_ARROW){ + navigateHistory("older"); + }else if(e.keyCode == dk.DOWN_ARROW || e.charCode == dk.DOWN_ARROW){ + navigateHistory("newer"); + }else if(e.keyCode == dk.HOME || e.charCode == dk.HOME){ + historyPosition = 1; + navigateHistory("older"); + }else if(e.keyCode == dk.END || e.charCode == dk.END){ + historyPosition = 999999; + navigateHistory("newer"); + } + } + + var historyPosition = -1; + var historyCommandLine = null; + + function addToHistory(value){ + var history = cookie("firebug_history"); + history = (history) ? dojo.fromJson(history) : []; + var pos = dojo.indexOf(history, value); + if (pos != -1){ + history.splice(pos, 1); + } + history.push(value); + cookie("firebug_history", dojo.toJson(history), 30); + while(history.length && !cookie("firebug_history")){ + history.shift(); + cookie("firebug_history", dojo.toJson(history), 30); + } + historyCommandLine = null; + historyPosition = -1; + } + + function navigateHistory(direction){ + var history = cookie("firebug_history"); + history = (history) ? dojo.fromJson(history) : []; + if(!history.length){ + return; + } + + if(historyCommandLine === null){ + historyCommandLine = commandLine.value; + } + + if(historyPosition == -1){ + historyPosition = history.length; + } + + if(direction == "older"){ + --historyPosition; + if(historyPosition < 0){ + historyPosition = 0; + } + }else if(direction == "newer"){ + ++historyPosition; + if(historyPosition > history.length){ + historyPosition = history.length; + } + } + + if(historyPosition == history.length){ + commandLine.value = historyCommandLine; + historyCommandLine = null; + }else{ + commandLine.value = history[historyPosition]; + } + } + + function cookie(name, value){ + var c = document.cookie; + if(arguments.length == 1){ + var matches = c.match(new RegExp("(?:^|; )" + name + "=([^;]*)")); + return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined + }else{ + var d = new Date(); + d.setMonth(d.getMonth()+1); + document.cookie = name + "=" + encodeURIComponent(value) + ((d.toUtcString) ? "; expires=" + d.toUTCString() : ""); + } + } + + function isArray(it){ + return it && it instanceof Array || typeof it == "array"; + } + + //*************************************************************************************************** + // Print Object Helpers + function objectLength(o){ + var cnt = 0; + for(var nm in o){ + cnt++; + } + return cnt; + } + + function printObject(o, i, txt, used){ + // Recursively trace object, indenting to represent depth for display in object inspector + var ind = " \t"; + txt = txt || ""; + i = i || ind; + used = used || []; + var opnCls; + + if(o && o.nodeType == 1){ + var html = []; + appendNode(o, html); + return html.join(""); + } + + var br=",\n", cnt = 0, length = objectLength(o); + + if(o instanceof Date){ + return i + o.toString() + br; + } + looking: + for(var nm in o){ + cnt++; + if(cnt==length){br = "\n";} + if(o[nm] === window || o[nm] === document){ + // do nothing + }else if(o[nm] === null){ + txt += i+nm + " : NULL" + br; + }else if(o[nm] && o[nm].nodeType){ + if(o[nm].nodeType == 1){ + //txt += i+nm + " : < "+o[nm].tagName+" id=\""+ o[nm].id+"\" />" + br; + }else if(o[nm].nodeType == 3){ + txt += i+nm + " : [ TextNode "+o[nm].data + " ]" + br; + } + + }else if(typeof o[nm] == "object" && (o[nm] instanceof String || o[nm] instanceof Number || o[nm] instanceof Boolean)){ + txt += i+nm + " : " + o[nm] + "," + br; + + }else if(o[nm] instanceof Date){ + txt += i+nm + " : " + o[nm].toString() + br; + + }else if(typeof(o[nm]) == "object" && o[nm]){ + for(var j = 0, seen; seen = used[j]; j++){ + if(o[nm] === seen){ + txt += i+nm + " : RECURSION" + br; + continue looking; + } + } + used.push(o[nm]); + + opnCls = (isArray(o[nm]))?["[","]"]:["{","}"]; + txt += i+nm +" : " + opnCls[0] + "\n";//non-standard break, (no comma) + txt += printObject(o[nm], i+ind, "", used); + txt += i + opnCls[1] + br; + + }else if(typeof o[nm] == "undefined"){ + txt += i+nm + " : undefined" + br; + }else if(nm == "toString" && typeof o[nm] == "function"){ + var toString = o[nm](); + if(typeof toString == "string" && toString.match(/function ?(.*?)\(/)){ + toString = escapeHTML(getObjectAbbr(o[nm])); + } + txt += i+nm +" : " + toString + br; + }else{ + txt += i+nm +" : "+ escapeHTML(getObjectAbbr(o[nm])) + br; + } + } + return txt; + } + + function getObjectAbbr(obj){ + // Gets an abbreviation of an object for display in log + // X items in object, including id + // X items in an array + // TODO: Firebug Sr. actually goes by char count + var isError = (obj instanceof Error); + if(obj.nodeType == 1){ + return escapeHTML('< '+obj.tagName.toLowerCase()+' id=\"'+ obj.id+ '\" />'); + } + if(obj.nodeType == 3){ + return escapeHTML('[TextNode: "'+obj.nodeValue+'"]'); + } + var nm = (obj && (obj.id || obj.name || obj.ObjectID || obj.widgetId)); + if(!isError && nm){ return "{"+nm+"}"; } + + var obCnt = 2; + var arCnt = 4; + var cnt = 0; + + if(isError){ + nm = "[ Error: "+(obj.message || obj.description || obj)+" ]"; + }else if(isArray(obj)){ + nm = "[" + obj.slice(0,arCnt).join(","); + if(obj.length > arCnt){ + nm += " ... ("+obj.length+" items)"; + } + nm += "]"; + }else if(typeof obj == "function"){ + nm = obj + ""; + var reg = /function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/; + var m = reg.exec(nm); + if(m){ + if(!m[1]){ + m[1] = "function"; + } + nm = m[1] + m[2]; + }else{ + nm = "function()"; + } + }else if(typeof obj != "object" || typeof obj == "string"){ + nm = obj + ""; + }else{ + nm = "{"; + for(var i in obj){ + cnt++; + if(cnt > obCnt){ break; } + nm += i+":"+escapeHTML(obj[i])+" "; + } + nm+="}"; + } + + return nm; + } + + //************************************************************************************* + + //window.onerror = onError; + + addEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown); + + if( (document.documentElement.getAttribute("debug") == "true")|| + (dojo.config.isDebug) + ){ + toggleConsole(true); + } + + dojo.addOnWindowUnload(function(){ + // Erase the globals and event handlers I created, to prevent spurious leak warnings + removeEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown); + window.onFirebugResize = null; + window.console = null; + }); + +});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/resources/log4j.xml Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> + <appender name="console" class="org.apache.log4j.ConsoleAppender"> + <param name="Target" value="System.out"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> + </layout> + </appender> + <logger name="org.iri_research.renkan"> + <level value="DEBUG" /> + </logger> + <root> + <priority value ="WARN" /> + <appender-ref ref="console" /> + </root> + +</log4j:configuration> \ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/cowebConfig.json Fri Aug 17 18:36:12 2012 +0200 +++ b/server/src/main/webapp/WEB-INF/cowebConfig.json Mon Aug 20 16:07:15 2012 +0200 @@ -1,2 +1,6 @@ -{ +{ + "sessionModerator" : "org.iri_research.renkan.coweb.RenkanSessionModerator", + "moderatorIsUpdater" : true, + "operationEngine" : true, + "bots": [] }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/js/backbone-relational.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,1687 @@ +/** + * Backbone-relational.js 0.6.0 + * (c) 2011 Paul Uithol + * + * Backbone-relational may be freely distributed under the MIT license; see the accompanying LICENSE.txt. + * For details and documentation: https://github.com/PaulUithol/Backbone-relational. + * Depends on Backbone (and thus on Underscore as well): https://github.com/documentcloud/backbone. + */ +( function( undefined ) { + "use strict"; + + /** + * CommonJS shim + **/ + var _, Backbone, exports; + if ( typeof window === 'undefined' ) { + _ = require( 'underscore' ); + Backbone = require( 'backbone' ); + exports = module.exports = Backbone; + } + else { + _ = window._; + Backbone = window.Backbone; + exports = window; + } + + Backbone.Relational = { + showWarnings: true + }; + + /** + * Semaphore mixin; can be used as both binary and counting. + **/ + Backbone.Semaphore = { + _permitsAvailable: null, + _permitsUsed: 0, + + acquire: function() { + if ( this._permitsAvailable && this._permitsUsed >= this._permitsAvailable ) { + throw new Error( 'Max permits acquired' ); + } + else { + this._permitsUsed++; + } + }, + + release: function() { + if ( this._permitsUsed === 0 ) { + throw new Error( 'All permits released' ); + } + else { + this._permitsUsed--; + } + }, + + isLocked: function() { + return this._permitsUsed > 0; + }, + + setAvailablePermits: function( amount ) { + if ( this._permitsUsed > amount ) { + throw new Error( 'Available permits cannot be less than used permits' ); + } + this._permitsAvailable = amount; + } + }; + + /** + * A BlockingQueue that accumulates items while blocked (via 'block'), + * and processes them when unblocked (via 'unblock'). + * Process can also be called manually (via 'process'). + */ + Backbone.BlockingQueue = function() { + this._queue = []; + }; + _.extend( Backbone.BlockingQueue.prototype, Backbone.Semaphore, { + _queue: null, + + add: function( func ) { + if ( this.isBlocked() ) { + this._queue.push( func ); + } + else { + func(); + } + }, + + process: function() { + while ( this._queue && this._queue.length ) { + this._queue.shift()(); + } + }, + + block: function() { + this.acquire(); + }, + + unblock: function() { + this.release(); + if ( !this.isBlocked() ) { + this.process(); + } + }, + + isBlocked: function() { + return this.isLocked(); + } + }); + /** + * Global event queue. Accumulates external events ('add:<key>', 'remove:<key>' and 'update:<key>') + * until the top-level object is fully initialized (see 'Backbone.RelationalModel'). + */ + Backbone.Relational.eventQueue = new Backbone.BlockingQueue(); + + /** + * Backbone.Store keeps track of all created (and destruction of) Backbone.RelationalModel. + * Handles lookup for relations. + */ + Backbone.Store = function() { + this._collections = []; + this._reverseRelations = []; + this._subModels = []; + this._modelScopes = [ exports ]; + }; + _.extend( Backbone.Store.prototype, Backbone.Events, { + addModelScope: function( scope ) { + this._modelScopes.push( scope ); + }, + + /** + * Add a set of subModelTypes to the store, that can be used to resolve the '_superModel' + * for a model later in 'setupSuperModel'. + * + * @param {Backbone.RelationalModel} subModelTypes + * @param {Backbone.RelationalModel} superModelType + */ + addSubModels: function( subModelTypes, superModelType ) { + this._subModels.push({ + 'superModelType': superModelType, + 'subModels': subModelTypes + }); + }, + + /** + * Check if the given modelType is registered as another model's subModel. If so, add it to the super model's + * '_subModels', and set the modelType's '_superModel', '_subModelTypeName', and '_subModelTypeAttribute'. + * + * @param {Backbone.RelationalModel} modelType + */ + setupSuperModel: function( modelType ) { + _.find( this._subModels, function( subModelDef ) { + return _.find( subModelDef.subModels, function( subModelTypeName, typeValue ) { + var subModelType = this.getObjectByName( subModelTypeName ); + + if ( modelType === subModelType ) { + // Set 'modelType' as a child of the found superModel + subModelDef.superModelType._subModels[ typeValue ] = modelType; + + // Set '_superModel', '_subModelTypeValue', and '_subModelTypeAttribute' on 'modelType'. + modelType._superModel = subModelDef.superModelType; + modelType._subModelTypeValue = typeValue; + modelType._subModelTypeAttribute = subModelDef.superModelType.prototype.subModelTypeAttribute; + return true; + } + }, this ); + }, this ); + }, + + /** + * Add a reverse relation. Is added to the 'relations' property on model's prototype, and to + * existing instances of 'model' in the store as well. + * @param {Object} relation + * @param {Backbone.RelationalModel} relation.model + * @param {String} relation.type + * @param {String} relation.key + * @param {String|Object} relation.relatedModel + */ + addReverseRelation: function( relation ) { + var exists = _.any( this._reverseRelations, function( rel ) { + return _.all( relation, function( val, key ) { + return val === rel[ key ]; + }); + }); + + if ( !exists && relation.model && relation.type ) { + this._reverseRelations.push( relation ); + + var addRelation = function( model, relation ) { + if ( !model.prototype.relations ) { + model.prototype.relations = []; + } + model.prototype.relations.push( relation ); + + _.each( model._subModels, function( subModel ) { + addRelation( subModel, relation ); + }, this ); + }; + + addRelation( relation.model, relation ); + + this.retroFitRelation( relation ); + } + }, + + /** + * Add a 'relation' to all existing instances of 'relation.model' in the store + * @param {Object} relation + */ + retroFitRelation: function( relation ) { + var coll = this.getCollection( relation.model ); + coll.each( function( model ) { + if ( !( model instanceof relation.model ) ) { + return; + } + + new relation.type( model, relation ); + }, this); + }, + + /** + * Find the Store's collection for a certain type of model. + * @param {Backbone.RelationalModel} model + * @return {Backbone.Collection} A collection if found (or applicable for 'model'), or null + */ + getCollection: function( model ) { + if ( model instanceof Backbone.RelationalModel ) { + model = model.constructor; + } + + var rootModel = model; + while ( rootModel._superModel ) { + rootModel = rootModel._superModel; + } + + var coll = _.detect( this._collections, function( c ) { + return c.model === rootModel; + }); + + if ( !coll ) { + coll = this._createCollection( rootModel ); + } + + return coll; + }, + + /** + * Find a type on the global object by name. Splits name on dots. + * @param {String} name + * @return {Object} + */ + getObjectByName: function( name ) { + var parts = name.split( '.' ), + type = null; + + _.find( this._modelScopes, function( scope ) { + type = _.reduce( parts, function( memo, val ) { + return memo[ val ]; + }, scope ); + + if ( type && type !== scope ) { + return true; + } + }, this ); + + return type; + }, + + _createCollection: function( type ) { + var coll; + + // If 'type' is an instance, take its constructor + if ( type instanceof Backbone.RelationalModel ) { + type = type.constructor; + } + + // Type should inherit from Backbone.RelationalModel. + if ( type.prototype instanceof Backbone.RelationalModel ) { + coll = new Backbone.Collection(); + coll.model = type; + + this._collections.push( coll ); + } + + return coll; + }, + + /** + * Find the attribute that is to be used as the `id` on a given object + * @param type + * @param {String|Number|Object|Backbone.RelationalModel} item + * @return {String|Number} + */ + resolveIdForItem: function( type, item ) { + var id = _.isString( item ) || _.isNumber( item ) ? item : null; + + if ( id === null ) { + if ( item instanceof Backbone.RelationalModel ) { + id = item.id; + } + else if ( _.isObject( item ) ) { + id = item[ type.prototype.idAttribute ]; + } + } + + // Make all falsy values `null` (except for 0, which could be an id.. see '/issues/179') + if ( !id && id !== 0 ) { + id = null; + } + + return id; + }, + + /** + * + * @param type + * @param {String|Number|Object|Backbone.RelationalModel} item + */ + find: function( type, item ) { + var id = this.resolveIdForItem( type, item ); + var coll = this.getCollection( type ); + + // Because the found object could be of any of the type's superModel + // types, only return it if it's actually of the type asked for. + if ( coll ) { + var obj = coll.get( id ); + + if ( obj instanceof type ) { + return obj; + } + } + + return null; + }, + + /** + * Add a 'model' to it's appropriate collection. Retain the original contents of 'model.collection'. + * @param {Backbone.RelationalModel} model + */ + register: function( model ) { + var coll = this.getCollection( model ); + + if ( coll ) { + if ( coll.get( model ) ) { + throw new Error( "Cannot instantiate more than one Backbone.RelationalModel with the same id per type!" ); + } + + var modelColl = model.collection; + coll.add( model ); + model.bind( 'destroy', this.unregister, this ); + model.collection = modelColl; + } + }, + + /** + * Explicitly update a model's id in it's store collection + * @param {Backbone.RelationalModel} model + */ + update: function( model ) { + var coll = this.getCollection( model ); + coll._onModelEvent( 'change:' + model.idAttribute, model, coll ); + }, + + /** + * Remove a 'model' from the store. + * @param {Backbone.RelationalModel} model + */ + unregister: function( model ) { + model.unbind( 'destroy', this.unregister ); + var coll = this.getCollection( model ); + coll && coll.remove( model ); + } + }); + Backbone.Relational.store = new Backbone.Store(); + + /** + * The main Relation class, from which 'HasOne' and 'HasMany' inherit. Internally, 'relational:<key>' events + * are used to regulate addition and removal of models from relations. + * + * @param {Backbone.RelationalModel} instance + * @param {Object} options + * @param {string} options.key + * @param {Backbone.RelationalModel.constructor} options.relatedModel + * @param {Boolean|String} [options.includeInJSON=true] Serialize the given attribute for related model(s)' in toJSON, or just their ids. + * @param {Boolean} [options.createModels=true] Create objects from the contents of keys if the object is not found in Backbone.store. + * @param {Object} [options.reverseRelation] Specify a bi-directional relation. If provided, Relation will reciprocate + * the relation to the 'relatedModel'. Required and optional properties match 'options', except that it also needs + * {Backbone.Relation|String} type ('HasOne' or 'HasMany'). + */ + Backbone.Relation = function( instance, options ) { + this.instance = instance; + // Make sure 'options' is sane, and fill with defaults from subclasses and this object's prototype + options = _.isObject( options ) ? options : {}; + this.reverseRelation = _.defaults( options.reverseRelation || {}, this.options.reverseRelation ); + this.reverseRelation.type = !_.isString( this.reverseRelation.type ) ? this.reverseRelation.type : + Backbone[ this.reverseRelation.type ] || Backbone.Relational.store.getObjectByName( this.reverseRelation.type ); + this.model = options.model || this.instance.constructor; + this.options = _.defaults( options, this.options, Backbone.Relation.prototype.options ); + + this.key = this.options.key; + this.keySource = this.options.keySource || this.key; + this.keyDestination = this.options.keyDestination || this.keySource || this.key; + + // 'exports' should be the global object where 'relatedModel' can be found on if given as a string. + this.relatedModel = this.options.relatedModel; + if ( _.isString( this.relatedModel ) ) { + this.relatedModel = Backbone.Relational.store.getObjectByName( this.relatedModel ); + } + + if ( !this.checkPreconditions() ) { + return false; + } + + if ( instance ) { + this.keyContents = this.instance.get( this.keySource ); + + // Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'. + if ( this.key !== this.keySource ) { + this.instance.unset( this.keySource, { silent: true } ); + } + + // Add this Relation to instance._relations + this.instance._relations.push( this ); + } + + // Add the reverse relation on 'relatedModel' to the store's reverseRelations + if ( !this.options.isAutoRelation && this.reverseRelation.type && this.reverseRelation.key ) { + Backbone.Relational.store.addReverseRelation( _.defaults( { + isAutoRelation: true, + model: this.relatedModel, + relatedModel: this.model, + reverseRelation: this.options // current relation is the 'reverseRelation' for it's own reverseRelation + }, + this.reverseRelation // Take further properties from this.reverseRelation (type, key, etc.) + ) ); + } + + _.bindAll( this, '_modelRemovedFromCollection', '_relatedModelAdded', '_relatedModelRemoved' ); + + if ( instance ) { + this.initialize(); + + // When a model in the store is destroyed, check if it is 'this.instance'. + Backbone.Relational.store.getCollection( this.instance ) + .bind( 'relational:remove', this._modelRemovedFromCollection ); + + // When 'relatedModel' are created or destroyed, check if it affects this relation. + Backbone.Relational.store.getCollection( this.relatedModel ) + .bind( 'relational:add', this._relatedModelAdded ) + .bind( 'relational:remove', this._relatedModelRemoved ); + } + }; + // Fix inheritance :\ + Backbone.Relation.extend = Backbone.Model.extend; + // Set up all inheritable **Backbone.Relation** properties and methods. + _.extend( Backbone.Relation.prototype, Backbone.Events, Backbone.Semaphore, { + options: { + createModels: true, + includeInJSON: true, + isAutoRelation: false + }, + + instance: null, + key: null, + keyContents: null, + relatedModel: null, + reverseRelation: null, + related: null, + + _relatedModelAdded: function( model, coll, options ) { + // Allow 'model' to set up it's relations, before calling 'tryAddRelated' + // (which can result in a call to 'addRelated' on a relation of 'model') + var dit = this; + model.queue( function() { + dit.tryAddRelated( model, options ); + }); + }, + + _relatedModelRemoved: function( model, coll, options ) { + this.removeRelated( model, options ); + }, + + _modelRemovedFromCollection: function( model ) { + if ( model === this.instance ) { + this.destroy(); + } + }, + + /** + * Check several pre-conditions. + * @return {Boolean} True if pre-conditions are satisfied, false if they're not. + */ + checkPreconditions: function() { + var i = this.instance, + k = this.key, + m = this.model, + rm = this.relatedModel, + warn = Backbone.Relational.showWarnings && typeof console !== 'undefined'; + + if ( !m || !k || !rm ) { + warn && console.warn( 'Relation=%o; no model, key or relatedModel (%o, %o, %o)', this, m, k, rm ); + return false; + } + // Check if the type in 'model' inherits from Backbone.RelationalModel + if ( !( m.prototype instanceof Backbone.RelationalModel ) ) { + warn && console.warn( 'Relation=%o; model does not inherit from Backbone.RelationalModel (%o)', this, i ); + return false; + } + // Check if the type in 'relatedModel' inherits from Backbone.RelationalModel + if ( !( rm.prototype instanceof Backbone.RelationalModel ) ) { + warn && console.warn( 'Relation=%o; relatedModel does not inherit from Backbone.RelationalModel (%o)', this, rm ); + return false; + } + // Check if this is not a HasMany, and the reverse relation is HasMany as well + if ( this instanceof Backbone.HasMany && this.reverseRelation.type === Backbone.HasMany ) { + warn && console.warn( 'Relation=%o; relation is a HasMany, and the reverseRelation is HasMany as well.', this ); + return false; + } + + // Check if we're not attempting to create a duplicate relationship + if ( i && i._relations.length ) { + var exists = _.any( i._relations, function( rel ) { + var hasReverseRelation = this.reverseRelation.key && rel.reverseRelation.key; + return rel.relatedModel === rm && rel.key === k && + ( !hasReverseRelation || this.reverseRelation.key === rel.reverseRelation.key ); + }, this ); + + if ( exists ) { + warn && console.warn( 'Relation=%o between instance=%o.%s and relatedModel=%o.%s already exists', + this, i, k, rm, this.reverseRelation.key ); + return false; + } + } + + return true; + }, + + /** + * Set the related model(s) for this relation + * @param {Backbone.Mode|Backbone.Collection} related + * @param {Object} [options] + */ + setRelated: function( related, options ) { + this.related = related; + + this.instance.acquire(); + this.instance.set( this.key, related, _.defaults( options || {}, { silent: true } ) ); + this.instance.release(); + }, + + /** + * Determine if a relation (on a different RelationalModel) is the reverse + * relation of the current one. + * @param {Backbone.Relation} relation + * @return {Boolean} + */ + _isReverseRelation: function( relation ) { + if ( relation.instance instanceof this.relatedModel && this.reverseRelation.key === relation.key && + this.key === relation.reverseRelation.key ) { + return true; + } + return false; + }, + + /** + * Get the reverse relations (pointing back to 'this.key' on 'this.instance') for the currently related model(s). + * @param {Backbone.RelationalModel} [model] Get the reverse relations for a specific model. + * If not specified, 'this.related' is used. + * @return {Backbone.Relation[]} + */ + getReverseRelations: function( model ) { + var reverseRelations = []; + // Iterate over 'model', 'this.related.models' (if this.related is a Backbone.Collection), or wrap 'this.related' in an array. + var models = !_.isUndefined( model ) ? [ model ] : this.related && ( this.related.models || [ this.related ] ); + _.each( models , function( related ) { + _.each( related.getRelations(), function( relation ) { + if ( this._isReverseRelation( relation ) ) { + reverseRelations.push( relation ); + } + }, this ); + }, this ); + + return reverseRelations; + }, + + /** + * Rename options.silent to options.silentChange, so events propagate properly. + * (for example in HasMany, from 'addRelated'->'handleAddition') + * @param {Object} [options] + * @return {Object} + */ + sanitizeOptions: function( options ) { + options = options ? _.clone( options ) : {}; + if ( options.silent ) { + options.silentChange = true; + delete options.silent; + } + return options; + }, + + /** + * Rename options.silentChange to options.silent, so events are silenced as intended in Backbone's + * original functions. + * @param {Object} [options] + * @return {Object} + */ + unsanitizeOptions: function( options ) { + options = options ? _.clone( options ) : {}; + if ( options.silentChange ) { + options.silent = true; + delete options.silentChange; + } + return options; + }, + + // Cleanup. Get reverse relation, call removeRelated on each. + destroy: function() { + Backbone.Relational.store.getCollection( this.instance ) + .unbind( 'relational:remove', this._modelRemovedFromCollection ); + + Backbone.Relational.store.getCollection( this.relatedModel ) + .unbind( 'relational:add', this._relatedModelAdded ) + .unbind( 'relational:remove', this._relatedModelRemoved ); + + _.each( this.getReverseRelations(), function( relation ) { + relation.removeRelated( this.instance ); + }, this ); + } + }); + + Backbone.HasOne = Backbone.Relation.extend({ + options: { + reverseRelation: { type: 'HasMany' } + }, + + initialize: function() { + _.bindAll( this, 'onChange' ); + + this.instance.bind( 'relational:change:' + this.key, this.onChange ); + + var model = this.findRelated( { silent: true } ); + this.setRelated( model ); + + // Notify new 'related' object of the new relation. + _.each( this.getReverseRelations(), function( relation ) { + relation.addRelated( this.instance ); + }, this ); + }, + + findRelated: function( options ) { + var item = this.keyContents; + var model = null; + + if ( item instanceof this.relatedModel ) { + model = item; + } + else if ( item || item === 0 ) { // since 0 can be a valid `id` as well + model = this.relatedModel.findOrCreate( item, { create: this.options.createModels } ); + } + + return model; + }, + + /** + * If the key is changed, notify old & new reverse relations and initialize the new relation + */ + onChange: function( model, attr, options ) { + // Don't accept recursive calls to onChange (like onChange->findRelated->findOrCreate->initializeRelations->addRelated->onChange) + if ( this.isLocked() ) { + return; + } + this.acquire(); + options = this.sanitizeOptions( options ); + + // 'options._related' is set by 'addRelated'/'removeRelated'. If it is set, the change + // is the result of a call from a relation. If it's not, the change is the result of + // a 'set' call on this.instance. + var changed = _.isUndefined( options._related ); + var oldRelated = changed ? this.related : options._related; + + if ( changed ) { + this.keyContents = attr; + + // Set new 'related' + if ( attr instanceof this.relatedModel ) { + this.related = attr; + } + else if ( attr ) { + var related = this.findRelated( options ); + this.setRelated( related ); + } + else { + this.setRelated( null ); + } + } + + // Notify old 'related' object of the terminated relation + if ( oldRelated && this.related !== oldRelated ) { + _.each( this.getReverseRelations( oldRelated ), function( relation ) { + relation.removeRelated( this.instance, options ); + }, this ); + } + + // Notify new 'related' object of the new relation. Note we do re-apply even if this.related is oldRelated; + // that can be necessary for bi-directional relations if 'this.instance' was created after 'this.related'. + // In that case, 'this.instance' will already know 'this.related', but the reverse might not exist yet. + _.each( this.getReverseRelations(), function( relation ) { + relation.addRelated( this.instance, options ); + }, this); + + // Fire the 'update:<key>' event if 'related' was updated + if ( !options.silentChange && this.related !== oldRelated ) { + var dit = this; + Backbone.Relational.eventQueue.add( function() { + dit.instance.trigger( 'update:' + dit.key, dit.instance, dit.related, options ); + }); + } + this.release(); + }, + + /** + * If a new 'this.relatedModel' appears in the 'store', try to match it to the last set 'keyContents' + */ + tryAddRelated: function( model, options ) { + if ( this.related ) { + return; + } + options = this.sanitizeOptions( options ); + + var item = this.keyContents; + if ( item || item === 0 ) { // since 0 can be a valid `id` as well + var id = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item ); + if ( !_.isNull( id ) && model.id === id ) { + this.addRelated( model, options ); + } + } + }, + + addRelated: function( model, options ) { + if ( model !== this.related ) { + var oldRelated = this.related || null; + this.setRelated( model ); + this.onChange( this.instance, model, { _related: oldRelated } ); + } + }, + + removeRelated: function( model, options ) { + if ( !this.related ) { + return; + } + + if ( model === this.related ) { + var oldRelated = this.related || null; + this.setRelated( null ); + this.onChange( this.instance, model, { _related: oldRelated } ); + } + } + }); + + Backbone.HasMany = Backbone.Relation.extend({ + collectionType: null, + + options: { + reverseRelation: { type: 'HasOne' }, + collectionType: Backbone.Collection, + collectionKey: true, + collectionOptions: {} + }, + + initialize: function() { + _.bindAll( this, 'onChange', 'handleAddition', 'handleRemoval', 'handleReset' ); + this.instance.bind( 'relational:change:' + this.key, this.onChange ); + + // Handle a custom 'collectionType' + this.collectionType = this.options.collectionType; + if ( _.isString( this.collectionType ) ) { + this.collectionType = Backbone.Relational.store.getObjectByName( this.collectionType ); + } + if ( !this.collectionType.prototype instanceof Backbone.Collection ){ + throw new Error( 'collectionType must inherit from Backbone.Collection' ); + } + + // Handle cases where a model/relation is created with a collection passed straight into 'attributes' + if ( this.keyContents instanceof Backbone.Collection ) { + this.setRelated( this._prepareCollection( this.keyContents ) ); + } + else { + this.setRelated( this._prepareCollection() ); + } + + this.findRelated( { silent: true } ); + }, + + _getCollectionOptions: function() { + return _.isFunction( this.options.collectionOptions ) ? + this.options.collectionOptions( this.instance ) : + this.options.collectionOptions; + }, + + /** + * Bind events and setup collectionKeys for a collection that is to be used as the backing store for a HasMany. + * If no 'collection' is supplied, a new collection will be created of the specified 'collectionType' option. + * @param {Backbone.Collection} [collection] + */ + _prepareCollection: function( collection ) { + if ( this.related ) { + this.related + .unbind( 'relational:add', this.handleAddition ) + .unbind( 'relational:remove', this.handleRemoval ) + .unbind( 'relational:reset', this.handleReset ) + } + + if ( !collection || !( collection instanceof Backbone.Collection ) ) { + collection = new this.collectionType( [], this._getCollectionOptions() ); + } + + collection.model = this.relatedModel; + + if ( this.options.collectionKey ) { + var key = this.options.collectionKey === true ? this.options.reverseRelation.key : this.options.collectionKey; + + if ( collection[ key ] && collection[ key ] !== this.instance ) { + if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) { + console.warn( 'Relation=%o; collectionKey=%s already exists on collection=%o', this, key, this.options.collectionKey ); + } + } + else if ( key ) { + collection[ key ] = this.instance; + } + } + + collection + .bind( 'relational:add', this.handleAddition ) + .bind( 'relational:remove', this.handleRemoval ) + .bind( 'relational:reset', this.handleReset ); + + return collection; + }, + + findRelated: function( options ) { + if ( this.keyContents ) { + var models = []; + + if ( this.keyContents instanceof Backbone.Collection ) { + models = this.keyContents.models; + } + else { + // Handle cases the an API/user supplies just an Object/id instead of an Array + this.keyContents = _.isArray( this.keyContents ) ? this.keyContents : [ this.keyContents ]; + + // Try to find instances of the appropriate 'relatedModel' in the store + _.each( this.keyContents, function( item ) { + var model = null; + if ( item instanceof this.relatedModel ) { + model = item; + } + else if ( item || item === 0 ) { // since 0 can be a valid `id` as well + model = this.relatedModel.findOrCreate( item, { create: this.options.createModels } ); + } + + if ( model && !this.related.getByCid( model ) && !this.related.get( model ) ) { + models.push( model ); + } + }, this ); + } + + // Add all found 'models' in on go, so 'add' will only be called once (and thus 'sort', etc.) + if ( models.length ) { + options = this.unsanitizeOptions( options ); + this.related.add( models, options ); + } + } + }, + + /** + * If the key is changed, notify old & new reverse relations and initialize the new relation + */ + onChange: function( model, attr, options ) { + options = this.sanitizeOptions( options ); + this.keyContents = attr; + + // Notify old 'related' object of the terminated relation + _.each( this.getReverseRelations(), function( relation ) { + relation.removeRelated( this.instance, options ); + }, this ); + + // Replace 'this.related' by 'attr' if it is a Backbone.Collection + if ( attr instanceof Backbone.Collection ) { + this._prepareCollection( attr ); + this.related = attr; + } + // Otherwise, 'attr' should be an array of related object ids. + // Re-use the current 'this.related' if it is a Backbone.Collection, and remove any current entries. + // Otherwise, create a new collection. + else { + var coll; + + if ( this.related instanceof Backbone.Collection ) { + coll = this.related; + coll.remove( coll.models ); + } + else { + coll = this._prepareCollection(); + } + + this.setRelated( coll ); + this.findRelated( options ); + } + + // Notify new 'related' object of the new relation + _.each( this.getReverseRelations(), function( relation ) { + relation.addRelated( this.instance, options ); + }, this ); + + var dit = this; + Backbone.Relational.eventQueue.add( function() { + !options.silentChange && dit.instance.trigger( 'update:' + dit.key, dit.instance, dit.related, options ); + }); + }, + + tryAddRelated: function( model, options ) { + options = this.sanitizeOptions( options ); + if ( !this.related.getByCid( model ) && !this.related.get( model ) ) { + // Check if this new model was specified in 'this.keyContents' + var item = _.any( this.keyContents, function( item ) { + var id = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item ); + return !_.isNull( id ) && id === model.id; + }, this ); + + if ( item ) { + this.related.add( model, options ); + } + } + }, + + /** + * When a model is added to a 'HasMany', trigger 'add' on 'this.instance' and notify reverse relations. + * (should be 'HasOne', must set 'this.instance' as their related). + */ + handleAddition: function( model, coll, options ) { + //console.debug('handleAddition called; args=%o', arguments); + // Make sure the model is in fact a valid model before continuing. + // (it can be invalid as a result of failing validation in Backbone.Collection._prepareModel) + if ( !( model instanceof Backbone.Model ) ) { + return; + } + + options = this.sanitizeOptions( options ); + + _.each( this.getReverseRelations( model ), function( relation ) { + relation.addRelated( this.instance, options ); + }, this ); + + // Only trigger 'add' once the newly added model is initialized (so, has it's relations set up) + var dit = this; + Backbone.Relational.eventQueue.add( function() { + !options.silentChange && dit.instance.trigger( 'add:' + dit.key, model, dit.related, options ); + }); + }, + + /** + * When a model is removed from a 'HasMany', trigger 'remove' on 'this.instance' and notify reverse relations. + * (should be 'HasOne', which should be nullified) + */ + handleRemoval: function( model, coll, options ) { + //console.debug('handleRemoval called; args=%o', arguments); + if ( !( model instanceof Backbone.Model ) ) { + return; + } + + options = this.sanitizeOptions( options ); + + _.each( this.getReverseRelations( model ), function( relation ) { + relation.removeRelated( this.instance, options ); + }, this ); + + var dit = this; + Backbone.Relational.eventQueue.add( function() { + !options.silentChange && dit.instance.trigger( 'remove:' + dit.key, model, dit.related, options ); + }); + }, + + handleReset: function( coll, options ) { + options = this.sanitizeOptions( options ); + + var dit = this; + Backbone.Relational.eventQueue.add( function() { + !options.silentChange && dit.instance.trigger( 'reset:' + dit.key, dit.related, options ); + }); + }, + + addRelated: function( model, options ) { + var dit = this; + options = this.unsanitizeOptions( options ); + model.queue( function() { // Queued to avoid errors for adding 'model' to the 'this.related' set twice + if ( dit.related && !dit.related.getByCid( model ) && !dit.related.get( model ) ) { + dit.related.add( model, options ); + } + }); + }, + + removeRelated: function( model, options ) { + options = this.unsanitizeOptions( options ); + if ( this.related.getByCid( model ) || this.related.get( model ) ) { + this.related.remove( model, options ); + } + } + }); + + /** + * A type of Backbone.Model that also maintains relations to other models and collections. + * New events when compared to the original: + * - 'add:<key>' (model, related collection, options) + * - 'remove:<key>' (model, related collection, options) + * - 'update:<key>' (model, related model or collection, options) + */ + Backbone.RelationalModel = Backbone.Model.extend({ + relations: null, // Relation descriptions on the prototype + _relations: null, // Relation instances + _isInitialized: false, + _deferProcessing: false, + _queue: null, + + subModelTypeAttribute: 'type', + subModelTypes: null, + + constructor: function( attributes, options ) { + // Nasty hack, for cases like 'model.get( <HasMany key> ).add( item )'. + // Defer 'processQueue', so that when 'Relation.createModels' is used we: + // a) Survive 'Backbone.Collection.add'; this takes care we won't error on "can't add model to a set twice" + // (by creating a model from properties, having the model add itself to the collection via one of + // it's relations, then trying to add it to the collection). + // b) Trigger 'HasMany' collection events only after the model is really fully set up. + // Example that triggers both a and b: "p.get('jobs').add( { company: c, person: p } )". + var dit = this; + if ( options && options.collection ) { + this._deferProcessing = true; + + var processQueue = function( model ) { + if ( model === dit ) { + dit._deferProcessing = false; + dit.processQueue(); + options.collection.unbind( 'relational:add', processQueue ); + } + }; + options.collection.bind( 'relational:add', processQueue ); + + // So we do process the queue eventually, regardless of whether this model really gets added to 'options.collection'. + _.defer( function() { + processQueue( dit ); + }); + } + + this._queue = new Backbone.BlockingQueue(); + this._queue.block(); + Backbone.Relational.eventQueue.block(); + + Backbone.Model.apply( this, arguments ); + + // Try to run the global queue holding external events + Backbone.Relational.eventQueue.unblock(); + }, + + /** + * Override 'trigger' to queue 'change' and 'change:*' events + */ + trigger: function( eventName ) { + if ( eventName.length > 5 && 'change' === eventName.substr( 0, 6 ) ) { + var dit = this, args = arguments; + Backbone.Relational.eventQueue.add( function() { + Backbone.Model.prototype.trigger.apply( dit, args ); + }); + } + else { + Backbone.Model.prototype.trigger.apply( this, arguments ); + } + + return this; + }, + + /** + * Initialize Relations present in this.relations; determine the type (HasOne/HasMany), then creates a new instance. + * Invoked in the first call so 'set' (which is made from the Backbone.Model constructor). + */ + initializeRelations: function() { + this.acquire(); // Setting up relations often also involve calls to 'set', and we only want to enter this function once + this._relations = []; + + _.each( this.relations, function( rel ) { + var type = !_.isString( rel.type ) ? rel.type : Backbone[ rel.type ] || Backbone.Relational.store.getObjectByName( rel.type ); + if ( type && type.prototype instanceof Backbone.Relation ) { + new type( this, rel ); // Also pushes the new Relation into _relations + } + else { + Backbone.Relational.showWarnings && typeof console !== 'undefined' && console.warn( 'Relation=%o; missing or invalid type!', rel ); + } + }, this ); + + this._isInitialized = true; + this.release(); + this.processQueue(); + }, + + /** + * When new values are set, notify this model's relations (also if options.silent is set). + * (Relation.setRelated locks this model before calling 'set' on it to prevent loops) + */ + updateRelations: function( options ) { + if ( this._isInitialized && !this.isLocked() ) { + _.each( this._relations, function( rel ) { + // Update from data in `rel.keySource` if set, or `rel.key` otherwise + var val = this.attributes[ rel.keySource ] || this.attributes[ rel.key ]; + if ( rel.related !== val ) { + this.trigger( 'relational:change:' + rel.key, this, val, options || {} ); + } + }, this ); + } + }, + + /** + * Either add to the queue (if we're not initialized yet), or execute right away. + */ + queue: function( func ) { + this._queue.add( func ); + }, + + /** + * Process _queue + */ + processQueue: function() { + if ( this._isInitialized && !this._deferProcessing && this._queue.isBlocked() ) { + this._queue.unblock(); + } + }, + + /** + * Get a specific relation. + * @param key {string} The relation key to look for. + * @return {Backbone.Relation} An instance of 'Backbone.Relation', if a relation was found for 'key', or null. + */ + getRelation: function( key ) { + return _.detect( this._relations, function( rel ) { + if ( rel.key === key ) { + return true; + } + }, this ); + }, + + /** + * Get all of the created relations. + * @return {Backbone.Relation[]} + */ + getRelations: function() { + return this._relations; + }, + + /** + * Retrieve related objects. + * @param key {string} The relation key to fetch models for. + * @param [options] {Object} Options for 'Backbone.Model.fetch' and 'Backbone.sync'. + * @param [update=false] {boolean} Whether to force a fetch from the server (updating existing models). + * @return {jQuery.when[]} An array of request objects + */ + fetchRelated: function( key, options, update ) { + options || ( options = {} ); + var setUrl, + requests = [], + rel = this.getRelation( key ), + keyContents = rel && rel.keyContents, + toFetch = keyContents && _.select( _.isArray( keyContents ) ? keyContents : [ keyContents ], function( item ) { + var id = Backbone.Relational.store.resolveIdForItem( rel.relatedModel, item ); + return !_.isNull( id ) && ( update || !Backbone.Relational.store.find( rel.relatedModel, id ) ); + }, this ); + + if ( toFetch && toFetch.length ) { + // Create a model for each entry in 'keyContents' that is to be fetched + var models = _.map( toFetch, function( item ) { + var model; + + if ( _.isObject( item ) ) { + model = rel.relatedModel.build( item ); + } + else { + var attrs = {}; + attrs[ rel.relatedModel.prototype.idAttribute ] = item; + model = rel.relatedModel.build( attrs ); + } + + return model; + }, this ); + + // Try if the 'collection' can provide a url to fetch a set of models in one request. + if ( rel.related instanceof Backbone.Collection && _.isFunction( rel.related.url ) ) { + setUrl = rel.related.url( models ); + } + + // An assumption is that when 'Backbone.Collection.url' is a function, it can handle building of set urls. + // To make sure it can, test if the url we got by supplying a list of models to fetch is different from + // the one supplied for the default fetch action (without args to 'url'). + if ( setUrl && setUrl !== rel.related.url() ) { + var opts = _.defaults( + { + error: function() { + var args = arguments; + _.each( models, function( model ) { + model.trigger( 'destroy', model, model.collection, options ); + options.error && options.error.apply( model, args ); + }); + }, + url: setUrl + }, + options, + { add: true } + ); + + requests = [ rel.related.fetch( opts ) ]; + } + else { + requests = _.map( models, function( model ) { + var opts = _.defaults( + { + error: function() { + model.trigger( 'destroy', model, model.collection, options ); + options.error && options.error.apply( model, arguments ); + } + }, + options + ); + return model.fetch( opts ); + }, this ); + } + } + + return requests; + }, + + set: function( key, value, options ) { + Backbone.Relational.eventQueue.block(); + + // Duplicate backbone's behavior to allow separate key/value parameters, instead of a single 'attributes' object + var attributes; + if ( _.isObject( key ) || key == null ) { + attributes = key; + options = value; + } + else { + attributes = {}; + attributes[ key ] = value; + } + + var result = Backbone.Model.prototype.set.apply( this, arguments ); + + // Ideal place to set up relations :) + if ( !this._isInitialized && !this.isLocked() ) { + this.constructor.initializeModelHierarchy(); + + Backbone.Relational.store.register( this ); + + this.initializeRelations(); + } + // Update the 'idAttribute' in Backbone.store if; we don't want it to miss an 'id' update due to {silent:true} + else if ( attributes && this.idAttribute in attributes ) { + Backbone.Relational.store.update( this ); + } + + if ( attributes ) { + this.updateRelations( options ); + } + + // Try to run the global queue holding external events + Backbone.Relational.eventQueue.unblock(); + + return result; + }, + + unset: function( attribute, options ) { + Backbone.Relational.eventQueue.block(); + + var result = Backbone.Model.prototype.unset.apply( this, arguments ); + this.updateRelations( options ); + + // Try to run the global queue holding external events + Backbone.Relational.eventQueue.unblock(); + + return result; + }, + + clear: function( options ) { + Backbone.Relational.eventQueue.block(); + + var result = Backbone.Model.prototype.clear.apply( this, arguments ); + this.updateRelations( options ); + + // Try to run the global queue holding external events + Backbone.Relational.eventQueue.unblock(); + + return result; + }, + + /** + * Override 'change', so the change will only execute after 'set' has finised (relations are updated), + * and 'previousAttributes' will be available when the event is fired. + */ + change: function( options ) { + var dit = this, args = arguments; + Backbone.Relational.eventQueue.add( function() { + Backbone.Model.prototype.change.apply( dit, args ); + }); + }, + + clone: function() { + var attributes = _.clone( this.attributes ); + if ( !_.isUndefined( attributes[ this.idAttribute ] ) ) { + attributes[ this.idAttribute ] = null; + } + + _.each( this.getRelations(), function( rel ) { + delete attributes[ rel.key ]; + }); + + return new this.constructor( attributes ); + }, + + /** + * Convert relations to JSON, omits them when required + */ + toJSON: function() { + // If this Model has already been fully serialized in this branch once, return to avoid loops + if ( this.isLocked() ) { + return this.id; + } + + this.acquire(); + var json = Backbone.Model.prototype.toJSON.call( this ); + + if ( this.constructor._superModel && !( this.constructor._subModelTypeAttribute in json ) ) { + json[ this.constructor._subModelTypeAttribute ] = this.constructor._subModelTypeValue; + } + + _.each( this._relations, function( rel ) { + var value = json[ rel.key ]; + + if ( rel.options.includeInJSON === true) { + if ( value && _.isFunction( value.toJSON ) ) { + json[ rel.keyDestination ] = value.toJSON(); + } + else { + json[ rel.keyDestination ] = null; + } + } + else if ( _.isString( rel.options.includeInJSON ) ) { + if ( value instanceof Backbone.Collection ) { + json[ rel.keyDestination ] = value.pluck( rel.options.includeInJSON ); + } + else if ( value instanceof Backbone.Model ) { + json[ rel.keyDestination ] = value.get( rel.options.includeInJSON ); + } + else { + json[ rel.keyDestination ] = null; + } + } + else if ( _.isArray( rel.options.includeInJSON ) ) { + if ( value instanceof Backbone.Collection ) { + var valueSub = []; + value.each( function( model ) { + var curJson = {}; + _.each( rel.options.includeInJSON, function( key ) { + curJson[ key ] = model.get( key ); + }); + valueSub.push( curJson ); + }); + json[ rel.keyDestination ] = valueSub; + } + else if ( value instanceof Backbone.Model ) { + var valueSub = {}; + _.each( rel.options.includeInJSON, function( key ) { + valueSub[ key ] = value.get( key ); + }); + json[ rel.keyDestination ] = valueSub; + } + else { + json[ rel.keyDestination ] = null; + } + } + else { + delete json[ rel.key ]; + } + + if ( rel.keyDestination !== rel.key ) { + delete json[ rel.key ]; + } + }); + + this.release(); + return json; + } + }, + { + setup: function( superModel ) { + // We don't want to share a relations array with a parent, as this will cause problems with + // reverse relations. + this.prototype.relations = ( this.prototype.relations || [] ).slice( 0 ); + + this._subModels = {}; + this._superModel = null; + + // If this model has 'subModelTypes' itself, remember them in the store + if ( this.prototype.hasOwnProperty( 'subModelTypes' ) ) { + Backbone.Relational.store.addSubModels( this.prototype.subModelTypes, this ); + } + // The 'subModelTypes' property should not be inherited, so reset it. + else { + this.prototype.subModelTypes = null; + } + + // Initialize all reverseRelations that belong to this new model. + _.each( this.prototype.relations, function( rel ) { + if ( !rel.model ) { + rel.model = this; + } + + if ( rel.reverseRelation && rel.model === this ) { + var preInitialize = true; + if ( _.isString( rel.relatedModel ) ) { + /** + * The related model might not be defined for two reasons + * 1. it never gets defined, e.g. a typo + * 2. it is related to itself + * In neither of these cases do we need to pre-initialize reverse relations. + */ + var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel ); + preInitialize = relatedModel && ( relatedModel.prototype instanceof Backbone.RelationalModel ); + } + + var type = !_.isString( rel.type ) ? rel.type : Backbone[ rel.type ] || Backbone.Relational.store.getObjectByName( rel.type ); + if ( preInitialize && type && type.prototype instanceof Backbone.Relation ) { + new type( null, rel ); + } + } + }, this ); + + return this; + }, + + /** + * Create a 'Backbone.Model' instance based on 'attributes'. + * @param {Object} attributes + * @param {Object} [options] + * @return {Backbone.Model} + */ + build: function( attributes, options ) { + var model = this; + + // 'build' is a possible entrypoint; it's possible no model hierarchy has been determined yet. + this.initializeModelHierarchy(); + + // Determine what type of (sub)model should be built if applicable. + // Lookup the proper subModelType in 'this._subModels'. + if ( this._subModels && this.prototype.subModelTypeAttribute in attributes ) { + var subModelTypeAttribute = attributes[ this.prototype.subModelTypeAttribute ]; + var subModelType = this._subModels[ subModelTypeAttribute ]; + if ( subModelType ) { + model = subModelType; + } + } + + return new model( attributes, options ); + }, + + initializeModelHierarchy: function() { + // If we're here for the first time, try to determine if this modelType has a 'superModel'. + if ( _.isUndefined( this._superModel ) || _.isNull( this._superModel ) ) { + Backbone.Relational.store.setupSuperModel( this ); + + // If a superModel has been found, copy relations from the _superModel if they haven't been + // inherited automatically (due to a redefinition of 'relations'). + // Otherwise, make sure we don't get here again for this type by making '_superModel' false so we fail + // the isUndefined/isNull check next time. + if ( this._superModel ) { + // + if ( this._superModel.prototype.relations ) { + var supermodelRelationsExist = _.any( this.prototype.relations, function( rel ) { + return rel.model && rel.model !== this; + }, this ); + + if ( !supermodelRelationsExist ) { + this.prototype.relations = this._superModel.prototype.relations.concat( this.prototype.relations ); + } + } + } + else { + this._superModel = false; + } + } + + // If we came here through 'build' for a model that has 'subModelTypes', and not all of them have been resolved yet, try to resolve each. + if ( this.prototype.subModelTypes && _.keys( this.prototype.subModelTypes ).length !== _.keys( this._subModels ).length ) { + _.each( this.prototype.subModelTypes, function( subModelTypeName ) { + var subModelType = Backbone.Relational.store.getObjectByName( subModelTypeName ); + subModelType && subModelType.initializeModelHierarchy(); + }); + } + }, + + /** + * Find an instance of `this` type in 'Backbone.Relational.store'. + * - If `attributes` is a string or a number, `findOrCreate` will just query the `store` and return a model if found. + * - If `attributes` is an object, the model will be updated with `attributes` if found. + * Otherwise, a new model is created with `attributes` (unless `options.create` is explicitly set to `false`). + * @param {Object|String|Number} attributes Either a model's id, or the attributes used to create or update a model. + * @param {Object} [options] + * @param {Boolean} [options.create=true] + * @return {Backbone.RelationalModel} + */ + findOrCreate: function( attributes, options ) { + // Try to find an instance of 'this' model type in the store + var model = Backbone.Relational.store.find( this, attributes ); + + // If we found an instance, update it with the data in 'item'; if not, create an instance + // (unless 'options.create' is false). + if ( _.isObject( attributes ) ) { + if ( model ) { + model.set( model.parse ? model.parse( attributes ) : attributes, options ); + } + else if ( !options || ( options && options.create !== false ) ) { + model = this.build( attributes, options ); + } + } + + return model; + } + }); + _.extend( Backbone.RelationalModel.prototype, Backbone.Semaphore ); + + /** + * Override Backbone.Collection._prepareModel, so objects will be built using the correct type + * if the collection.model has subModels. + */ + Backbone.Collection.prototype.__prepareModel = Backbone.Collection.prototype._prepareModel; + Backbone.Collection.prototype._prepareModel = function ( model, options ) { + options || (options = {}); + if ( !( model instanceof Backbone.Model ) ) { + var attrs = model; + options.collection = this; + + if ( typeof this.model.findOrCreate !== 'undefined' ) { + model = this.model.findOrCreate( attrs, options ); + } + else { + model = new this.model( attrs, options ); + } + + if ( !model._validate( model.attributes, options ) ) { + model = false; + } + } + else if ( !model.collection ) { + model.collection = this; + } + + return model; + } + + /** + * Override Backbone.Collection.add, so objects fetched from the server multiple times will + * update the existing Model. Also, trigger 'relational:add'. + */ + var add = Backbone.Collection.prototype.__add = Backbone.Collection.prototype.add; + Backbone.Collection.prototype.add = function( models, options ) { + options || (options = {}); + if ( !_.isArray( models ) ) { + models = [ models ]; + } + + var modelsToAdd = []; + + //console.debug( 'calling add on coll=%o; model=%o, options=%o', this, models, options ); + _.each( models, function( model ) { + if ( !( model instanceof Backbone.Model ) ) { + // `_prepareModel` attempts to find `model` in Backbone.store through `findOrCreate`, + // and sets the new properties on it if is found. Otherwise, a new model is instantiated. + model = Backbone.Collection.prototype._prepareModel.call( this, model, options ); + } + + if ( model instanceof Backbone.Model && !this.get( model ) && !this.getByCid( model ) ) { + modelsToAdd.push( model ); + } + }, this ); + + + // Add 'models' in a single batch, so the original add will only be called once (and thus 'sort', etc). + if ( modelsToAdd.length ) { + add.call( this, modelsToAdd, options ); + + _.each( modelsToAdd, function( model ) { + this.trigger( 'relational:add', model, this, options ); + }, this ); + } + + return this; + }; + + /** + * Override 'Backbone.Collection.remove' to trigger 'relational:remove'. + */ + var remove = Backbone.Collection.prototype.__remove = Backbone.Collection.prototype.remove; + Backbone.Collection.prototype.remove = function( models, options ) { + options || (options = {}); + if ( !_.isArray( models ) ) { + models = [ models ]; + } + else { + models = models.slice( 0 ); + } + + //console.debug('calling remove on coll=%o; models=%o, options=%o', this, models, options ); + _.each( models, function( model ) { + model = this.getByCid( model ) || this.get( model ); + + if ( model instanceof Backbone.Model ) { + remove.call( this, model, options ); + this.trigger('relational:remove', model, this, options); + } + }, this ); + + return this; + }; + + /** + * Override 'Backbone.Collection.reset' to trigger 'relational:reset'. + */ + var reset = Backbone.Collection.prototype.__reset = Backbone.Collection.prototype.reset; + Backbone.Collection.prototype.reset = function( models, options ) { + reset.call( this, models, options ); + this.trigger( 'relational:reset', this, options ); + + return this; + }; + + /** + * Override 'Backbone.Collection.sort' to trigger 'relational:reset'. + */ + var sort = Backbone.Collection.prototype.__sort = Backbone.Collection.prototype.sort; + Backbone.Collection.prototype.sort = function( options ) { + sort.call( this, options ); + this.trigger( 'relational:reset', this, options ); + + return this; + }; + + /** + * Override 'Backbone.Collection.trigger' so 'add', 'remove' and 'reset' events are queued until relations + * are ready. + */ + var trigger = Backbone.Collection.prototype.__trigger = Backbone.Collection.prototype.trigger; + Backbone.Collection.prototype.trigger = function( eventName ) { + if ( eventName === 'add' || eventName === 'remove' || eventName === 'reset' ) { + var dit = this, args = arguments; + + if (eventName === 'add') { + args = _.toArray(args); + // the fourth argument in case of a regular add is the option object. + // we need to clone it, as it could be modified while we wait on the eventQueue to be unblocked + if (_.isObject(args[3])) { + args[3] = _.clone(args[3]); + } + } + + Backbone.Relational.eventQueue.add( function() { + trigger.apply( dit, args ); + }); + } + else { + trigger.apply( this, arguments ); + } + + return this; + }; + + // Override .extend() to automatically call .setup() + Backbone.RelationalModel.extend = function( protoProps, classProps ) { + var child = Backbone.Model.extend.apply( this, arguments ); + + child.setup( this ); + + return child; + }; +})();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/js/backbone.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,1431 @@ +// Backbone.js 0.9.2 + +// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Backbone may be freely distributed under the MIT license. +// For all details and documentation: +// http://backbonejs.org + +(function(){ + + // Initial Setup + // ------------- + + // Save a reference to the global object (`window` in the browser, `global` + // on the server). + var root = this; + + // Save the previous value of the `Backbone` variable, so that it can be + // restored later on, if `noConflict` is used. + var previousBackbone = root.Backbone; + + // Create a local reference to slice/splice. + var slice = Array.prototype.slice; + var splice = Array.prototype.splice; + + // The top-level namespace. All public Backbone classes and modules will + // be attached to this. Exported for both CommonJS and the browser. + var Backbone; + if (typeof exports !== 'undefined') { + Backbone = exports; + } else { + Backbone = root.Backbone = {}; + } + + // Current version of the library. Keep in sync with `package.json`. + Backbone.VERSION = '0.9.2'; + + // Require Underscore, if we're on the server, and it's not already present. + var _ = root._; + if (!_ && (typeof require !== 'undefined')) _ = require('underscore'); + + // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable. + var $ = root.jQuery || root.Zepto || root.ender; + + // Set the JavaScript library that will be used for DOM manipulation and + // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery, + // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an + // alternate JavaScript library (or a mock library for testing your views + // outside of a browser). + Backbone.setDomLibrary = function(lib) { + $ = lib; + }; + + // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable + // to its previous owner. Returns a reference to this Backbone object. + Backbone.noConflict = function() { + root.Backbone = previousBackbone; + return this; + }; + + // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option + // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and + // set a `X-Http-Method-Override` header. + Backbone.emulateHTTP = false; + + // Turn on `emulateJSON` to support legacy servers that can't deal with direct + // `application/json` requests ... will encode the body as + // `application/x-www-form-urlencoded` instead and will send the model in a + // form param named `model`. + Backbone.emulateJSON = false; + + // Backbone.Events + // ----------------- + + // Regular expression used to split event strings + var eventSplitter = /\s+/; + + // A module that can be mixed in to *any object* in order to provide it with + // custom events. You may bind with `on` or remove with `off` callback functions + // to an event; trigger`-ing an event fires all callbacks in succession. + // + // var object = {}; + // _.extend(object, Backbone.Events); + // object.on('expand', function(){ alert('expanded'); }); + // object.trigger('expand'); + // + var Events = Backbone.Events = { + + // Bind one or more space separated events, `events`, to a `callback` + // function. Passing `"all"` will bind the callback to all events fired. + on: function(events, callback, context) { + + var calls, event, node, tail, list; + if (!callback) return this; + events = events.split(eventSplitter); + calls = this._callbacks || (this._callbacks = {}); + + // Create an immutable callback list, allowing traversal during + // modification. The tail is an empty object that will always be used + // as the next node. + while (event = events.shift()) { + list = calls[event]; + node = list ? list.tail : {}; + node.next = tail = {}; + node.context = context; + node.callback = callback; + calls[event] = {tail: tail, next: list ? list.next : node}; + } + + return this; + }, + + // Remove one or many callbacks. If `context` is null, removes all callbacks + // with that function. If `callback` is null, removes all callbacks for the + // event. If `events` is null, removes all bound callbacks for all events. + off: function(events, callback, context) { + var event, calls, node, tail, cb, ctx; + + // No events, or removing *all* events. + if (!(calls = this._callbacks)) return; + if (!(events || callback || context)) { + delete this._callbacks; + return this; + } + + // Loop through the listed events and contexts, splicing them out of the + // linked list of callbacks if appropriate. + events = events ? events.split(eventSplitter) : _.keys(calls); + while (event = events.shift()) { + node = calls[event]; + delete calls[event]; + if (!node || !(callback || context)) continue; + // Create a new list, omitting the indicated callbacks. + tail = node.tail; + while ((node = node.next) !== tail) { + cb = node.callback; + ctx = node.context; + if ((callback && cb !== callback) || (context && ctx !== context)) { + this.on(event, cb, ctx); + } + } + } + + return this; + }, + + // Trigger one or many events, firing all bound callbacks. Callbacks are + // passed the same arguments as `trigger` is, apart from the event name + // (unless you're listening on `"all"`, which will cause your callback to + // receive the true name of the event as the first argument). + trigger: function(events) { + var event, node, calls, tail, args, all, rest; + if (!(calls = this._callbacks)) return this; + all = calls.all; + events = events.split(eventSplitter); + rest = slice.call(arguments, 1); + + // For each event, walk through the linked list of callbacks twice, + // first to trigger the event, then to trigger any `"all"` callbacks. + while (event = events.shift()) { + if (node = calls[event]) { + tail = node.tail; + while ((node = node.next) !== tail) { + node.callback.apply(node.context || this, rest); + } + } + if (node = all) { + tail = node.tail; + args = [event].concat(rest); + while ((node = node.next) !== tail) { + node.callback.apply(node.context || this, args); + } + } + } + + return this; + } + + }; + + // Aliases for backwards compatibility. + Events.bind = Events.on; + Events.unbind = Events.off; + + // Backbone.Model + // -------------- + + // Create a new model, with defined attributes. A client id (`cid`) + // is automatically generated and assigned for you. + var Model = Backbone.Model = function(attributes, options) { + var defaults; + attributes || (attributes = {}); + if (options && options.parse) attributes = this.parse(attributes); + if (defaults = getValue(this, 'defaults')) { + attributes = _.extend({}, defaults, attributes); + } + if (options && options.collection) this.collection = options.collection; + this.attributes = {}; + this._escapedAttributes = {}; + this.cid = _.uniqueId('c'); + this.changed = {}; + this._silent = {}; + this._pending = {}; + this.set(attributes, {silent: true}); + // Reset change tracking. + this.changed = {}; + this._silent = {}; + this._pending = {}; + this._previousAttributes = _.clone(this.attributes); + this.initialize.apply(this, arguments); + }; + + // Attach all inheritable methods to the Model prototype. + _.extend(Model.prototype, Events, { + + // A hash of attributes whose current and previous value differ. + changed: null, + + // A hash of attributes that have silently changed since the last time + // `change` was called. Will become pending attributes on the next call. + _silent: null, + + // A hash of attributes that have changed since the last `'change'` event + // began. + _pending: null, + + // The default name for the JSON `id` attribute is `"id"`. MongoDB and + // CouchDB users may want to set this to `"_id"`. + idAttribute: 'id', + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // Return a copy of the model's `attributes` object. + toJSON: function(options) { + return _.clone(this.attributes); + }, + + // Get the value of an attribute. + get: function(attr) { + return this.attributes[attr]; + }, + + // Get the HTML-escaped value of an attribute. + escape: function(attr) { + var html; + if (html = this._escapedAttributes[attr]) return html; + var val = this.get(attr); + return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val); + }, + + // Returns `true` if the attribute contains a value that is not null + // or undefined. + has: function(attr) { + return this.get(attr) != null; + }, + + // Set a hash of model attributes on the object, firing `"change"` unless + // you choose to silence it. + set: function(key, value, options) { + var attrs, attr, val; + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (_.isObject(key) || key == null) { + attrs = key; + options = value; + } else { + attrs = {}; + attrs[key] = value; + } + + // Extract attributes and options. + options || (options = {}); + if (!attrs) return this; + if (attrs instanceof Model) attrs = attrs.attributes; + if (options.unset) for (attr in attrs) attrs[attr] = void 0; + + // Run validation. + if (!this._validate(attrs, options)) return false; + + // Check for changes of `id`. + if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; + + var changes = options.changes = {}; + var now = this.attributes; + var escaped = this._escapedAttributes; + var prev = this._previousAttributes || {}; + + // For each `set` attribute... + for (attr in attrs) { + val = attrs[attr]; + + // If the new and current value differ, record the change. + if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) { + delete escaped[attr]; + (options.silent ? this._silent : changes)[attr] = true; + } + + // Update or delete the current value. + options.unset ? delete now[attr] : now[attr] = val; + + // If the new and previous value differ, record the change. If not, + // then remove changes for this attribute. + if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) { + this.changed[attr] = val; + if (!options.silent) this._pending[attr] = true; + } else { + delete this.changed[attr]; + delete this._pending[attr]; + } + } + + // Fire the `"change"` events. + if (!options.silent) this.change(options); + return this; + }, + + // Remove an attribute from the model, firing `"change"` unless you choose + // to silence it. `unset` is a noop if the attribute doesn't exist. + unset: function(attr, options) { + (options || (options = {})).unset = true; + return this.set(attr, null, options); + }, + + // Clear all attributes on the model, firing `"change"` unless you choose + // to silence it. + clear: function(options) { + (options || (options = {})).unset = true; + return this.set(_.clone(this.attributes), options); + }, + + // Fetch the model from the server. If the server's representation of the + // model differs from its current attributes, they will be overriden, + // triggering a `"change"` event. + fetch: function(options) { + options = options ? _.clone(options) : {}; + var model = this; + var success = options.success; + options.success = function(resp, status, xhr) { + if (!model.set(model.parse(resp, xhr), options)) return false; + if (success) success(model, resp); + }; + options.error = Backbone.wrapError(options.error, model, options); + return (this.sync || Backbone.sync).call(this, 'read', this, options); + }, + + // Set a hash of model attributes, and sync the model to the server. + // If the server returns an attributes hash that differs, the model's + // state will be `set` again. + save: function(key, value, options) { + var attrs, current; + + // Handle both `("key", value)` and `({key: value})` -style calls. + if (_.isObject(key) || key == null) { + attrs = key; + options = value; + } else { + attrs = {}; + attrs[key] = value; + } + options = options ? _.clone(options) : {}; + + // If we're "wait"-ing to set changed attributes, validate early. + if (options.wait) { + if (!this._validate(attrs, options)) return false; + current = _.clone(this.attributes); + } + + // Regular saves `set` attributes before persisting to the server. + var silentOptions = _.extend({}, options, {silent: true}); + if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) { + return false; + } + + // After a successful server-side save, the client is (optionally) + // updated with the server-side state. + var model = this; + var success = options.success; + options.success = function(resp, status, xhr) { + var serverAttrs = model.parse(resp, xhr); + if (options.wait) { + delete options.wait; + serverAttrs = _.extend(attrs || {}, serverAttrs); + } + if (!model.set(serverAttrs, options)) return false; + if (success) { + success(model, resp); + } else { + model.trigger('sync', model, resp, options); + } + }; + + // Finish configuring and sending the Ajax request. + options.error = Backbone.wrapError(options.error, model, options); + var method = this.isNew() ? 'create' : 'update'; + var xhr = (this.sync || Backbone.sync).call(this, method, this, options); + if (options.wait) this.set(current, silentOptions); + return xhr; + }, + + // Destroy this model on the server if it was already persisted. + // Optimistically removes the model from its collection, if it has one. + // If `wait: true` is passed, waits for the server to respond before removal. + destroy: function(options) { + options = options ? _.clone(options) : {}; + var model = this; + var success = options.success; + + var triggerDestroy = function() { + model.trigger('destroy', model, model.collection, options); + }; + + if (this.isNew()) { + triggerDestroy(); + return false; + } + + options.success = function(resp) { + if (options.wait) triggerDestroy(); + if (success) { + success(model, resp); + } else { + model.trigger('sync', model, resp, options); + } + }; + + options.error = Backbone.wrapError(options.error, model, options); + var xhr = (this.sync || Backbone.sync).call(this, 'delete', this, options); + if (!options.wait) triggerDestroy(); + return xhr; + }, + + // Default URL for the model's representation on the server -- if you're + // using Backbone's restful methods, override this to change the endpoint + // that will be called. + url: function() { + var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError(); + if (this.isNew()) return base; + return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id); + }, + + // **parse** converts a response into the hash of attributes to be `set` on + // the model. The default implementation is just to pass the response along. + parse: function(resp, xhr) { + return resp; + }, + + // Create a new model with identical attributes to this one. + clone: function() { + return new this.constructor(this.attributes); + }, + + // A model is new if it has never been saved to the server, and lacks an id. + isNew: function() { + return this.id == null; + }, + + // Call this method to manually fire a `"change"` event for this model and + // a `"change:attribute"` event for each changed attribute. + // Calling this will cause all objects observing the model to update. + change: function(options) { + options || (options = {}); + var changing = this._changing; + this._changing = true; + + // Silent changes become pending changes. + for (var attr in this._silent) this._pending[attr] = true; + + // Silent changes are triggered. + var changes = _.extend({}, options.changes, this._silent); + this._silent = {}; + for (var attr in changes) { + this.trigger('change:' + attr, this, this.get(attr), options); + } + if (changing) return this; + + // Continue firing `"change"` events while there are pending changes. + while (!_.isEmpty(this._pending)) { + this._pending = {}; + this.trigger('change', this, options); + // Pending and silent changes still remain. + for (var attr in this.changed) { + if (this._pending[attr] || this._silent[attr]) continue; + delete this.changed[attr]; + } + this._previousAttributes = _.clone(this.attributes); + } + + this._changing = false; + return this; + }, + + // Determine if the model has changed since the last `"change"` event. + // If you specify an attribute name, determine if that attribute has changed. + hasChanged: function(attr) { + if (!arguments.length) return !_.isEmpty(this.changed); + return _.has(this.changed, attr); + }, + + // Return an object containing all the attributes that have changed, or + // false if there are no changed attributes. Useful for determining what + // parts of a view need to be updated and/or what attributes need to be + // persisted to the server. Unset attributes will be set to undefined. + // You can also pass an attributes object to diff against the model, + // determining if there *would be* a change. + changedAttributes: function(diff) { + if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; + var val, changed = false, old = this._previousAttributes; + for (var attr in diff) { + if (_.isEqual(old[attr], (val = diff[attr]))) continue; + (changed || (changed = {}))[attr] = val; + } + return changed; + }, + + // Get the previous value of an attribute, recorded at the time the last + // `"change"` event was fired. + previous: function(attr) { + if (!arguments.length || !this._previousAttributes) return null; + return this._previousAttributes[attr]; + }, + + // Get all of the attributes of the model at the time of the previous + // `"change"` event. + previousAttributes: function() { + return _.clone(this._previousAttributes); + }, + + // Check if the model is currently in a valid state. It's only possible to + // get into an *invalid* state if you're using silent changes. + isValid: function() { + return !this.validate(this.attributes); + }, + + // Run validation against the next complete set of model attributes, + // returning `true` if all is well. If a specific `error` callback has + // been passed, call that instead of firing the general `"error"` event. + _validate: function(attrs, options) { + if (options.silent || !this.validate) return true; + attrs = _.extend({}, this.attributes, attrs); + var error = this.validate(attrs, options); + if (!error) return true; + if (options && options.error) { + options.error(this, error, options); + } else { + this.trigger('error', this, error, options); + } + return false; + } + + }); + + // Backbone.Collection + // ------------------- + + // Provides a standard collection class for our sets of models, ordered + // or unordered. If a `comparator` is specified, the Collection will maintain + // its models in sort order, as they're added and removed. + var Collection = Backbone.Collection = function(models, options) { + options || (options = {}); + if (options.model) this.model = options.model; + if (options.comparator) this.comparator = options.comparator; + this._reset(); + this.initialize.apply(this, arguments); + if (models) this.reset(models, {silent: true, parse: options.parse}); + }; + + // Define the Collection's inheritable methods. + _.extend(Collection.prototype, Events, { + + // The default model for a collection is just a **Backbone.Model**. + // This should be overridden in most cases. + model: Model, + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // The JSON representation of a Collection is an array of the + // models' attributes. + toJSON: function(options) { + return this.map(function(model){ return model.toJSON(options); }); + }, + + // Add a model, or list of models to the set. Pass **silent** to avoid + // firing the `add` event for every new model. + add: function(models, options) { + var i, index, length, model, cid, id, cids = {}, ids = {}, dups = []; + options || (options = {}); + models = _.isArray(models) ? models.slice() : [models]; + + // Begin by turning bare objects into model references, and preventing + // invalid models or duplicate models from being added. + for (i = 0, length = models.length; i < length; i++) { + if (!(model = models[i] = this._prepareModel(models[i], options))) { + throw new Error("Can't add an invalid model to a collection"); + } + cid = model.cid; + id = model.id; + if (cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) { + dups.push(i); + continue; + } + cids[cid] = ids[id] = model; + } + + // Remove duplicates. + i = dups.length; + while (i--) { + models.splice(dups[i], 1); + } + + // Listen to added models' events, and index models for lookup by + // `id` and by `cid`. + for (i = 0, length = models.length; i < length; i++) { + (model = models[i]).on('all', this._onModelEvent, this); + this._byCid[model.cid] = model; + if (model.id != null) this._byId[model.id] = model; + } + + // Insert models into the collection, re-sorting if needed, and triggering + // `add` events unless silenced. + this.length += length; + index = options.at != null ? options.at : this.models.length; + splice.apply(this.models, [index, 0].concat(models)); + if (this.comparator) this.sort({silent: true}); + if (options.silent) return this; + for (i = 0, length = this.models.length; i < length; i++) { + if (!cids[(model = this.models[i]).cid]) continue; + options.index = i; + model.trigger('add', model, this, options); + } + return this; + }, + + // Remove a model, or a list of models from the set. Pass silent to avoid + // firing the `remove` event for every model removed. + remove: function(models, options) { + var i, l, index, model; + options || (options = {}); + models = _.isArray(models) ? models.slice() : [models]; + for (i = 0, l = models.length; i < l; i++) { + model = this.getByCid(models[i]) || this.get(models[i]); + if (!model) continue; + delete this._byId[model.id]; + delete this._byCid[model.cid]; + index = this.indexOf(model); + this.models.splice(index, 1); + this.length--; + if (!options.silent) { + options.index = index; + model.trigger('remove', model, this, options); + } + this._removeReference(model); + } + return this; + }, + + // Add a model to the end of the collection. + push: function(model, options) { + model = this._prepareModel(model, options); + this.add(model, options); + return model; + }, + + // Remove a model from the end of the collection. + pop: function(options) { + var model = this.at(this.length - 1); + this.remove(model, options); + return model; + }, + + // Add a model to the beginning of the collection. + unshift: function(model, options) { + model = this._prepareModel(model, options); + this.add(model, _.extend({at: 0}, options)); + return model; + }, + + // Remove a model from the beginning of the collection. + shift: function(options) { + var model = this.at(0); + this.remove(model, options); + return model; + }, + + // Get a model from the set by id. + get: function(id) { + if (id == null) return void 0; + return this._byId[id.id != null ? id.id : id]; + }, + + // Get a model from the set by client id. + getByCid: function(cid) { + return cid && this._byCid[cid.cid || cid]; + }, + + // Get the model at the given index. + at: function(index) { + return this.models[index]; + }, + + // Return models with matching attributes. Useful for simple cases of `filter`. + where: function(attrs) { + if (_.isEmpty(attrs)) return []; + return this.filter(function(model) { + for (var key in attrs) { + if (attrs[key] !== model.get(key)) return false; + } + return true; + }); + }, + + // Force the collection to re-sort itself. You don't need to call this under + // normal circumstances, as the set will maintain sort order as each item + // is added. + sort: function(options) { + options || (options = {}); + if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); + var boundComparator = _.bind(this.comparator, this); + if (this.comparator.length == 1) { + this.models = this.sortBy(boundComparator); + } else { + this.models.sort(boundComparator); + } + if (!options.silent) this.trigger('reset', this, options); + return this; + }, + + // Pluck an attribute from each model in the collection. + pluck: function(attr) { + return _.map(this.models, function(model){ return model.get(attr); }); + }, + + // When you have more items than you want to add or remove individually, + // you can reset the entire set with a new list of models, without firing + // any `add` or `remove` events. Fires `reset` when finished. + reset: function(models, options) { + models || (models = []); + options || (options = {}); + for (var i = 0, l = this.models.length; i < l; i++) { + this._removeReference(this.models[i]); + } + this._reset(); + this.add(models, _.extend({silent: true}, options)); + if (!options.silent) this.trigger('reset', this, options); + return this; + }, + + // Fetch the default set of models for this collection, resetting the + // collection when they arrive. If `add: true` is passed, appends the + // models to the collection instead of resetting. + fetch: function(options) { + options = options ? _.clone(options) : {}; + if (options.parse === undefined) options.parse = true; + var collection = this; + var success = options.success; + options.success = function(resp, status, xhr) { + collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options); + if (success) success(collection, resp); + }; + options.error = Backbone.wrapError(options.error, collection, options); + return (this.sync || Backbone.sync).call(this, 'read', this, options); + }, + + // Create a new instance of a model in this collection. Add the model to the + // collection immediately, unless `wait: true` is passed, in which case we + // wait for the server to agree. + create: function(model, options) { + var coll = this; + options = options ? _.clone(options) : {}; + model = this._prepareModel(model, options); + if (!model) return false; + if (!options.wait) coll.add(model, options); + var success = options.success; + options.success = function(nextModel, resp, xhr) { + if (options.wait) coll.add(nextModel, options); + if (success) { + success(nextModel, resp); + } else { + nextModel.trigger('sync', model, resp, options); + } + }; + model.save(null, options); + return model; + }, + + // **parse** converts a response into a list of models to be added to the + // collection. The default implementation is just to pass it through. + parse: function(resp, xhr) { + return resp; + }, + + // Proxy to _'s chain. Can't be proxied the same way the rest of the + // underscore methods are proxied because it relies on the underscore + // constructor. + chain: function () { + return _(this.models).chain(); + }, + + // Reset all internal state. Called when the collection is reset. + _reset: function(options) { + this.length = 0; + this.models = []; + this._byId = {}; + this._byCid = {}; + }, + + // Prepare a model or hash of attributes to be added to this collection. + _prepareModel: function(model, options) { + options || (options = {}); + if (!(model instanceof Model)) { + var attrs = model; + options.collection = this; + model = new this.model(attrs, options); + if (!model._validate(model.attributes, options)) model = false; + } else if (!model.collection) { + model.collection = this; + } + return model; + }, + + // Internal method to remove a model's ties to a collection. + _removeReference: function(model) { + if (this == model.collection) { + delete model.collection; + } + model.off('all', this._onModelEvent, this); + }, + + // Internal method called every time a model in the set fires an event. + // Sets need to update their indexes when models change ids. All other + // events simply proxy through. "add" and "remove" events that originate + // in other collections are ignored. + _onModelEvent: function(event, model, collection, options) { + if ((event == 'add' || event == 'remove') && collection != this) return; + if (event == 'destroy') { + this.remove(model, options); + } + if (model && event === 'change:' + model.idAttribute) { + delete this._byId[model.previous(model.idAttribute)]; + this._byId[model.id] = model; + } + this.trigger.apply(this, arguments); + } + + }); + + // Underscore methods that we want to implement on the Collection. + var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', + 'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any', + 'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', + 'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf', + 'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy']; + + // Mix in each Underscore method as a proxy to `Collection#models`. + _.each(methods, function(method) { + Collection.prototype[method] = function() { + return _[method].apply(_, [this.models].concat(_.toArray(arguments))); + }; + }); + + // Backbone.Router + // ------------------- + + // Routers map faux-URLs to actions, and fire events when routes are + // matched. Creating a new one sets its `routes` hash, if not set statically. + var Router = Backbone.Router = function(options) { + options || (options = {}); + if (options.routes) this.routes = options.routes; + this._bindRoutes(); + this.initialize.apply(this, arguments); + }; + + // Cached regular expressions for matching named param parts and splatted + // parts of route strings. + var namedParam = /:\w+/g; + var splatParam = /\*\w+/g; + var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g; + + // Set up all inheritable **Backbone.Router** properties and methods. + _.extend(Router.prototype, Events, { + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // Manually bind a single named route to a callback. For example: + // + // this.route('search/:query/p:num', 'search', function(query, num) { + // ... + // }); + // + route: function(route, name, callback) { + Backbone.history || (Backbone.history = new History); + if (!_.isRegExp(route)) route = this._routeToRegExp(route); + if (!callback) callback = this[name]; + Backbone.history.route(route, _.bind(function(fragment) { + var args = this._extractParameters(route, fragment); + callback && callback.apply(this, args); + this.trigger.apply(this, ['route:' + name].concat(args)); + Backbone.history.trigger('route', this, name, args); + }, this)); + return this; + }, + + // Simple proxy to `Backbone.history` to save a fragment into the history. + navigate: function(fragment, options) { + Backbone.history.navigate(fragment, options); + }, + + // Bind all defined routes to `Backbone.history`. We have to reverse the + // order of the routes here to support behavior where the most general + // routes can be defined at the bottom of the route map. + _bindRoutes: function() { + if (!this.routes) return; + var routes = []; + for (var route in this.routes) { + routes.unshift([route, this.routes[route]]); + } + for (var i = 0, l = routes.length; i < l; i++) { + this.route(routes[i][0], routes[i][1], this[routes[i][1]]); + } + }, + + // Convert a route string into a regular expression, suitable for matching + // against the current location hash. + _routeToRegExp: function(route) { + route = route.replace(escapeRegExp, '\\$&') + .replace(namedParam, '([^\/]+)') + .replace(splatParam, '(.*?)'); + return new RegExp('^' + route + '$'); + }, + + // Given a route, and a URL fragment that it matches, return the array of + // extracted parameters. + _extractParameters: function(route, fragment) { + return route.exec(fragment).slice(1); + } + + }); + + // Backbone.History + // ---------------- + + // Handles cross-browser history management, based on URL fragments. If the + // browser does not support `onhashchange`, falls back to polling. + var History = Backbone.History = function() { + this.handlers = []; + _.bindAll(this, 'checkUrl'); + }; + + // Cached regex for cleaning leading hashes and slashes . + var routeStripper = /^[#\/]/; + + // Cached regex for detecting MSIE. + var isExplorer = /msie [\w.]+/; + + // Has the history handling already been started? + History.started = false; + + // Set up all inheritable **Backbone.History** properties and methods. + _.extend(History.prototype, Events, { + + // The default interval to poll for hash changes, if necessary, is + // twenty times a second. + interval: 50, + + // Gets the true hash value. Cannot use location.hash directly due to bug + // in Firefox where location.hash will always be decoded. + getHash: function(windowOverride) { + var loc = windowOverride ? windowOverride.location : window.location; + var match = loc.href.match(/#(.*)$/); + return match ? match[1] : ''; + }, + + // Get the cross-browser normalized URL fragment, either from the URL, + // the hash, or the override. + getFragment: function(fragment, forcePushState) { + if (fragment == null) { + if (this._hasPushState || forcePushState) { + fragment = window.location.pathname; + var search = window.location.search; + if (search) fragment += search; + } else { + fragment = this.getHash(); + } + } + if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length); + return fragment.replace(routeStripper, ''); + }, + + // Start the hash change handling, returning `true` if the current URL matches + // an existing route, and `false` otherwise. + start: function(options) { + if (History.started) throw new Error("Backbone.history has already been started"); + History.started = true; + + // Figure out the initial configuration. Do we need an iframe? + // Is pushState desired ... is it available? + this.options = _.extend({}, {root: '/'}, this.options, options); + this._wantsHashChange = this.options.hashChange !== false; + this._wantsPushState = !!this.options.pushState; + this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState); + var fragment = this.getFragment(); + var docMode = document.documentMode; + var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); + + if (oldIE) { + this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow; + this.navigate(fragment); + } + + // Depending on whether we're using pushState or hashes, and whether + // 'onhashchange' is supported, determine how we check the URL state. + if (this._hasPushState) { + $(window).bind('popstate', this.checkUrl); + } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) { + $(window).bind('hashchange', this.checkUrl); + } else if (this._wantsHashChange) { + this._checkUrlInterval = setInterval(this.checkUrl, this.interval); + } + + // Determine if we need to change the base url, for a pushState link + // opened by a non-pushState browser. + this.fragment = fragment; + var loc = window.location; + var atRoot = loc.pathname == this.options.root; + + // If we've started off with a route from a `pushState`-enabled browser, + // but we're currently in a browser that doesn't support it... + if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) { + this.fragment = this.getFragment(null, true); + window.location.replace(this.options.root + '#' + this.fragment); + // Return immediately as browser will do redirect to new url + return true; + + // Or if we've started out with a hash-based route, but we're currently + // in a browser where it could be `pushState`-based instead... + } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) { + this.fragment = this.getHash().replace(routeStripper, ''); + window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment); + } + + if (!this.options.silent) { + return this.loadUrl(); + } + }, + + // Disable Backbone.history, perhaps temporarily. Not useful in a real app, + // but possibly useful for unit testing Routers. + stop: function() { + $(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl); + clearInterval(this._checkUrlInterval); + History.started = false; + }, + + // Add a route to be tested when the fragment changes. Routes added later + // may override previous routes. + route: function(route, callback) { + this.handlers.unshift({route: route, callback: callback}); + }, + + // Checks the current URL to see if it has changed, and if it has, + // calls `loadUrl`, normalizing across the hidden iframe. + checkUrl: function(e) { + var current = this.getFragment(); + if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe)); + if (current == this.fragment) return false; + if (this.iframe) this.navigate(current); + this.loadUrl() || this.loadUrl(this.getHash()); + }, + + // Attempt to load the current URL fragment. If a route succeeds with a + // match, returns `true`. If no defined routes matches the fragment, + // returns `false`. + loadUrl: function(fragmentOverride) { + var fragment = this.fragment = this.getFragment(fragmentOverride); + var matched = _.any(this.handlers, function(handler) { + if (handler.route.test(fragment)) { + handler.callback(fragment); + return true; + } + }); + return matched; + }, + + // Save a fragment into the hash history, or replace the URL state if the + // 'replace' option is passed. You are responsible for properly URL-encoding + // the fragment in advance. + // + // The options object can contain `trigger: true` if you wish to have the + // route callback be fired (not usually desirable), or `replace: true`, if + // you wish to modify the current URL without adding an entry to the history. + navigate: function(fragment, options) { + if (!History.started) return false; + if (!options || options === true) options = {trigger: options}; + var frag = (fragment || '').replace(routeStripper, ''); + if (this.fragment == frag) return; + + // If pushState is available, we use it to set the fragment as a real URL. + if (this._hasPushState) { + if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag; + this.fragment = frag; + window.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, frag); + + // If hash changes haven't been explicitly disabled, update the hash + // fragment to store history. + } else if (this._wantsHashChange) { + this.fragment = frag; + this._updateHash(window.location, frag, options.replace); + if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) { + // Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change. + // When replace is true, we don't want this. + if(!options.replace) this.iframe.document.open().close(); + this._updateHash(this.iframe.location, frag, options.replace); + } + + // If you've told us that you explicitly don't want fallback hashchange- + // based history, then `navigate` becomes a page refresh. + } else { + window.location.assign(this.options.root + fragment); + } + if (options.trigger) this.loadUrl(fragment); + }, + + // Update the hash location, either replacing the current entry, or adding + // a new one to the browser history. + _updateHash: function(location, fragment, replace) { + if (replace) { + location.replace(location.toString().replace(/(javascript:|#).*$/, '') + '#' + fragment); + } else { + location.hash = fragment; + } + } + }); + + // Backbone.View + // ------------- + + // Creating a Backbone.View creates its initial element outside of the DOM, + // if an existing element is not provided... + var View = Backbone.View = function(options) { + this.cid = _.uniqueId('view'); + this._configure(options || {}); + this._ensureElement(); + this.initialize.apply(this, arguments); + this.delegateEvents(); + }; + + // Cached regex to split keys for `delegate`. + var delegateEventSplitter = /^(\S+)\s*(.*)$/; + + // List of view options to be merged as properties. + var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName']; + + // Set up all inheritable **Backbone.View** properties and methods. + _.extend(View.prototype, Events, { + + // The default `tagName` of a View's element is `"div"`. + tagName: 'div', + + // jQuery delegate for element lookup, scoped to DOM elements within the + // current view. This should be prefered to global lookups where possible. + $: function(selector) { + return this.$el.find(selector); + }, + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // **render** is the core function that your view should override, in order + // to populate its element (`this.el`), with the appropriate HTML. The + // convention is for **render** to always return `this`. + render: function() { + return this; + }, + + // Remove this view from the DOM. Note that the view isn't present in the + // DOM by default, so calling this method may be a no-op. + remove: function() { + this.$el.remove(); + return this; + }, + + // For small amounts of DOM Elements, where a full-blown template isn't + // needed, use **make** to manufacture elements, one at a time. + // + // var el = this.make('li', {'class': 'row'}, this.model.escape('title')); + // + make: function(tagName, attributes, content) { + var el = document.createElement(tagName); + if (attributes) $(el).attr(attributes); + if (content) $(el).html(content); + return el; + }, + + // Change the view's element (`this.el` property), including event + // re-delegation. + setElement: function(element, delegate) { + if (this.$el) this.undelegateEvents(); + this.$el = (element instanceof $) ? element : $(element); + this.el = this.$el[0]; + if (delegate !== false) this.delegateEvents(); + return this; + }, + + // Set callbacks, where `this.events` is a hash of + // + // *{"event selector": "callback"}* + // + // { + // 'mousedown .title': 'edit', + // 'click .button': 'save' + // 'click .open': function(e) { ... } + // } + // + // pairs. Callbacks will be bound to the view, with `this` set properly. + // Uses event delegation for efficiency. + // Omitting the selector binds the event to `this.el`. + // This only works for delegate-able events: not `focus`, `blur`, and + // not `change`, `submit`, and `reset` in Internet Explorer. + delegateEvents: function(events) { + if (!(events || (events = getValue(this, 'events')))) return; + this.undelegateEvents(); + for (var key in events) { + var method = events[key]; + if (!_.isFunction(method)) method = this[events[key]]; + if (!method) throw new Error('Method "' + events[key] + '" does not exist'); + var match = key.match(delegateEventSplitter); + var eventName = match[1], selector = match[2]; + method = _.bind(method, this); + eventName += '.delegateEvents' + this.cid; + if (selector === '') { + this.$el.bind(eventName, method); + } else { + this.$el.delegate(selector, eventName, method); + } + } + }, + + // Clears all callbacks previously bound to the view with `delegateEvents`. + // You usually don't need to use this, but may wish to if you have multiple + // Backbone views attached to the same DOM element. + undelegateEvents: function() { + this.$el.unbind('.delegateEvents' + this.cid); + }, + + // Performs the initial configuration of a View with a set of options. + // Keys with special meaning *(model, collection, id, className)*, are + // attached directly to the view. + _configure: function(options) { + if (this.options) options = _.extend({}, this.options, options); + for (var i = 0, l = viewOptions.length; i < l; i++) { + var attr = viewOptions[i]; + if (options[attr]) this[attr] = options[attr]; + } + this.options = options; + }, + + // Ensure that the View has a DOM element to render into. + // If `this.el` is a string, pass it through `$()`, take the first + // matching element, and re-assign it to `el`. Otherwise, create + // an element from the `id`, `className` and `tagName` properties. + _ensureElement: function() { + if (!this.el) { + var attrs = getValue(this, 'attributes') || {}; + if (this.id) attrs.id = this.id; + if (this.className) attrs['class'] = this.className; + this.setElement(this.make(this.tagName, attrs), false); + } else { + this.setElement(this.el, false); + } + } + + }); + + // The self-propagating extend function that Backbone classes use. + var extend = function (protoProps, classProps) { + var child = inherits(this, protoProps, classProps); + child.extend = this.extend; + return child; + }; + + // Set up inheritance for the model, collection, and view. + Model.extend = Collection.extend = Router.extend = View.extend = extend; + + // Backbone.sync + // ------------- + + // Map from CRUD to HTTP for our default `Backbone.sync` implementation. + var methodMap = { + 'create': 'POST', + 'update': 'PUT', + 'delete': 'DELETE', + 'read': 'GET' + }; + + // Override this function to change the manner in which Backbone persists + // models to the server. You will be passed the type of request, and the + // model in question. By default, makes a RESTful Ajax request + // to the model's `url()`. Some possible customizations could be: + // + // * Use `setTimeout` to batch rapid-fire updates into a single request. + // * Send up the models as XML instead of JSON. + // * Persist models via WebSockets instead of Ajax. + // + // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests + // as `POST`, with a `_method` parameter containing the true HTTP method, + // as well as all requests with the body as `application/x-www-form-urlencoded` + // instead of `application/json` with the model in a param named `model`. + // Useful when interfacing with server-side languages like **PHP** that make + // it difficult to read the body of `PUT` requests. + Backbone.sync = function(method, model, options) { + var type = methodMap[method]; + + // Default options, unless specified. + options || (options = {}); + + // Default JSON-request options. + var params = {type: type, dataType: 'json'}; + + // Ensure that we have a URL. + if (!options.url) { + params.url = getValue(model, 'url') || urlError(); + } + + // Ensure that we have the appropriate request data. + if (!options.data && model && (method == 'create' || method == 'update')) { + params.contentType = 'application/json'; + params.data = JSON.stringify(model.toJSON()); + } + + // For older servers, emulate JSON by encoding the request into an HTML-form. + if (Backbone.emulateJSON) { + params.contentType = 'application/x-www-form-urlencoded'; + params.data = params.data ? {model: params.data} : {}; + } + + // For older servers, emulate HTTP by mimicking the HTTP method with `_method` + // And an `X-HTTP-Method-Override` header. + if (Backbone.emulateHTTP) { + if (type === 'PUT' || type === 'DELETE') { + if (Backbone.emulateJSON) params.data._method = type; + params.type = 'POST'; + params.beforeSend = function(xhr) { + xhr.setRequestHeader('X-HTTP-Method-Override', type); + }; + } + } + + // Don't process data on a non-GET request. + if (params.type !== 'GET' && !Backbone.emulateJSON) { + params.processData = false; + } + + // Make the request, allowing the user to override any Ajax options. + return $.ajax(_.extend(params, options)); + }; + + // Wrap an optional error callback with a fallback error event. + Backbone.wrapError = function(onError, originalModel, options) { + return function(model, resp) { + resp = model === originalModel ? resp : model; + if (onError) { + onError(originalModel, resp, options); + } else { + originalModel.trigger('error', originalModel, resp, options); + } + }; + }; + + // Helpers + // ------- + + // Shared empty constructor function to aid in prototype-chain creation. + var ctor = function(){}; + + // Helper function to correctly set up the prototype chain, for subclasses. + // Similar to `goog.inherits`, but uses a hash of prototype properties and + // class properties to be extended. + var inherits = function(parent, protoProps, staticProps) { + var child; + + // The constructor function for the new subclass is either defined by you + // (the "constructor" property in your `extend` definition), or defaulted + // by us to simply call the parent's constructor. + if (protoProps && protoProps.hasOwnProperty('constructor')) { + child = protoProps.constructor; + } else { + child = function(){ parent.apply(this, arguments); }; + } + + // Inherit class (static) properties from parent. + _.extend(child, parent); + + // Set the prototype chain to inherit from `parent`, without calling + // `parent`'s constructor function. + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + + // Add prototype properties (instance properties) to the subclass, + // if supplied. + if (protoProps) _.extend(child.prototype, protoProps); + + // Add static properties to the constructor function, if supplied. + if (staticProps) _.extend(child, staticProps); + + // Correctly set child's `prototype.constructor`. + child.prototype.constructor = child; + + // Set a convenience property in case the parent's prototype is needed later. + child.__super__ = parent.prototype; + + return child; + }; + + // Helper function to get a value from a Backbone object as a property + // or as a function. + var getValue = function(object, prop) { + if (!(object && object[prop])) return null; + return _.isFunction(object[prop]) ? object[prop]() : object[prop]; + }; + + // Throw an error when a URL is needed, and none is supplied. + var urlError = function() { + throw new Error('A "url" property or function must be specified'); + }; + +}).call(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/js/config.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,31 @@ +// +// Config file. Split out from the app for ease of overlaying a new config +// without affecting the app controller. +// +// Copyright (c) The Dojo Foundation 2011. All Rights Reserved. +// +var dojoConfig = { + baseUrl: '/renkan', + async:true, + paths : { + coweb : 'lib/coweb', + cowebx: 'lib/cowebx', + org : 'lib/org' + }, +/* packages:[{ + name: 'dojo', + location:'http://vhost1629.developer.ihost.com/dojotoolkit/1.7.0/dojo', + main:'main' + }, + { + name: 'dijit', + location:'http://vhost1629.developer.ihost.com/dojotoolkit/1.7.0/dijit', + main:'main' + }, + { + name: 'dojox', + location:'http://vhost1629.developer.ihost.com/dojotoolkit/1.7.0/dojox', + main:'main' + }]*/ +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/js/dojo.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,15 @@ +/* + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +/* + This is an optimized version of Dojo, built for deployment and not for + development. To get sources and documentation, please visit: + + http://dojotoolkit.org +*/ + +//>>built +(function(_1,_2){var _3=function(){},_4=function(it){for(var p in it){return 0;}return 1;},_5={}.toString,_6=function(it){return _5.call(it)=="[object Function]";},_7=function(it){return _5.call(it)=="[object String]";},_8=function(it){return _5.call(it)=="[object Array]";},_9=function(_a,_b){if(_a){for(var i=0;i<_a.length;){_b(_a[i++]);}}},_c=function(_d,_e){for(var p in _e){_d[p]=_e[p];}return _d;},_f=function(_10,_11){return _c(new Error(_10),{src:"dojoLoader",info:_11});},_12=1,uid=function(){return "_"+_12++;},req=function(_13,_14,_15){return _16(_13,_14,_15,0,req);},_17=this,doc=_17.document,_18=doc&&doc.createElement("DiV"),has=req.has=function(_19){return _6(_1a[_19])?(_1a[_19]=_1a[_19](_17,doc,_18)):_1a[_19];},_1a=has.cache=_2.hasCache;has.add=function(_1b,_1c,now,_1d){(_1a[_1b]===undefined||_1d)&&(_1a[_1b]=_1c);return now&&has(_1b);};0&&has.add("host-node",_1.has&&"host-node" in _1.has?_1.has["host-node"]:(typeof process=="object"&&process.versions&&process.versions.node&&process.versions.v8));if(0){require("./_base/configNode.js").config(_2);_2.loaderPatch.nodeRequire=require;}0&&has.add("host-rhino",_1.has&&"host-rhino" in _1.has?_1.has["host-rhino"]:(typeof load=="function"&&(typeof Packages=="function"||typeof Packages=="object")));if(0){for(var _1e=_1.baseUrl||".",arg,_1f=this.arguments,i=0;i<_1f.length;){arg=(_1f[i++]+"").split("=");if(arg[0]=="baseUrl"){_1e=arg[1];break;}}load(_1e+"/_base/configRhino.js");rhinoDojoConfig(_2,_1e,_1f);}for(var p in _1.has){has.add(p,_1.has[p],0,1);}var _20=1,_21=2,_22=3,_23=4,_24=5;if(0){_20="requested";_21="arrived";_22="not-a-module";_23="executing";_24="executed";}var _25=0,_26="sync",xd="xd",_27=[],_28=0,_29=_3,_2a=_3,_2b;if(1){req.isXdUrl=_3;req.initSyncLoader=function(_2c,_2d,_2e){if(!_28){_28=_2c;_29=_2d;_2a=_2e;}return {sync:_26,requested:_20,arrived:_21,nonmodule:_22,executing:_23,executed:_24,syncExecStack:_27,modules:_2f,execQ:_30,getModule:_31,injectModule:_32,setArrived:_33,signal:_34,finishExec:_35,execModule:_36,dojoRequirePlugin:_28,getLegacyMode:function(){return _25;},guardCheckComplete:_37};};if(1){var _38=location.protocol,_39=location.host;req.isXdUrl=function(url){if(/^\./.test(url)){return false;}if(/^\/\//.test(url)){return true;}var _3a=url.match(/^([^\/\:]+\:)\/+([^\/]+)/);return _3a&&(_3a[1]!=_38||(_39&&_3a[2]!=_39));};1||has.add("dojo-xhr-factory",1);has.add("dojo-force-activex-xhr",1&&!doc.addEventListener&&window.location.protocol=="file:");has.add("native-xhr",typeof XMLHttpRequest!="undefined");if(has("native-xhr")&&!has("dojo-force-activex-xhr")){_2b=function(){return new XMLHttpRequest();};}else{for(var _3b=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],_3c,i=0;i<3;){try{_3c=_3b[i++];if(new ActiveXObject(_3c)){break;}}catch(e){}}_2b=function(){return new ActiveXObject(_3c);};}req.getXhr=_2b;has.add("dojo-gettext-api",1);req.getText=function(url,_3d,_3e){var xhr=_2b();xhr.open("GET",_3f(url),false);xhr.send(null);if(xhr.status==200||(!location.host&&!xhr.status)){if(_3e){_3e(xhr.responseText,_3d);}}else{throw _f("xhrFailed",xhr.status);}return xhr.responseText;};}}else{req.async=1;}var _40=new Function("return eval(arguments[0]);");req.eval=function(_41,_42){return _40(_41+"\r\n////@ sourceURL="+_42);};var _43={},_44="error",_34=req.signal=function(_45,_46){var _47=_43[_45];_9(_47&&_47.slice(0),function(_48){_48.apply(null,_8(_46)?_46:[_46]);});},on=req.on=function(_49,_4a){var _4b=_43[_49]||(_43[_49]=[]);_4b.push(_4a);return {remove:function(){for(var i=0;i<_4b.length;i++){if(_4b[i]===_4a){_4b.splice(i,1);return;}}}};};var _4c=[],_4d={},_4e=[],_4f={},map=req.map={},_50=[],_2f={},_51="",_52={},_53="url:",_54={},_55={};if(1){var _56=function(_57){var p,_58,_59,now,m;for(p in _54){_58=_54[p];_59=p.match(/^url\:(.+)/);if(_59){_52[_53+_5a(_59[1],_57)]=_58;}else{if(p=="*now"){now=_58;}else{if(p!="*noref"){m=_5b(p,_57);_52[m.mid]=_52[_53+m.url]=_58;}}}}if(now){now(_5c(_57));}_54={};},_5d=function(s){return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(c){return "\\"+c;});},_5e=function(map,_5f){_5f.splice(0,_5f.length);for(var p in map){_5f.push([p,map[p],new RegExp("^"+_5d(p)+"(/|$)"),p.length]);}_5f.sort(function(lhs,rhs){return rhs[3]-lhs[3];});return _5f;},_60=function(_61){var _62=_61.name;if(!_62){_62=_61;_61={name:_62};}_61=_c({main:"main"},_61);_61.location=_61.location?_61.location:_62;if(_61.packageMap){map[_62]=_61.packageMap;}if(!_61.main.indexOf("./")){_61.main=_61.main.substring(2);}_4f[_62]=_61;},_63=function(_64,_65,_66){for(var p in _64){if(p=="waitSeconds"){req.waitms=(_64[p]||0)*1000;}if(p=="cacheBust"){_51=_64[p]?(_7(_64[p])?_64[p]:(new Date()).getTime()+""):"";}if(p=="baseUrl"||p=="combo"){req[p]=_64[p];}if(1&&p=="async"){var _67=_64[p];req.legacyMode=_25=(_7(_67)&&/sync|legacyAsync/.test(_67)?_67:(!_67?_26:false));req.async=!_25;}if(_64[p]!==_1a){req.rawConfig[p]=_64[p];p!="has"&&has.add("config-"+p,_64[p],0,_65);}}if(!req.baseUrl){req.baseUrl="./";}if(!/\/$/.test(req.baseUrl)){req.baseUrl+="/";}for(p in _64.has){has.add(p,_64.has[p],0,_65);}_9(_64.packages,_60);for(_1e in _64.packagePaths){_9(_64.packagePaths[_1e],function(_68){var _69=_1e+"/"+_68;if(_7(_68)){_68={name:_68};}_68.location=_69;_60(_68);});}_5e(_c(map,_64.map),_50);_9(_50,function(_6a){_6a[1]=_5e(_6a[1],[]);if(_6a[0]=="*"){_50.star=_6a[1];}});_5e(_c(_4d,_64.paths),_4e);_9(_64.aliases,function(_6b){if(_7(_6b[0])){_6b[0]=new RegExp("^"+_5d(_6b[0])+"$");}_4c.push(_6b);});for(p in _64.config){var _6c=_31(p,_66);_6c.config=_c(_6c.config||{},_64.config[p]);}if(_64.cache){_56();_54=_64.cache;if(_64.cache["*noref"]){_56();}}_34("config",[_64,req.rawConfig]);};if(has("dojo-cdn")||1){var _6d=doc.getElementsByTagName("script"),i=0,_6e,_6f,src,_70;while(i<_6d.length){_6e=_6d[i++];if((src=_6e.getAttribute("src"))&&(_70=src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){_6f=_70[3]||"";_2.baseUrl=_2.baseUrl||_6f;src=(_6e.getAttribute("data-dojo-config")||_6e.getAttribute("djConfig"));if(src){_55=req.eval("({ "+src+" })","data-dojo-config");}if(0){var _71=_6e.getAttribute("data-main");if(_71){_55.deps=_55.deps||[_71];}}break;}}}if(0){try{if(window.parent!=window&&window.parent.require){var doh=window.parent.require("doh");doh&&_c(_55,doh.testConfig);}}catch(e){}}req.rawConfig={};_63(_2,1);if(has("dojo-cdn")){_4f.dojo.location=_6f;if(_6f){_6f+="/";}_4f.dijit.location=_6f+"../dijit/";_4f.dojox.location=_6f+"../dojox/";}_63(_1,1);_63(_55,1);}else{_4d=_2.paths;_4e=_2.pathsMapProg;_4f=_2.packs;_4c=_2.aliases;_50=_2.mapProgs;_2f=_2.modules;_52=_2.cache;_51=_2.cacheBust;req.rawConfig=_2;}if(0){req.combo=req.combo||{add:_3};var _72=0,_73=[],_74=null;}var _75=function(_76){_37(function(){_9(_76.deps,_32);if(0&&_72&&!_74){_74=setTimeout(function(){_72=0;_74=null;req.combo.done(function(_77,url){var _78=function(){_79(0,_77);_7a();};_73.push(_77);_7b=_77;req.injectUrl(url,_78,_77);_7b=0;},req);},0);}});},_16=function(a1,a2,a3,_7c,_7d){var _7e,_7f;if(_7(a1)){_7e=_31(a1,_7c,true);if(_7e&&_7e.executed){return _7e.result;}throw _f("undefinedModule",a1);}if(!_8(a1)){_63(a1,0,_7c);a1=a2;a2=a3;}if(_8(a1)){if(!a1.length){a2&&a2();}else{_7f="require*"+uid();for(var mid,_80=[],i=0;i<a1.length;){mid=a1[i++];_80.push(_31(mid,_7c));}_7e=_c(_81("",_7f,0,""),{injected:_21,deps:_80,def:a2||_3,require:_7c?_7c.require:req,gc:1});_2f[_7e.mid]=_7e;_75(_7e);var _82=_83&&_25!=_26;_37(function(){_36(_7e,_82);});if(!_7e.executed){_30.push(_7e);}_7a();}}return _7d;},_5c=function(_84){if(!_84){return req;}var _85=_84.require;if(!_85){_85=function(a1,a2,a3){return _16(a1,a2,a3,_84,_85);};_84.require=_c(_85,req);_85.module=_84;_85.toUrl=function(_86){return _5a(_86,_84);};_85.toAbsMid=function(mid){return _b3(mid,_84);};if(0){_85.undef=function(mid){req.undef(mid,_84);};}if(1){_85.syncLoadNls=function(mid){var _87=_5b(mid,_84),_88=_2f[_87.mid];if(!_88||!_88.executed){_89=_52[_87.mid]||_52[_53+_87.url];if(_89){_8a(_89);_88=_2f[_87.mid];}}return _88&&_88.executed&&_88.result;};}}return _85;},_30=[],_8b=[],_8c={},_8d=function(_8e){_8e.injected=_20;_8c[_8e.mid]=1;if(_8e.url){_8c[_8e.url]=_8e.pack||1;}_8f();},_33=function(_90){_90.injected=_21;delete _8c[_90.mid];if(_90.url){delete _8c[_90.url];}if(_4(_8c)){_91();1&&_25==xd&&(_25=_26);}},_92=req.idle=function(){return !_8b.length&&_4(_8c)&&!_30.length&&!_83;},_93=function(_94,map){if(map){for(var i=0;i<map.length;i++){if(map[i][2].test(_94)){return map[i];}}}return 0;},_95=function(_96){var _97=[],_98,_99;_96=_96.replace(/\\/g,"/").split("/");while(_96.length){_98=_96.shift();if(_98==".."&&_97.length&&_99!=".."){_97.pop();_99=_97[_97.length-1];}else{if(_98!="."){_97.push(_99=_98);}}}return _97.join("/");},_81=function(pid,mid,_9a,url){if(1){var xd=req.isXdUrl(url);return {pid:pid,mid:mid,pack:_9a,url:url,executed:0,def:0,isXd:xd,isAmd:!!(xd||(_4f[pid]&&_4f[pid].isAmd))};}else{return {pid:pid,mid:mid,pack:_9a,url:url,executed:0,def:0};}},_9b=function(mid,_9c,_9d,_9e,_9f,_a0,_a1,_a2){var pid,_a3,_a4,_a5,_a6,url,_a7,_a8,_a9;_a9=mid;_a8=/^\./.test(mid);if(/(^\/)|(\:)|(\.js$)/.test(mid)||(_a8&&!_9c)){return _81(0,mid,0,mid);}else{mid=_95(_a8?(_9c.mid+"/../"+mid):mid);if(/^\./.test(mid)){throw _f("irrationalPath",mid);}if(_9c){_a6=_93(_9c.mid,_a0);}_a6=_a6||_a0.star;_a6=_a6&&_93(mid,_a6[1]);if(_a6){mid=_a6[1]+mid.substring(_a6[3]);}_70=mid.match(/^([^\/]+)(\/(.+))?$/);pid=_70?_70[1]:"";if((_a3=_9d[pid])){mid=pid+"/"+(_a4=(_70[3]||_a3.main));}else{pid="";}var _aa=0,_ab=0;_9(_4c,function(_ac){var _ad=mid.match(_ac[0]);if(_ad&&_ad.length>_aa){_ab=_6(_ac[1])?mid.replace(_ac[0],_ac[1]):_ac[1];}});if(_ab){return _9b(_ab,0,_9d,_9e,_9f,_a0,_a1,_a2);}_a7=_9e[mid];if(_a7){return _a2?_81(_a7.pid,_a7.mid,_a7.pack,_a7.url):_9e[mid];}}_a6=_93(mid,_a1);if(_a6){url=_a6[1]+mid.substring(_a6[3]);}else{if(pid){url=_a3.location+"/"+_a4;}else{if(has("config-tlmSiblingOfDojo")){url="../"+mid;}else{url=mid;}}}if(!(/(^\/)|(\:)/.test(url))){url=_9f+url;}url+=".js";return _81(pid,mid,_a3,_95(url));},_5b=function(mid,_ae){return _9b(mid,_ae,_4f,_2f,req.baseUrl,_50,_4e);},_af=function(_b0,_b1,_b2){return _b0.normalize?_b0.normalize(_b1,function(mid){return _b3(mid,_b2);}):_b3(_b1,_b2);},_b4=0,_31=function(mid,_b5,_b6){var _b7,_b8,_b9,_ba;_b7=mid.match(/^(.+?)\!(.*)$/);if(_b7){_b8=_31(_b7[1],_b5,_b6);if(1&&_25==_26&&!_b8.executed){_32(_b8);if(_b8.injected===_21&&!_b8.executed){_37(function(){_36(_b8);});}if(_b8.executed){_bb(_b8);}else{_30.unshift(_b8);}}if(_b8.executed===_24&&!_b8.load){_bb(_b8);}if(_b8.load){_b9=_af(_b8,_b7[2],_b5);mid=(_b8.mid+"!"+(_b8.dynamic?++_b4+"!":"")+_b9);}else{_b9=_b7[2];mid=_b8.mid+"!"+(++_b4)+"!waitingForPlugin";}_ba={plugin:_b8,mid:mid,req:_5c(_b5),prid:_b9};}else{_ba=_5b(mid,_b5);}return _2f[_ba.mid]||(!_b6&&(_2f[_ba.mid]=_ba));},_b3=req.toAbsMid=function(mid,_bc){return _5b(mid,_bc).mid;},_5a=req.toUrl=function(_bd,_be){var _bf=_5b(_bd+"/x",_be),url=_bf.url;return _3f(_bf.pid===0?_bd:url.substring(0,url.length-5));},_c0={injected:_21,executed:_24,def:_22,result:_22},_c1=function(mid){return _2f[mid]=_c({mid:mid},_c0);},_c2=_c1("require"),_c3=_c1("exports"),_c4=_c1("module"),_c5=function(_c6,_c7){req.trace("loader-run-factory",[_c6.mid]);var _c8=_c6.def,_c9;1&&_27.unshift(_c6);if(has("config-dojo-loader-catches")){try{_c9=_6(_c8)?_c8.apply(null,_c7):_c8;}catch(e){_34(_44,_c6.result=_f("factoryThrew",[_c6,e]));}}else{_c9=_6(_c8)?_c8.apply(null,_c7):_c8;}_c6.result=_c9===undefined&&_c6.cjs?_c6.cjs.exports:_c9;1&&_27.shift(_c6);},_ca={},_cb=0,_bb=function(_cc){var _cd=_cc.result;_cc.dynamic=_cd.dynamic;_cc.normalize=_cd.normalize;_cc.load=_cd.load;return _cc;},_ce=function(_cf){var map={};_9(_cf.loadQ,function(_d0){var _d1=_af(_cf,_d0.prid,_d0.req.module),mid=_cf.dynamic?_d0.mid.replace(/waitingForPlugin$/,_d1):(_cf.mid+"!"+_d1),_d2=_c(_c({},_d0),{mid:mid,prid:_d1,injected:0});if(!_2f[mid]){_e4(_2f[mid]=_d2);}map[_d0.mid]=_2f[mid];_33(_d0);delete _2f[_d0.mid];});_cf.loadQ=0;var _d3=function(_d4){for(var _d5,_d6=_d4.deps||[],i=0;i<_d6.length;i++){_d5=map[_d6[i].mid];if(_d5){_d6[i]=_d5;}}};for(var p in _2f){_d3(_2f[p]);}_9(_30,_d3);},_35=function(_d7){req.trace("loader-finish-exec",[_d7.mid]);_d7.executed=_24;_d7.defOrder=_cb++;1&&_9(_d7.provides,function(cb){cb();});if(_d7.loadQ){_bb(_d7);_ce(_d7);}for(i=0;i<_30.length;){if(_30[i]===_d7){_30.splice(i,1);}else{i++;}}if(/^require\*/.test(_d7.mid)){delete _2f[_d7.mid];}},_d8=[],_36=function(_d9,_da){if(_d9.executed===_23){req.trace("loader-circular-dependency",[_d8.concat(_d9.mid).join("->")]);return (!_d9.def||_da)?_ca:(_d9.cjs&&_d9.cjs.exports);}if(!_d9.executed){if(!_d9.def){return _ca;}var mid=_d9.mid,_db=_d9.deps||[],arg,_dc,_dd=[],i=0;if(0){_d8.push(mid);req.trace("loader-exec-module",["exec",_d8.length,mid]);}_d9.executed=_23;while(i<_db.length){arg=_db[i++];_dc=((arg===_c2)?_5c(_d9):((arg===_c3)?_d9.cjs.exports:((arg===_c4)?_d9.cjs:_36(arg,_da))));if(_dc===_ca){_d9.executed=0;req.trace("loader-exec-module",["abort",mid]);0&&_d8.pop();return _ca;}_dd.push(_dc);}_c5(_d9,_dd);_35(_d9);0&&_d8.pop();}return _d9.result;},_83=0,_37=function(_de){try{_83++;_de();}finally{_83--;}if(_92()){_34("idle",[]);}},_7a=function(){if(_83){return;}_37(function(){_29();for(var _df,_e0,i=0;i<_30.length;){_df=_cb;_e0=_30[i];_36(_e0);if(_df!=_cb){_29();i=0;}else{i++;}}});};if(0){req.undef=function(_e1,_e2){var _e3=_31(_e1,_e2);_33(_e3);delete _2f[_e3.mid];};}if(1){if(has("dojo-loader-eval-hint-url")===undefined){has.add("dojo-loader-eval-hint-url",1);}var _3f=function(url){url+="";return url+(_51?((/\?/.test(url)?"&":"?")+_51):"");},_e4=function(_e5){var _e6=_e5.plugin;if(_e6.executed===_24&&!_e6.load){_bb(_e6);}var _e7=function(def){_e5.result=def;_33(_e5);_35(_e5);_7a();};if(_e6.load){_e6.load(_e5.prid,_e5.req,_e7);}else{if(_e6.loadQ){_e6.loadQ.push(_e5);}else{_e6.loadQ=[_e5];_30.unshift(_e6);_32(_e6);}}},_89=0,_7b=0,_e8=0,_8a=function(_e9,_ea){if(has("config-stripStrict")){_e9=_e9.replace(/"use strict"/g,"");}_e8=1;if(has("config-dojo-loader-catches")){try{if(_e9===_89){_89.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}catch(e){_34(_44,_f("evalModuleThrew",_ea));}}else{if(_e9===_89){_89.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}_e8=0;},_32=function(_eb){var mid=_eb.mid,url=_eb.url;if(_eb.executed||_eb.injected||_8c[mid]||(_eb.url&&((_eb.pack&&_8c[_eb.url]===_eb.pack)||_8c[_eb.url]==1))){return;}_8d(_eb);if(0){var _ec=0;if(_eb.plugin&&_eb.plugin.isCombo){req.combo.add(_eb.plugin.mid,_eb.prid,0,req);_ec=1;}else{if(!_eb.plugin){_ec=req.combo.add(0,_eb.mid,_eb.url,req);}}if(_ec){_72=1;return;}}if(_eb.plugin){_e4(_eb);return;}var _ed=function(){_79(_eb);if(_eb.injected!==_21){_33(_eb);_c(_eb,_c0);req.trace("loader-define-nonmodule",[_eb.url]);}if(1&&_25){!_27.length&&_7a();}else{_7a();}};_89=_52[mid]||_52[_53+_eb.url];if(_89){req.trace("loader-inject",["cache",_eb.mid,url]);_8a(_89,_eb);_ed();return;}if(1&&_25){if(_eb.isXd){_25==_26&&(_25=xd);}else{if(_eb.isAmd&&_25!=_26){}else{var _ee=function(_ef){if(_25==_26){_27.unshift(_eb);_8a(_ef,_eb);_27.shift();_79(_eb);if(!_eb.cjs){_33(_eb);_35(_eb);}if(_eb.finish){var _f0=mid+"*finish",_f1=_eb.finish;delete _eb.finish;def(_f0,["dojo",("dojo/require!"+_f1.join(",")).replace(/\./g,"/")],function(_f2){_9(_f1,function(mid){_f2.require(mid);});});_30.unshift(_31(_f0));}_ed();}else{_ef=_2a(_eb,_ef);if(_ef){_8a(_ef,_eb);_ed();}else{_7b=_eb;req.injectUrl(_3f(url),_ed,_eb);_7b=0;}}};req.trace("loader-inject",["xhr",_eb.mid,url,_25!=_26]);if(has("config-dojo-loader-catches")){try{req.getText(url,_25!=_26,_ee);}catch(e){_34(_44,_f("xhrInjectFailed",[_eb,e]));}}else{req.getText(url,_25!=_26,_ee);}return;}}}req.trace("loader-inject",["script",_eb.mid,url]);_7b=_eb;req.injectUrl(_3f(url),_ed,_eb);_7b=0;},_f3=function(_f4,_f5,def){req.trace("loader-define-module",[_f4.mid,_f5]);if(0&&_f4.plugin&&_f4.plugin.isCombo){_f4.result=_6(def)?def():def;_33(_f4);_35(_f4);return _f4;}var mid=_f4.mid;if(_f4.injected===_21){_34(_44,_f("multipleDefine",_f4));return _f4;}_c(_f4,{deps:_f5,def:def,cjs:{id:_f4.mid,uri:_f4.url,exports:(_f4.result={}),setExports:function(_f6){_f4.cjs.exports=_f6;},config:function(){return _f4.config;}}});for(var i=0;i<_f5.length;i++){_f5[i]=_31(_f5[i],_f4);}if(1&&_25&&!_8c[mid]){_75(_f4);_30.push(_f4);_7a();}_33(_f4);if(!_6(def)&&!_f5.length){_f4.result=def;_35(_f4);}return _f4;},_79=function(_f7,_f8){var _f9=[],_fa,_fb;while(_8b.length){_fb=_8b.shift();_f8&&(_fb[0]=_f8.shift());_fa=(_fb[0]&&_31(_fb[0]))||_f7;_f9.push([_fa,_fb[1],_fb[2]]);}_56(_f7);_9(_f9,function(_fc){_75(_f3.apply(null,_fc));});};}var _fd=0,_91=_3,_8f=_3;if(1){_91=function(){_fd&&clearTimeout(_fd);_fd=0;},_8f=function(){_91();if(req.waitms){_fd=window.setTimeout(function(){_91();_34(_44,_f("timeout",_8c));},req.waitms);}};}if(1){has.add("ie-event-behavior",!!doc.attachEvent&&(typeof opera==="undefined"||opera.toString()!="[object Opera]"));}if(1&&(1||1)){var _fe=function(_ff,_100,_101,_102){if(!has("ie-event-behavior")){_ff.addEventListener(_100,_102,false);return function(){_ff.removeEventListener(_100,_102,false);};}else{_ff.attachEvent(_101,_102);return function(){_ff.detachEvent(_101,_102);};}},_103=_fe(window,"load","onload",function(){req.pageLoaded=1;doc.readyState!="complete"&&(doc.readyState="complete");_103();});if(1){var _104=doc.getElementsByTagName("script")[0],_105=_104.parentNode;req.injectUrl=function(url,_106,_107){var node=_107.node=doc.createElement("script"),_108=function(e){e=e||window.event;var node=e.target||e.srcElement;if(e.type==="load"||/complete|loaded/.test(node.readyState)){_109();_10a();_106&&_106();}},_109=_fe(node,"load","onreadystatechange",_108),_10a=_fe(node,"error","onerror",function(e){_109();_10a();_34(_44,_f("scriptError",[url,e]));});node.type="text/javascript";node.charset="utf-8";node.src=url;_105.insertBefore(node,_104);return node;};}}if(1){req.log=function(){try{for(var i=0;i<arguments.length;i++){}}catch(e){}};}else{req.log=_3;}if(0){var _10b=req.trace=function(_10c,args){if(_10b.on&&_10b.group[_10c]){_34("trace",[_10c,args]);for(var arg,dump=[],text="trace:"+_10c+(args.length?(":"+args[0]):""),i=1;i<args.length;){arg=args[i++];if(_7(arg)){text+=", "+arg;}else{dump.push(arg);}}req.log(text);dump.length&&dump.push(".");req.log.apply(req,dump);}};_c(_10b,{on:1,group:{},set:function(_10d,_10e){if(_7(_10d)){_10b.group[_10d]=_10e;}else{_c(_10b.group,_10d);}}});_10b.set(_c(_c(_c({},_2.trace),_1.trace),_55.trace));on("config",function(_10f){_10f.trace&&_10b.set(_10f.trace);});}else{req.trace=_3;}var def=function(mid,_110,_111){var _112=arguments.length,_113=["require","exports","module"],args=[0,mid,_110];if(_112==1){args=[0,(_6(mid)?_113:[]),mid];}else{if(_112==2&&_7(mid)){args=[mid,(_6(_110)?_113:[]),_110];}else{if(_112==3){args=[mid,_110,_111];}}}if(0&&args[1]===_113){args[2].toString().replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,"").replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g,function(_114,dep){args[1].push(dep);});}req.trace("loader-define",args.slice(0,2));var _115=args[0]&&_31(args[0]),_116;if(_115&&!_8c[_115.mid]){_75(_f3(_115,args[1],args[2]));}else{if(!has("ie-event-behavior")||!1||_e8){_8b.push(args);}else{_115=_115||_7b;if(!_115){for(mid in _8c){_116=_2f[mid];if(_116&&_116.node&&_116.node.readyState==="interactive"){_115=_116;break;}}if(0&&!_115){for(var i=0;i<_73.length;i++){_115=_73[i];if(_115.node&&_115.node.readyState==="interactive"){break;}_115=0;}}}if(0&&_8(_115)){_75(_f3(_31(_115.shift()),args[1],args[2]));if(!_115.length){_73.splice(i,1);}}else{if(_115){_56(_115);_75(_f3(_115,args[1],args[2]));}else{_34(_44,_f("ieDefineFailed",args[0]));}}_7a();}}};def.amd={vendor:"dojotoolkit.org"};if(0){req.def=def;}_c(_c(req,_2.loaderPatch),_1.loaderPatch);on(_44,function(arg){try{console.error(arg);if(arg instanceof Error){for(var p in arg){}}}catch(e){}});_c(req,{uid:uid,cache:_52,packs:_4f});if(0){_c(req,{paths:_4d,aliases:_4c,modules:_2f,legacyMode:_25,execQ:_30,defQ:_8b,waiting:_8c,packs:_4f,mapProgs:_50,pathsMapProg:_4e,listenerQueues:_43,computeMapProg:_5e,runMapProg:_93,compactPath:_95,getModuleInfo:_9b});}if(_17.define){if(1){_34(_44,_f("defineAlreadyDefined",0));}return;}else{_17.define=def;_17.require=req;if(0){require=req;}}if(0&&req.combo&&req.combo.plugins){var _117=req.combo.plugins,_118;for(_118 in _117){_c(_c(_31(_118),_117[_118]),{isCombo:1,executed:"executed",load:1});}}if(1){var _119=_55.deps||_1.deps||_2.deps,_11a=_55.callback||_1.callback||_2.callback;req.boot=(_119||_11a)?[_119||[],_11a]:0;}if(!1){!req.async&&req(["dojo"]);req.boot&&req.apply(null,req.boot);}})(this.dojoConfig||this.djConfig||this.require||{},{async:0,hasCache:{"config-selectorEngine":"acme","config-tlmSiblingOfDojo":1,"dojo-built":1,"dojo-loader":1,dom:1,"host-browser":1},packages:[{location:"../dijit",name:"dijit"},{location:"../dojox",name:"dojox"},{location:".",name:"dojo"}]});require({cache:{"dojo/_base/fx":function(){define(["./kernel","./config","./lang","../Evented","./Color","./connect","./sniff","../dom","../dom-style"],function(dojo,_11b,lang,_11c,_11d,_11e,has,dom,_11f){var _120=lang.mixin;var _121={};var _122=_121._Line=function(_123,end){this.start=_123;this.end=end;};_122.prototype.getValue=function(n){return ((this.end-this.start)*n)+this.start;};var _124=_121.Animation=function(args){_120(this,args);if(lang.isArray(this.curve)){this.curve=new _122(this.curve[0],this.curve[1]);}};_124.prototype=new _11c();lang.extend(_124,{duration:350,repeat:0,rate:20,_percent:0,_startRepeatCount:0,_getStep:function(){var _125=this._percent,_126=this.easing;return _126?_126(_125):_125;},_fire:function(evt,args){var a=args||[];if(this[evt]){if(_11b.debugAtAllCosts){this[evt].apply(this,a);}else{try{this[evt].apply(this,a);}catch(e){console.error("exception in animation handler for:",evt);console.error(e);}}}return this;},play:function(_127,_128){var _129=this;if(_129._delayTimer){_129._clearTimer();}if(_128){_129._stopTimer();_129._active=_129._paused=false;_129._percent=0;}else{if(_129._active&&!_129._paused){return _129;}}_129._fire("beforeBegin",[_129.node]);var de=_127||_129.delay,_12a=lang.hitch(_129,"_play",_128);if(de>0){_129._delayTimer=setTimeout(_12a,de);return _129;}_12a();return _129;},_play:function(_12b){var _12c=this;if(_12c._delayTimer){_12c._clearTimer();}_12c._startTime=new Date().valueOf();if(_12c._paused){_12c._startTime-=_12c.duration*_12c._percent;}_12c._active=true;_12c._paused=false;var _12d=_12c.curve.getValue(_12c._getStep());if(!_12c._percent){if(!_12c._startRepeatCount){_12c._startRepeatCount=_12c.repeat;}_12c._fire("onBegin",[_12d]);}_12c._fire("onPlay",[_12d]);_12c._cycle();return _12c;},pause:function(){var _12e=this;if(_12e._delayTimer){_12e._clearTimer();}_12e._stopTimer();if(!_12e._active){return _12e;}_12e._paused=true;_12e._fire("onPause",[_12e.curve.getValue(_12e._getStep())]);return _12e;},gotoPercent:function(_12f,_130){var _131=this;_131._stopTimer();_131._active=_131._paused=true;_131._percent=_12f;if(_130){_131.play();}return _131;},stop:function(_132){var _133=this;if(_133._delayTimer){_133._clearTimer();}if(!_133._timer){return _133;}_133._stopTimer();if(_132){_133._percent=1;}_133._fire("onStop",[_133.curve.getValue(_133._getStep())]);_133._active=_133._paused=false;return _133;},status:function(){if(this._active){return this._paused?"paused":"playing";}return "stopped";},_cycle:function(){var _134=this;if(_134._active){var curr=new Date().valueOf();var step=_134.duration===0?1:(curr-_134._startTime)/(_134.duration);if(step>=1){step=1;}_134._percent=step;if(_134.easing){step=_134.easing(step);}_134._fire("onAnimate",[_134.curve.getValue(step)]);if(_134._percent<1){_134._startTimer();}else{_134._active=false;if(_134.repeat>0){_134.repeat--;_134.play(null,true);}else{if(_134.repeat==-1){_134.play(null,true);}else{if(_134._startRepeatCount){_134.repeat=_134._startRepeatCount;_134._startRepeatCount=0;}}}_134._percent=0;_134._fire("onEnd",[_134.node]);!_134.repeat&&_134._stopTimer();}}return _134;},_clearTimer:function(){clearTimeout(this._delayTimer);delete this._delayTimer;}});var ctr=0,_135=null,_136={run:function(){}};lang.extend(_124,{_startTimer:function(){if(!this._timer){this._timer=_11e.connect(_136,"run",this,"_cycle");ctr++;}if(!_135){_135=setInterval(lang.hitch(_136,"run"),this.rate);}},_stopTimer:function(){if(this._timer){_11e.disconnect(this._timer);this._timer=null;ctr--;}if(ctr<=0){clearInterval(_135);_135=null;ctr=0;}}});var _137=has("ie")?function(node){var ns=node.style;if(!ns.width.length&&_11f.get(node,"width")=="auto"){ns.width="auto";}}:function(){};_121._fade=function(args){args.node=dom.byId(args.node);var _138=_120({properties:{}},args),_139=(_138.properties.opacity={});_139.start=!("start" in _138)?function(){return +_11f.get(_138.node,"opacity")||0;}:_138.start;_139.end=_138.end;var anim=_121.animateProperty(_138);_11e.connect(anim,"beforeBegin",lang.partial(_137,_138.node));return anim;};_121.fadeIn=function(args){return _121._fade(_120({end:1},args));};_121.fadeOut=function(args){return _121._fade(_120({end:0},args));};_121._defaultEasing=function(n){return 0.5+((Math.sin((n+1.5)*Math.PI))/2);};var _13a=function(_13b){this._properties=_13b;for(var p in _13b){var prop=_13b[p];if(prop.start instanceof _11d){prop.tempColor=new _11d();}}};_13a.prototype.getValue=function(r){var ret={};for(var p in this._properties){var prop=this._properties[p],_13c=prop.start;if(_13c instanceof _11d){ret[p]=_11d.blendColors(_13c,prop.end,r,prop.tempColor).toCss();}else{if(!lang.isArray(_13c)){ret[p]=((prop.end-_13c)*r)+_13c+(p!="opacity"?prop.units||"px":0);}}}return ret;};_121.animateProperty=function(args){var n=args.node=dom.byId(args.node);if(!args.easing){args.easing=dojo._defaultEasing;}var anim=new _124(args);_11e.connect(anim,"beforeBegin",anim,function(){var pm={};for(var p in this.properties){if(p=="width"||p=="height"){this.node.display="block";}var prop=this.properties[p];if(lang.isFunction(prop)){prop=prop(n);}prop=pm[p]=_120({},(lang.isObject(prop)?prop:{end:prop}));if(lang.isFunction(prop.start)){prop.start=prop.start(n);}if(lang.isFunction(prop.end)){prop.end=prop.end(n);}var _13d=(p.toLowerCase().indexOf("color")>=0);function _13e(node,p){var v={height:node.offsetHeight,width:node.offsetWidth}[p];if(v!==undefined){return v;}v=_11f.get(node,p);return (p=="opacity")?+v:(_13d?v:parseFloat(v));};if(!("end" in prop)){prop.end=_13e(n,p);}else{if(!("start" in prop)){prop.start=_13e(n,p);}}if(_13d){prop.start=new _11d(prop.start);prop.end=new _11d(prop.end);}else{prop.start=(p=="opacity")?+prop.start:parseFloat(prop.start);}}this.curve=new _13a(pm);});_11e.connect(anim,"onAnimate",lang.hitch(_11f,"set",anim.node));return anim;};_121.anim=function(node,_13f,_140,_141,_142,_143){return _121.animateProperty({node:node,duration:_140||_124.prototype.duration,properties:_13f,easing:_141,onEnd:_142}).play(_143||0);};if(1){_120(dojo,_121);dojo._Animation=_124;}return _121;});},"dojo/dom-form":function(){define(["./_base/lang","./dom","./io-query","./json"],function(lang,dom,ioq,json){function _144(obj,name,_145){if(_145===null){return;}var val=obj[name];if(typeof val=="string"){obj[name]=[val,_145];}else{if(lang.isArray(val)){val.push(_145);}else{obj[name]=_145;}}};var _146="file|submit|image|reset|button";var form={fieldToObject:function fieldToObject(_147){var ret=null;_147=dom.byId(_147);if(_147){var _148=_147.name,type=(_147.type||"").toLowerCase();if(_148&&type&&!_147.disabled){if(type=="radio"||type=="checkbox"){if(_147.checked){ret=_147.value;}}else{if(_147.multiple){ret=[];var _149=[_147.firstChild];while(_149.length){for(var node=_149.pop();node;node=node.nextSibling){if(node.nodeType==1&&node.tagName.toLowerCase()=="option"){if(node.selected){ret.push(node.value);}}else{if(node.nextSibling){_149.push(node.nextSibling);}if(node.firstChild){_149.push(node.firstChild);}break;}}}}else{ret=_147.value;}}}}return ret;},toObject:function formToObject(_14a){var ret={},_14b=dom.byId(_14a).elements;for(var i=0,l=_14b.length;i<l;++i){var item=_14b[i],_14c=item.name,type=(item.type||"").toLowerCase();if(_14c&&type&&_146.indexOf(type)<0&&!item.disabled){_144(ret,_14c,form.fieldToObject(item));if(type=="image"){ret[_14c+".x"]=ret[_14c+".y"]=ret[_14c].x=ret[_14c].y=0;}}}return ret;},toQuery:function formToQuery(_14d){return ioq.objectToQuery(form.toObject(_14d));},toJson:function formToJson(_14e,_14f){return json.stringify(form.toObject(_14e),null,_14f?4:0);}};return form;});},"dojo/i18n":function(){define(["./_base/kernel","require","./has","./_base/array","./_base/config","./_base/lang","./_base/xhr","./json","module"],function(dojo,_150,has,_151,_152,lang,xhr,json,_153){has.add("dojo-preload-i18n-Api",1);1||has.add("dojo-v1x-i18n-Api",1);var _154=dojo.i18n={},_155=/(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,_156=function(root,_157,_158,_159){for(var _15a=[_158+_159],_15b=_157.split("-"),_15c="",i=0;i<_15b.length;i++){_15c+=(_15c?"-":"")+_15b[i];if(!root||root[_15c]){_15a.push(_158+_15c+"/"+_159);}}return _15a;},_15d={},_15e=function(_15f,_160,_161){_161=_161?_161.toLowerCase():dojo.locale;_15f=_15f.replace(/\./g,"/");_160=_160.replace(/\./g,"/");return (/root/i.test(_161))?(_15f+"/nls/"+_160):(_15f+"/nls/"+_161+"/"+_160);},_162=dojo.getL10nName=function(_163,_164,_165){return _163=_153.id+"!"+_15e(_163,_164,_165);},_166=function(_167,_168,_169,_16a,_16b,load){_167([_168],function(root){var _16c=lang.clone(root.root),_16d=_156(!root._v1x&&root,_16b,_169,_16a);_167(_16d,function(){for(var i=1;i<_16d.length;i++){_16c=lang.mixin(lang.clone(_16c),arguments[i]);}var _16e=_168+"/"+_16b;_15d[_16e]=_16c;load();});});},_16f=function(id,_170){return /^\./.test(id)?_170(id):id;},_171=function(_172){var list=_152.extraLocale||[];list=lang.isArray(list)?list:[list];list.push(_172);return list;},load=function(id,_173,load){if(has("dojo-preload-i18n-Api")){var _174=id.split("*"),_175=_174[1]=="preload";if(_175){if(!_15d[id]){_15d[id]=1;_176(_174[2],json.parse(_174[3]),1,_173);}load(1);}if(_175||_177(id,_173,load)){return;}}var _178=_155.exec(id),_179=_178[1]+"/",_17a=_178[5]||_178[4],_17b=_179+_17a,_17c=(_178[5]&&_178[4]),_17d=_17c||dojo.locale,_17e=_17b+"/"+_17d,_17f=_17c?[_17d]:_171(_17d),_180=_17f.length,_181=function(){if(!--_180){load(lang.delegate(_15d[_17e]));}};_151.forEach(_17f,function(_182){var _183=_17b+"/"+_182;if(has("dojo-preload-i18n-Api")){_184(_183);}if(!_15d[_183]){_166(_173,_17b,_179,_17a,_182,_181);}else{_181();}});};if(has("dojo-unit-tests")){var _185=_154.unitTests=[];}if(has("dojo-preload-i18n-Api")||1){var _186=_154.normalizeLocale=function(_187){var _188=_187?_187.toLowerCase():dojo.locale;return _188=="root"?"ROOT":_188;},isXd=function(mid,_189){return (1&&1)?_189.isXdUrl(_150.toUrl(mid+".js")):true;},_18a=0,_18b=[],_176=_154._preloadLocalizations=function(_18c,_18d,_18e,_18f){_18f=_18f||_150;function _190(mid,_191){if(isXd(mid,_18f)||_18e){_18f([mid],_191);}else{_19b([mid],_191,_18f);}};function _192(_193,func){var _194=_193.split("-");while(_194.length){if(func(_194.join("-"))){return;}_194.pop();}func("ROOT");};function _195(_196){_196=_186(_196);_192(_196,function(loc){if(_151.indexOf(_18d,loc)>=0){var mid=_18c.replace(/\./g,"/")+"_"+loc;_18a++;_190(mid,function(_197){for(var p in _197){_15d[_150.toAbsMid(p)+"/"+loc]=_197[p];}--_18a;while(!_18a&&_18b.length){load.apply(null,_18b.shift());}});return true;}return false;});};_195();_151.forEach(dojo.config.extraLocale,_195);},_177=function(id,_198,load){if(_18a){_18b.push([id,_198,load]);}return _18a;},_184=function(){};}if(1){var _199={},_19a=new Function("__bundle","__checkForLegacyModules","__mid","__amdValue","var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;},"+"\t require = function(){define.called = 1;};"+"try{"+"define.called = 0;"+"eval(__bundle);"+"if(define.called==1)"+"return __amdValue;"+"if((__checkForLegacyModules = __checkForLegacyModules(__mid)))"+"return __checkForLegacyModules;"+"}catch(e){}"+"try{"+"return eval('('+__bundle+')');"+"}catch(e){"+"return e;"+"}"),_19b=function(deps,_19c,_19d){var _19e=[];_151.forEach(deps,function(mid){var url=_19d.toUrl(mid+".js");function load(text){var _19f=_19a(text,_184,mid,_199);if(_19f===_199){_19e.push(_15d[url]=_199.result);}else{if(_19f instanceof Error){console.error("failed to evaluate i18n bundle; url="+url,_19f);_19f={};}_19e.push(_15d[url]=(/nls\/[^\/]+\/[^\/]+$/.test(url)?_19f:{root:_19f,_v1x:1}));}};if(_15d[url]){_19e.push(_15d[url]);}else{var _1a0=_19d.syncLoadNls(mid);if(_1a0){_19e.push(_1a0);}else{if(!xhr){try{_19d.getText(url,true,load);}catch(e){_19e.push(_15d[url]={});}}else{xhr.get({url:url,sync:true,load:load,error:function(){_19e.push(_15d[url]={});}});}}}});_19c&&_19c.apply(null,_19e);};_184=function(_1a1){for(var _1a2,_1a3=_1a1.split("/"),_1a4=dojo.global[_1a3[0]],i=1;_1a4&&i<_1a3.length-1;_1a4=_1a4[_1a3[i++]]){}if(_1a4){_1a2=_1a4[_1a3[i]];if(!_1a2){_1a2=_1a4[_1a3[i].replace(/-/g,"_")];}if(_1a2){_15d[_1a1]=_1a2;}}return _1a2;};_154.getLocalization=function(_1a5,_1a6,_1a7){var _1a8,_1a9=_15e(_1a5,_1a6,_1a7);load(_1a9,(!isXd(_1a9,_150)?function(deps,_1aa){_19b(deps,_1aa,_150);}:_150),function(_1ab){_1a8=_1ab;});return _1a8;};if(has("dojo-unit-tests")){_185.push(function(doh){doh.register("tests.i18n.unit",function(t){var _1ac;_1ac=_19a("{prop:1}",_184,"nonsense",_199);t.is({prop:1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("({prop:1})",_184,"nonsense",_199);t.is({prop:1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("{'prop-x':1}",_184,"nonsense",_199);t.is({"prop-x":1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("({'prop-x':1})",_184,"nonsense",_199);t.is({"prop-x":1},_1ac);t.is(undefined,_1ac[1]);_1ac=_19a("define({'prop-x':1})",_184,"nonsense",_199);t.is(_199,_1ac);t.is({"prop-x":1},_199.result);_1ac=_19a("define('some/module', {'prop-x':1})",_184,"nonsense",_199);t.is(_199,_1ac);t.is({"prop-x":1},_199.result);_1ac=_19a("this is total nonsense and should throw an error",_184,"nonsense",_199);t.is(_1ac instanceof Error,true);});});}}return lang.mixin(_154,{dynamic:true,normalize:_16f,load:load,cache:_15d});});},"dojo/promise/tracer":function(){define(["../_base/lang","./Promise","../Evented"],function(lang,_1ad,_1ae){"use strict";var _1af=new _1ae;var emit=_1af.emit;_1af.emit=null;function _1b0(args){setTimeout(function(){emit.apply(_1af,args);},0);};_1ad.prototype.trace=function(){var args=lang._toArray(arguments);this.then(function(_1b1){_1b0(["resolved",_1b1].concat(args));},function(_1b2){_1b0(["rejected",_1b2].concat(args));},function(_1b3){_1b0(["progress",_1b3].concat(args));});return this;};_1ad.prototype.traceRejected=function(){var args=lang._toArray(arguments);this.otherwise(function(_1b4){_1b0(["rejected",_1b4].concat(args));});return this;};return _1af;});},"dojo/errors/RequestError":function(){define(["./create"],function(_1b5){return _1b5("RequestError",function(_1b6,_1b7){this.response=_1b7;});});},"dojo/_base/html":function(){define("dojo/_base/html",["./kernel","../dom","../dom-style","../dom-attr","../dom-prop","../dom-class","../dom-construct","../dom-geometry"],function(dojo,dom,_1b8,attr,prop,cls,ctr,geom){dojo.byId=dom.byId;dojo.isDescendant=dom.isDescendant;dojo.setSelectable=dom.setSelectable;dojo.getAttr=attr.get;dojo.setAttr=attr.set;dojo.hasAttr=attr.has;dojo.removeAttr=attr.remove;dojo.getNodeProp=attr.getNodeProp;dojo.attr=function(node,name,_1b9){if(arguments.length==2){return attr[typeof name=="string"?"get":"set"](node,name);}return attr.set(node,name,_1b9);};dojo.hasClass=cls.contains;dojo.addClass=cls.add;dojo.removeClass=cls.remove;dojo.toggleClass=cls.toggle;dojo.replaceClass=cls.replace;dojo._toDom=dojo.toDom=ctr.toDom;dojo.place=ctr.place;dojo.create=ctr.create;dojo.empty=function(node){ctr.empty(node);};dojo._destroyElement=dojo.destroy=function(node){ctr.destroy(node);};dojo._getPadExtents=dojo.getPadExtents=geom.getPadExtents;dojo._getBorderExtents=dojo.getBorderExtents=geom.getBorderExtents;dojo._getPadBorderExtents=dojo.getPadBorderExtents=geom.getPadBorderExtents;dojo._getMarginExtents=dojo.getMarginExtents=geom.getMarginExtents;dojo._getMarginSize=dojo.getMarginSize=geom.getMarginSize;dojo._getMarginBox=dojo.getMarginBox=geom.getMarginBox;dojo.setMarginBox=geom.setMarginBox;dojo._getContentBox=dojo.getContentBox=geom.getContentBox;dojo.setContentSize=geom.setContentSize;dojo._isBodyLtr=dojo.isBodyLtr=geom.isBodyLtr;dojo._docScroll=dojo.docScroll=geom.docScroll;dojo._getIeDocumentElementOffset=dojo.getIeDocumentElementOffset=geom.getIeDocumentElementOffset;dojo._fixIeBiDiScrollLeft=dojo.fixIeBiDiScrollLeft=geom.fixIeBiDiScrollLeft;dojo.position=geom.position;dojo.marginBox=function marginBox(node,box){return box?geom.setMarginBox(node,box):geom.getMarginBox(node);};dojo.contentBox=function contentBox(node,box){return box?geom.setContentSize(node,box):geom.getContentBox(node);};dojo.coords=function(node,_1ba){dojo.deprecated("dojo.coords()","Use dojo.position() or dojo.marginBox().");node=dom.byId(node);var s=_1b8.getComputedStyle(node),mb=geom.getMarginBox(node,s);var abs=geom.position(node,_1ba);mb.x=abs.x;mb.y=abs.y;return mb;};dojo.getProp=prop.get;dojo.setProp=prop.set;dojo.prop=function(node,name,_1bb){if(arguments.length==2){return prop[typeof name=="string"?"get":"set"](node,name);}return prop.set(node,name,_1bb);};dojo.getStyle=_1b8.get;dojo.setStyle=_1b8.set;dojo.getComputedStyle=_1b8.getComputedStyle;dojo.__toPixelValue=dojo.toPixelValue=_1b8.toPixelValue;dojo.style=function(node,name,_1bc){switch(arguments.length){case 1:return _1b8.get(node);case 2:return _1b8[typeof name=="string"?"get":"set"](node,name);}return _1b8.set(node,name,_1bc);};return dojo;});},"dojo/_base/kernel":function(){define(["../has","./config","require","module"],function(has,_1bd,_1be,_1bf){var i,p,_1c0={},_1c1={},dojo={config:_1bd,global:this,dijit:_1c0,dojox:_1c1};var _1c2={dojo:["dojo",dojo],dijit:["dijit",_1c0],dojox:["dojox",_1c1]},_1c3=(_1be.map&&_1be.map[_1bf.id.match(/[^\/]+/)[0]]),item;for(p in _1c3){if(_1c2[p]){_1c2[p][0]=_1c3[p];}else{_1c2[p]=[_1c3[p],{}];}}for(p in _1c2){item=_1c2[p];item[1]._scopeName=item[0];if(!_1bd.noGlobals){this[item[0]]=item[1];}}dojo.scopeMap=_1c2;dojo.baseUrl=dojo.config.baseUrl=_1be.baseUrl;dojo.isAsync=!1||_1be.async;dojo.locale=_1bd.locale;var rev="$Rev: 29458 $".match(/\d+/);dojo.version={major:1,minor:8,patch:0,flag:"",revision:rev?+rev[0]:NaN,toString:function(){var v=dojo.version;return v.major+"."+v.minor+"."+v.patch+v.flag+" ("+v.revision+")";}};1||has.add("extend-dojo",1);(Function("d","d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);if(0){dojo.exit=function(_1c4){quit(_1c4);};}else{dojo.exit=function(){};}1||has.add("dojo-guarantee-console",1);if(1){typeof console!="undefined"||(console={});var cn=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","profile","profileEnd","time","timeEnd","trace","warn","log"];var tn;i=0;while((tn=cn[i++])){if(!console[tn]){(function(){var tcn=tn+"";console[tcn]=("log" in console)?function(){var a=Array.apply({},arguments);a.unshift(tcn+":");console["log"](a.join(" "));}:function(){};console[tcn]._fake=true;})();}}}has.add("dojo-debug-messages",!!_1bd.isDebug);dojo.deprecated=dojo.experimental=function(){};if(has("dojo-debug-messages")){dojo.deprecated=function(_1c5,_1c6,_1c7){var _1c8="DEPRECATED: "+_1c5;if(_1c6){_1c8+=" "+_1c6;}if(_1c7){_1c8+=" -- will be removed in version: "+_1c7;}console.warn(_1c8);};dojo.experimental=function(_1c9,_1ca){var _1cb="EXPERIMENTAL: "+_1c9+" -- APIs subject to change without notice.";if(_1ca){_1cb+=" "+_1ca;}console.warn(_1cb);};}1||has.add("dojo-modulePaths",1);if(1){if(_1bd.modulePaths){dojo.deprecated("dojo.modulePaths","use paths configuration");var _1cc={};for(p in _1bd.modulePaths){_1cc[p.replace(/\./g,"/")]=_1bd.modulePaths[p];}_1be({paths:_1cc});}}1||has.add("dojo-moduleUrl",1);if(1){dojo.moduleUrl=function(_1cd,url){dojo.deprecated("dojo.moduleUrl()","use require.toUrl","2.0");var _1ce=null;if(_1cd){_1ce=_1be.toUrl(_1cd.replace(/\./g,"/")+(url?("/"+url):"")+"/*.*").replace(/\/\*\.\*/,"")+(url?"":"/");}return _1ce;};}dojo._hasResource={};return dojo;});},"dojo/io-query":function(){define(["./_base/lang"],function(lang){var _1cf={};return {objectToQuery:function objectToQuery(map){var enc=encodeURIComponent,_1d0=[];for(var name in map){var _1d1=map[name];if(_1d1!=_1cf[name]){var _1d2=enc(name)+"=";if(lang.isArray(_1d1)){for(var i=0,l=_1d1.length;i<l;++i){_1d0.push(_1d2+enc(_1d1[i]));}}else{_1d0.push(_1d2+enc(_1d1));}}}return _1d0.join("&");},queryToObject:function queryToObject(str){var dec=decodeURIComponent,qp=str.split("&"),ret={},name,val;for(var i=0,l=qp.length,item;i<l;++i){item=qp[i];if(item.length){var s=item.indexOf("=");if(s<0){name=dec(item);val="";}else{name=dec(item.slice(0,s));val=dec(item.slice(s+1));}if(typeof ret[name]=="string"){ret[name]=[ret[name]];}if(lang.isArray(ret[name])){ret[name].push(val);}else{ret[name]=val;}}}return ret;}};});},"dojo/_base/Deferred":function(){define(["./kernel","../Deferred","../promise/Promise","../errors/CancelError","../has","./lang","../when"],function(dojo,_1d3,_1d4,_1d5,has,lang,when){var _1d6=function(){};var _1d7=Object.freeze||function(){};var _1d8=dojo.Deferred=function(_1d9){var _1da,_1db,_1dc,head,_1dd;var _1de=(this.promise=new _1d4());function _1df(_1e0){if(_1db){throw new Error("This deferred has already been resolved");}_1da=_1e0;_1db=true;_1e1();};function _1e1(){var _1e2;while(!_1e2&&_1dd){var _1e3=_1dd;_1dd=_1dd.next;if((_1e2=(_1e3.progress==_1d6))){_1db=false;}var func=(_1dc?_1e3.error:_1e3.resolved);if(has("config-useDeferredInstrumentation")){if(_1dc&&_1d3.instrumentRejected){_1d3.instrumentRejected(_1da,!!func);}}if(func){try{var _1e4=func(_1da);if(_1e4&&typeof _1e4.then==="function"){_1e4.then(lang.hitch(_1e3.deferred,"resolve"),lang.hitch(_1e3.deferred,"reject"),lang.hitch(_1e3.deferred,"progress"));continue;}var _1e5=_1e2&&_1e4===undefined;if(_1e2&&!_1e5){_1dc=_1e4 instanceof Error;}_1e3.deferred[_1e5&&_1dc?"reject":"resolve"](_1e5?_1da:_1e4);}catch(e){_1e3.deferred.reject(e);}}else{if(_1dc){_1e3.deferred.reject(_1da);}else{_1e3.deferred.resolve(_1da);}}}};this.resolve=this.callback=function(_1e6){this.fired=0;this.results=[_1e6,null];_1df(_1e6);};this.reject=this.errback=function(_1e7){_1dc=true;this.fired=1;if(has("config-useDeferredInstrumentation")){if(_1d3.instrumentRejected){_1d3.instrumentRejected(_1e7,!!_1dd);}}_1df(_1e7);this.results=[null,_1e7];};this.progress=function(_1e8){var _1e9=_1dd;while(_1e9){var _1ea=_1e9.progress;_1ea&&_1ea(_1e8);_1e9=_1e9.next;}};this.addCallbacks=function(_1eb,_1ec){this.then(_1eb,_1ec,_1d6);return this;};_1de.then=this.then=function(_1ed,_1ee,_1ef){var _1f0=_1ef==_1d6?this:new _1d8(_1de.cancel);var _1f1={resolved:_1ed,error:_1ee,progress:_1ef,deferred:_1f0};if(_1dd){head=head.next=_1f1;}else{_1dd=head=_1f1;}if(_1db){_1e1();}return _1f0.promise;};var _1f2=this;_1de.cancel=this.cancel=function(){if(!_1db){var _1f3=_1d9&&_1d9(_1f2);if(!_1db){if(!(_1f3 instanceof Error)){_1f3=new _1d5(_1f3);}_1f3.log=false;_1f2.reject(_1f3);}}};_1d7(_1de);};lang.extend(_1d8,{addCallback:function(_1f4){return this.addCallbacks(lang.hitch.apply(dojo,arguments));},addErrback:function(_1f5){return this.addCallbacks(null,lang.hitch.apply(dojo,arguments));},addBoth:function(_1f6){var _1f7=lang.hitch.apply(dojo,arguments);return this.addCallbacks(_1f7,_1f7);},fired:-1});_1d8.when=dojo.when=when;return _1d8;});},"dojo/NodeList-dom":function(){define(["./_base/kernel","./query","./_base/array","./_base/lang","./dom-class","./dom-construct","./dom-geometry","./dom-attr","./dom-style"],function(dojo,_1f8,_1f9,lang,_1fa,_1fb,_1fc,_1fd,_1fe){var _1ff=function(a){return a.length==1&&(typeof a[0]=="string");};var _200=function(node){var p=node.parentNode;if(p){p.removeChild(node);}};var _201=_1f8.NodeList,awc=_201._adaptWithCondition,aafe=_201._adaptAsForEach,aam=_201._adaptAsMap;function _202(_203){return function(node,name,_204){if(arguments.length==2){return _203[typeof name=="string"?"get":"set"](node,name);}return _203.set(node,name,_204);};};lang.extend(_201,{_normalize:function(_205,_206){var _207=_205.parse===true;if(typeof _205.template=="string"){var _208=_205.templateFunc||(dojo.string&&dojo.string.substitute);_205=_208?_208(_205.template,_205):_205;}var type=(typeof _205);if(type=="string"||type=="number"){_205=_1fb.toDom(_205,(_206&&_206.ownerDocument));if(_205.nodeType==11){_205=lang._toArray(_205.childNodes);}else{_205=[_205];}}else{if(!lang.isArrayLike(_205)){_205=[_205];}else{if(!lang.isArray(_205)){_205=lang._toArray(_205);}}}if(_207){_205._runParse=true;}return _205;},_cloneNode:function(node){return node.cloneNode(true);},_place:function(ary,_209,_20a,_20b){if(_209.nodeType!=1&&_20a=="only"){return;}var _20c=_209,_20d;var _20e=ary.length;for(var i=_20e-1;i>=0;i--){var node=(_20b?this._cloneNode(ary[i]):ary[i]);if(ary._runParse&&dojo.parser&&dojo.parser.parse){if(!_20d){_20d=_20c.ownerDocument.createElement("div");}_20d.appendChild(node);dojo.parser.parse(_20d);node=_20d.firstChild;while(_20d.firstChild){_20d.removeChild(_20d.firstChild);}}if(i==_20e-1){_1fb.place(node,_20c,_20a);}else{_20c.parentNode.insertBefore(node,_20c);}_20c=node;}},position:aam(_1fc.position),attr:awc(_202(_1fd),_1ff),style:awc(_202(_1fe),_1ff),addClass:aafe(_1fa.add),removeClass:aafe(_1fa.remove),toggleClass:aafe(_1fa.toggle),replaceClass:aafe(_1fa.replace),empty:aafe(_1fb.empty),removeAttr:aafe(_1fd.remove),marginBox:aam(_1fc.getMarginBox),place:function(_20f,_210){var item=_1f8(_20f)[0];return this.forEach(function(node){_1fb.place(node,item,_210);});},orphan:function(_211){return (_211?_1f8._filterResult(this,_211):this).forEach(_200);},adopt:function(_212,_213){return _1f8(_212).place(this[0],_213)._stash(this);},query:function(_214){if(!_214){return this;}var ret=new _201;this.map(function(node){_1f8(_214,node).forEach(function(_215){if(_215!==undefined){ret.push(_215);}});});return ret._stash(this);},filter:function(_216){var a=arguments,_217=this,_218=0;if(typeof _216=="string"){_217=_1f8._filterResult(this,a[0]);if(a.length==1){return _217._stash(this);}_218=1;}return this._wrap(_1f9.filter(_217,a[_218],a[_218+1]),this);},addContent:function(_219,_21a){_219=this._normalize(_219,this[0]);for(var i=0,node;(node=this[i]);i++){this._place(_219,node,_21a,i>0);}return this;}});return _201;});},"dojo/query":function(){define(["./_base/kernel","./has","./dom","./on","./_base/array","./_base/lang","./selector/_loader","./selector/_loader!default"],function(dojo,has,dom,on,_21b,lang,_21c,_21d){"use strict";has.add("array-extensible",function(){return lang.delegate([],{length:1}).length==1&&!has("bug-for-in-skips-shadowed");});var ap=Array.prototype,aps=ap.slice,apc=ap.concat,_21e=_21b.forEach;var tnl=function(a,_21f,_220){var _221=new (_220||this._NodeListCtor||nl)(a);return _21f?_221._stash(_21f):_221;};var _222=function(f,a,o){a=[0].concat(aps.call(a,0));o=o||dojo.global;return function(node){a[0]=node;return f.apply(o,a);};};var _223=function(f,o){return function(){this.forEach(_222(f,arguments,o));return this;};};var _224=function(f,o){return function(){return this.map(_222(f,arguments,o));};};var _225=function(f,o){return function(){return this.filter(_222(f,arguments,o));};};var _226=function(f,g,o){return function(){var a=arguments,body=_222(f,a,o);if(g.call(o||dojo.global,a)){return this.map(body);}this.forEach(body);return this;};};var _227=function(_228){var _229=this instanceof nl&&has("array-extensible");if(typeof _228=="number"){_228=Array(_228);}var _22a=(_228&&"length" in _228)?_228:arguments;if(_229||!_22a.sort){var _22b=_229?this:[],l=_22b.length=_22a.length;for(var i=0;i<l;i++){_22b[i]=_22a[i];}if(_229){return _22b;}_22a=_22b;}lang._mixin(_22a,nlp);_22a._NodeListCtor=function(_22c){return nl(_22c);};return _22a;};var nl=_227,nlp=nl.prototype=has("array-extensible")?[]:{};nl._wrap=nlp._wrap=tnl;nl._adaptAsMap=_224;nl._adaptAsForEach=_223;nl._adaptAsFilter=_225;nl._adaptWithCondition=_226;_21e(["slice","splice"],function(name){var f=ap[name];nlp[name]=function(){return this._wrap(f.apply(this,arguments),name=="slice"?this:null);};});_21e(["indexOf","lastIndexOf","every","some"],function(name){var f=_21b[name];nlp[name]=function(){return f.apply(dojo,[this].concat(aps.call(arguments,0)));};});lang.extend(_227,{constructor:nl,_NodeListCtor:nl,toString:function(){return this.join(",");},_stash:function(_22d){this._parent=_22d;return this;},on:function(_22e,_22f){var _230=this.map(function(node){return on(node,_22e,_22f);});_230.remove=function(){for(var i=0;i<_230.length;i++){_230[i].remove();}};return _230;},end:function(){if(this._parent){return this._parent;}else{return new this._NodeListCtor(0);}},concat:function(item){var t=aps.call(this,0),m=_21b.map(arguments,function(a){return aps.call(a,0);});return this._wrap(apc.apply(t,m),this);},map:function(func,obj){return this._wrap(_21b.map(this,func,obj),this);},forEach:function(_231,_232){_21e(this,_231,_232);return this;},filter:function(_233){var a=arguments,_234=this,_235=0;if(typeof _233=="string"){_234=_236._filterResult(this,a[0]);if(a.length==1){return _234._stash(this);}_235=1;}return this._wrap(_21b.filter(_234,a[_235],a[_235+1]),this);},instantiate:function(_237,_238){var c=lang.isFunction(_237)?_237:lang.getObject(_237);_238=_238||{};return this.forEach(function(node){new c(_238,node);});},at:function(){var t=new this._NodeListCtor(0);_21e(arguments,function(i){if(i<0){i=this.length+i;}if(this[i]){t.push(this[i]);}},this);return t._stash(this);}});function _239(_23a,_23b){var _23c=function(_23d,root){if(typeof root=="string"){root=dom.byId(root);if(!root){return new _23b([]);}}var _23e=typeof _23d=="string"?_23a(_23d,root):_23d?_23d.orphan?_23d:[_23d]:[];if(_23e.orphan){return _23e;}return new _23b(_23e);};_23c.matches=_23a.match||function(node,_23f,root){return _23c.filter([node],_23f,root).length>0;};_23c.filter=_23a.filter||function(_240,_241,root){return _23c(_241,root).filter(function(node){return _21b.indexOf(_240,node)>-1;});};if(typeof _23a!="function"){var _242=_23a.search;_23a=function(_243,root){return _242(root||document,_243);};}return _23c;};var _236=_239(_21d,_227);dojo.query=_239(_21d,function(_244){return _227(_244);});_236.load=function(id,_245,_246){_21c.load(id,_245,function(_247){_246(_239(_247,_227));});};dojo._filterQueryResult=_236._filterResult=function(_248,_249,root){return new _227(_236.filter(_248,_249,root));};dojo.NodeList=_236.NodeList=_227;return _236;});},"dojo/has":function(){define(["require","module"],function(_24a,_24b){var has=_24a.has||function(){};if(!1){var _24c=typeof window!="undefined"&&typeof location!="undefined"&&typeof document!="undefined"&&window.location==location&&window.document==document,_24d=this,doc=_24c&&document,_24e=doc&&doc.createElement("DiV"),_24f=(_24b.config&&_24b.config())||{};has=function(name){return typeof _24f[name]=="function"?(_24f[name]=_24f[name](_24d,doc,_24e)):_24f[name];};has.cache=_24f;has.add=function(name,test,now,_250){(typeof _24f[name]=="undefined"||_250)&&(_24f[name]=test);return now&&has(name);};1||has.add("host-browser",_24c);1||has.add("dom",_24c);1||has.add("dojo-dom-ready-api",1);1||has.add("dojo-sniff",1);}if(1){has.add("dom-addeventlistener",!!document.addEventListener);has.add("touch","ontouchstart" in document);has.add("device-width",screen.availWidth||innerWidth);var form=document.createElement("form");has.add("dom-attributes-explicit",form.attributes.length==0);has.add("dom-attributes-specified-flag",form.attributes.length>0&&form.attributes.length<40);}has.clearElement=function(_251){_251.innerHTML="";return _251;};has.normalize=function(id,_252){var _253=id.match(/[\?:]|[^:\?]*/g),i=0,get=function(skip){var term=_253[i++];if(term==":"){return 0;}else{if(_253[i++]=="?"){if(!skip&&has(term)){return get();}else{get(true);return get(skip);}}return term||0;}};id=get();return id&&_252(id);};has.load=function(id,_254,_255){if(id){_254([id],_255);}else{_255();}};return has;});},"dojo/_base/loader":function(){define(["./kernel","../has","require","module","./json","./lang","./array"],function(dojo,has,_256,_257,json,lang,_258){if(!1){console.error("cannot load the Dojo v1.x loader with a foreign loader");return 0;}1||has.add("dojo-fast-sync-require",1);var _259=function(id){return {src:_257.id,id:id};},_25a=function(name){return name.replace(/\./g,"/");},_25b=/\/\/>>built/,_25c=[],_25d=[],_25e=function(mid,_25f,_260){_25c.push(_260);_258.forEach(mid.split(","),function(mid){var _261=_262(mid,_25f.module);_25d.push(_261);_263(_261);});_264();},_264=(1?function(){var _265,mid;for(mid in _266){_265=_266[mid];if(_265.noReqPluginCheck===undefined){_265.noReqPluginCheck=/loadInit\!/.test(mid)||/require\!/.test(mid)?1:0;}if(!_265.executed&&!_265.noReqPluginCheck&&_265.injected==_267){return;}}_268(function(){var _269=_25c;_25c=[];_258.forEach(_269,function(cb){cb(1);});});}:(function(){var _26a,_26b=function(m){_26a[m.mid]=1;for(var t,_26c,deps=m.deps||[],i=0;i<deps.length;i++){_26c=deps[i];if(!(t=_26a[_26c.mid])){if(t===0||!_26b(_26c)){_26a[m.mid]=0;return false;}}}return true;};return function(){var _26d,mid;_26a={};for(mid in _266){_26d=_266[mid];if(_26d.executed||_26d.noReqPluginCheck){_26a[mid]=1;}else{if(_26d.noReqPluginCheck!==0){_26d.noReqPluginCheck=/loadInit\!/.test(mid)||/require\!/.test(mid)?1:0;}if(_26d.noReqPluginCheck){_26a[mid]=1;}else{if(_26d.injected!==_299){_26a[mid]=0;}}}}for(var t,i=0,end=_25d.length;i<end;i++){_26d=_25d[i];if(!(t=_26a[_26d.mid])){if(t===0||!_26b(_26d)){return;}}}_268(function(){var _26e=_25c;_25c=[];_258.forEach(_26e,function(cb){cb(1);});});};})()),_26f=function(mid,_270,_271){_270([mid],function(_272){_270(_272.names,function(){for(var _273="",args=[],i=0;i<arguments.length;i++){_273+="var "+_272.names[i]+"= arguments["+i+"]; ";args.push(arguments[i]);}eval(_273);var _274=_270.module,_275=[],_276,_277={provide:function(_278){_278=_25a(_278);var _279=_262(_278,_274);if(_279!==_274){_29f(_279);}},require:function(_27a,_27b){_27a=_25a(_27a);_27b&&(_262(_27a,_274).result=_29a);_275.push(_27a);},requireLocalization:function(_27c,_27d,_27e){if(!_276){_276=["dojo/i18n"];}_27e=(_27e||dojo.locale).toLowerCase();_27c=_25a(_27c)+"/nls/"+(/root/i.test(_27e)?"":_27e+"/")+_25a(_27d);if(_262(_27c,_274).isXd){_276.push("dojo/i18n!"+_27c);}},loadInit:function(f){f();}},hold={},p;try{for(p in _277){hold[p]=dojo[p];dojo[p]=_277[p];}_272.def.apply(null,args);}catch(e){_27f("error",[_259("failedDojoLoadInit"),e]);}finally{for(p in _277){dojo[p]=hold[p];}}if(_276){_275=_275.concat(_276);}if(_275.length){_25e(_275.join(","),_270,_271);}else{_271();}});});},_280=function(text,_281,_282){var _283=/\(|\)/g,_284=1,_285;_283.lastIndex=_281;while((_285=_283.exec(text))){if(_285[0]==")"){_284-=1;}else{_284+=1;}if(_284==0){break;}}if(_284!=0){throw "unmatched paren around character "+_283.lastIndex+" in: "+text;}return [dojo.trim(text.substring(_282,_283.lastIndex))+";\n",_283.lastIndex];},_286=/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,_287=/(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,_288=/(^|\s)(require|define)\s*\(/m,_289=function(text,_28a){var _28b,_28c,_28d,_28e,_28f=[],_290=[],_291=[];_28a=_28a||text.replace(_286,function(_292){_287.lastIndex=_288.lastIndex=0;return (_287.test(_292)||_288.test(_292))?"":_292;});while((_28b=_287.exec(_28a))){_28c=_287.lastIndex;_28d=_28c-_28b[0].length;_28e=_280(_28a,_28c,_28d);if(_28b[2]=="loadInit"){_28f.push(_28e[0]);}else{_290.push(_28e[0]);}_287.lastIndex=_28e[1];}_291=_28f.concat(_290);if(_291.length||!_288.test(_28a)){return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g,"\n0 && dojo.loadInit("),_291.join(""),_291];}else{return 0;}},_293=function(_294,text){var _295,id,_296=[],_297=[];if(_25b.test(text)||!(_295=_289(text))){return 0;}id=_294.mid+"-*loadInit";for(var p in _262("dojo",_294).result.scopeMap){_296.push(p);_297.push("\""+p+"\"");}return "// xdomain rewrite of "+_294.mid+"\n"+"define('"+id+"',{\n"+"\tnames:"+dojo.toJson(_296)+",\n"+"\tdef:function("+_296.join(",")+"){"+_295[1]+"}"+"});\n\n"+"define("+dojo.toJson(_296.concat(["dojo/loadInit!"+id]))+", function("+_296.join(",")+"){\n"+_295[0]+"});";},_298=_256.initSyncLoader(_25e,_264,_293),sync=_298.sync,_267=_298.requested,_299=_298.arrived,_29a=_298.nonmodule,_29b=_298.executing,_29c=_298.executed,_29d=_298.syncExecStack,_266=_298.modules,_29e=_298.execQ,_262=_298.getModule,_263=_298.injectModule,_29f=_298.setArrived,_27f=_298.signal,_2a0=_298.finishExec,_2a1=_298.execModule,_2a2=_298.getLegacyMode,_268=_298.guardCheckComplete;_25e=_298.dojoRequirePlugin;dojo.provide=function(mid){var _2a3=_29d[0],_2a4=lang.mixin(_262(_25a(mid),_256.module),{executed:_29b,result:lang.getObject(mid,true)});_29f(_2a4);if(_2a3){(_2a3.provides||(_2a3.provides=[])).push(function(){_2a4.result=lang.getObject(mid);delete _2a4.provides;_2a4.executed!==_29c&&_2a0(_2a4);});}return _2a4.result;};has.add("config-publishRequireResult",1,0,0);dojo.require=function(_2a5,_2a6){function _2a7(mid,_2a8){var _2a9=_262(_25a(mid),_256.module);if(_29d.length&&_29d[0].finish){_29d[0].finish.push(mid);return undefined;}if(_2a9.executed){return _2a9.result;}_2a8&&(_2a9.result=_29a);var _2aa=_2a2();_263(_2a9);_2aa=_2a2();if(_2a9.executed!==_29c&&_2a9.injected===_299){_298.guardCheckComplete(function(){_2a1(_2a9);});}if(_2a9.executed){return _2a9.result;}if(_2aa==sync){if(_2a9.cjs){_29e.unshift(_2a9);}else{_29d.length&&(_29d[0].finish=[mid]);}}else{_29e.push(_2a9);}return undefined;};var _2ab=_2a7(_2a5,_2a6);if(has("config-publishRequireResult")&&!lang.exists(_2a5)&&_2ab!==undefined){lang.setObject(_2a5,_2ab);}return _2ab;};dojo.loadInit=function(f){f();};dojo.registerModulePath=function(_2ac,_2ad){var _2ae={};_2ae[_2ac.replace(/\./g,"/")]=_2ad;_256({paths:_2ae});};dojo.platformRequire=function(_2af){var _2b0=(_2af.common||[]).concat(_2af[dojo._name]||_2af["default"]||[]),temp;while(_2b0.length){if(lang.isArray(temp=_2b0.shift())){dojo.require.apply(dojo,temp);}else{dojo.require(temp);}}};dojo.requireIf=dojo.requireAfterIf=function(_2b1,_2b2,_2b3){if(_2b1){dojo.require(_2b2,_2b3);}};dojo.requireLocalization=function(_2b4,_2b5,_2b6){_256(["../i18n"],function(i18n){i18n.getLocalization(_2b4,_2b5,_2b6);});};return {extractLegacyApiApplications:_289,require:_25e,loadInit:_26f};});},"dojo/json":function(){define(["./has"],function(has){"use strict";var _2b7=typeof JSON!="undefined";has.add("json-parse",_2b7);has.add("json-stringify",_2b7&&JSON.stringify({a:0},function(k,v){return v||1;})=="{\"a\":1}");if(has("json-stringify")){return JSON;}else{var _2b8=function(str){return ("\""+str.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");};return {parse:has("json-parse")?JSON.parse:function(str,_2b9){if(_2b9&&!/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){throw new SyntaxError("Invalid characters in JSON");}return eval("("+str+")");},stringify:function(_2ba,_2bb,_2bc){var _2bd;if(typeof _2bb=="string"){_2bc=_2bb;_2bb=null;}function _2be(it,_2bf,key){if(_2bb){it=_2bb(key,it);}var val,_2c0=typeof it;if(_2c0=="number"){return isFinite(it)?it+"":"null";}if(_2c0=="boolean"){return it+"";}if(it===null){return "null";}if(typeof it=="string"){return _2b8(it);}if(_2c0=="function"||_2c0=="undefined"){return _2bd;}if(typeof it.toJSON=="function"){return _2be(it.toJSON(key),_2bf,key);}if(it instanceof Date){return "\"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z\"".replace(/\{(\w+)(\+)?\}/g,function(t,prop,plus){var num=it["getUTC"+prop]()+(plus?1:0);return num<10?"0"+num:num;});}if(it.valueOf()!==it){return _2be(it.valueOf(),_2bf,key);}var _2c1=_2bc?(_2bf+_2bc):"";var sep=_2bc?" ":"";var _2c2=_2bc?"\n":"";if(it instanceof Array){var itl=it.length,res=[];for(key=0;key<itl;key++){var obj=it[key];val=_2be(obj,_2c1,key);if(typeof val!="string"){val="null";}res.push(_2c2+_2c1+val);}return "["+res.join(",")+_2c2+_2bf+"]";}var _2c3=[];for(key in it){var _2c4;if(it.hasOwnProperty(key)){if(typeof key=="number"){_2c4="\""+key+"\"";}else{if(typeof key=="string"){_2c4=_2b8(key);}else{continue;}}val=_2be(it[key],_2c1,key);if(typeof val!="string"){continue;}_2c3.push(_2c2+_2c1+_2c4+":"+sep+val);}}return "{"+_2c3.join(",")+_2c2+_2bf+"}";};return _2be(_2ba,"","");}};}});},"dojo/_base/declare":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var mix=lang.mixin,op=Object.prototype,opts=op.toString,xtor=new Function,_2c5=0,_2c6="constructor";function err(msg,cls){throw new Error("declare"+(cls?" "+cls:"")+": "+msg);};function _2c7(_2c8,_2c9){var _2ca=[],_2cb=[{cls:0,refs:[]}],_2cc={},_2cd=1,l=_2c8.length,i=0,j,lin,base,top,_2ce,rec,name,refs;for(;i<l;++i){base=_2c8[i];if(!base){err("mixin #"+i+" is unknown. Did you use dojo.require to pull it in?",_2c9);}else{if(opts.call(base)!="[object Function]"){err("mixin #"+i+" is not a callable constructor.",_2c9);}}lin=base._meta?base._meta.bases:[base];top=0;for(j=lin.length-1;j>=0;--j){_2ce=lin[j].prototype;if(!_2ce.hasOwnProperty("declaredClass")){_2ce.declaredClass="uniqName_"+(_2c5++);}name=_2ce.declaredClass;if(!_2cc.hasOwnProperty(name)){_2cc[name]={count:0,refs:[],cls:lin[j]};++_2cd;}rec=_2cc[name];if(top&&top!==rec){rec.refs.push(top);++top.count;}top=rec;}++top.count;_2cb[0].refs.push(top);}while(_2cb.length){top=_2cb.pop();_2ca.push(top.cls);--_2cd;while(refs=top.refs,refs.length==1){top=refs[0];if(!top||--top.count){top=0;break;}_2ca.push(top.cls);--_2cd;}if(top){for(i=0,l=refs.length;i<l;++i){top=refs[i];if(!--top.count){_2cb.push(top);}}}}if(_2cd){err("can't build consistent linearization",_2c9);}base=_2c8[0];_2ca[0]=base?base._meta&&base===_2ca[_2ca.length-base._meta.bases.length]?base._meta.bases.length:1:0;return _2ca;};function _2cf(args,a,f){var name,_2d0,_2d1,_2d2,meta,base,_2d3,opf,pos,_2d4=this._inherited=this._inherited||{};if(typeof args=="string"){name=args;args=a;a=f;}f=0;_2d2=args.callee;name=name||_2d2.nom;if(!name){err("can't deduce a name to call inherited()",this.declaredClass);}meta=this.constructor._meta;_2d1=meta.bases;pos=_2d4.p;if(name!=_2c6){if(_2d4.c!==_2d2){pos=0;base=_2d1[0];meta=base._meta;if(meta.hidden[name]!==_2d2){_2d0=meta.chains;if(_2d0&&typeof _2d0[name]=="string"){err("calling chained method with inherited: "+name,this.declaredClass);}do{meta=base._meta;_2d3=base.prototype;if(meta&&(_2d3[name]===_2d2&&_2d3.hasOwnProperty(name)||meta.hidden[name]===_2d2)){break;}}while(base=_2d1[++pos]);pos=base?pos:-1;}}base=_2d1[++pos];if(base){_2d3=base.prototype;if(base._meta&&_2d3.hasOwnProperty(name)){f=_2d3[name];}else{opf=op[name];do{_2d3=base.prototype;f=_2d3[name];if(f&&(base._meta?_2d3.hasOwnProperty(name):f!==opf)){break;}}while(base=_2d1[++pos]);}}f=base&&f||op[name];}else{if(_2d4.c!==_2d2){pos=0;meta=_2d1[0]._meta;if(meta&&meta.ctor!==_2d2){_2d0=meta.chains;if(!_2d0||_2d0.constructor!=="manual"){err("calling chained constructor with inherited",this.declaredClass);}while(base=_2d1[++pos]){meta=base._meta;if(meta&&meta.ctor===_2d2){break;}}pos=base?pos:-1;}}while(base=_2d1[++pos]){meta=base._meta;f=meta?meta.ctor:base;if(f){break;}}f=base&&f;}_2d4.c=f;_2d4.p=pos;if(f){return a===true?f:f.apply(this,a||args);}};function _2d5(name,args){if(typeof name=="string"){return this.__inherited(name,args,true);}return this.__inherited(name,true);};function _2d6(args,a1,a2){var f=this.getInherited(args,a1);if(f){return f.apply(this,a2||a1||args);}};var _2d7=dojo.config.isDebug?_2d6:_2cf;function _2d8(cls){var _2d9=this.constructor._meta.bases;for(var i=0,l=_2d9.length;i<l;++i){if(_2d9[i]===cls){return true;}}return this instanceof cls;};function _2da(_2db,_2dc){for(var name in _2dc){if(name!=_2c6&&_2dc.hasOwnProperty(name)){_2db[name]=_2dc[name];}}if(has("bug-for-in-skips-shadowed")){for(var _2dd=lang._extraNames,i=_2dd.length;i;){name=_2dd[--i];if(name!=_2c6&&_2dc.hasOwnProperty(name)){_2db[name]=_2dc[name];}}}};function _2de(_2df,_2e0){var name,t;for(name in _2e0){t=_2e0[name];if((t!==op[name]||!(name in op))&&name!=_2c6){if(opts.call(t)=="[object Function]"){t.nom=name;}_2df[name]=t;}}if(has("bug-for-in-skips-shadowed")){for(var _2e1=lang._extraNames,i=_2e1.length;i;){name=_2e1[--i];t=_2e0[name];if((t!==op[name]||!(name in op))&&name!=_2c6){if(opts.call(t)=="[object Function]"){t.nom=name;}_2df[name]=t;}}}return _2df;};function _2e2(_2e3){_2e4.safeMixin(this.prototype,_2e3);return this;};function _2e5(_2e6){return _2e4([this].concat(_2e6));};function _2e7(_2e8,_2e9){return function(){var a=arguments,args=a,a0=a[0],f,i,m,l=_2e8.length,_2ea;if(!(this instanceof a.callee)){return _2eb(a);}if(_2e9&&(a0&&a0.preamble||this.preamble)){_2ea=new Array(_2e8.length);_2ea[0]=a;for(i=0;;){a0=a[0];if(a0){f=a0.preamble;if(f){a=f.apply(this,a)||a;}}f=_2e8[i].prototype;f=f.hasOwnProperty("preamble")&&f.preamble;if(f){a=f.apply(this,a)||a;}if(++i==l){break;}_2ea[i]=a;}}for(i=l-1;i>=0;--i){f=_2e8[i];m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,_2ea?_2ea[i]:a);}}f=this.postscript;if(f){f.apply(this,args);}};};function _2ec(ctor,_2ed){return function(){var a=arguments,t=a,a0=a[0],f;if(!(this instanceof a.callee)){return _2eb(a);}if(_2ed){if(a0){f=a0.preamble;if(f){t=f.apply(this,t)||t;}}f=this.preamble;if(f){f.apply(this,t);}}if(ctor){ctor.apply(this,a);}f=this.postscript;if(f){f.apply(this,a);}};};function _2ee(_2ef){return function(){var a=arguments,i=0,f,m;if(!(this instanceof a.callee)){return _2eb(a);}for(;f=_2ef[i];++i){m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,a);break;}}f=this.postscript;if(f){f.apply(this,a);}};};function _2f0(name,_2f1,_2f2){return function(){var b,m,f,i=0,step=1;if(_2f2){i=_2f1.length-1;step=-1;}for(;b=_2f1[i];i+=step){m=b._meta;f=(m?m.hidden:b.prototype)[name];if(f){f.apply(this,arguments);}}};};function _2f3(ctor){xtor.prototype=ctor.prototype;var t=new xtor;xtor.prototype=null;return t;};function _2eb(args){var ctor=args.callee,t=_2f3(ctor);ctor.apply(t,args);return t;};function _2e4(_2f4,_2f5,_2f6){if(typeof _2f4!="string"){_2f6=_2f5;_2f5=_2f4;_2f4="";}_2f6=_2f6||{};var _2f7,i,t,ctor,name,_2f8,_2f9,_2fa=1,_2fb=_2f5;if(opts.call(_2f5)=="[object Array]"){_2f8=_2c7(_2f5,_2f4);t=_2f8[0];_2fa=_2f8.length-t;_2f5=_2f8[_2fa];}else{_2f8=[0];if(_2f5){if(opts.call(_2f5)=="[object Function]"){t=_2f5._meta;_2f8=_2f8.concat(t?t.bases:_2f5);}else{err("base class is not a callable constructor.",_2f4);}}else{if(_2f5!==null){err("unknown base class. Did you use dojo.require to pull it in?",_2f4);}}}if(_2f5){for(i=_2fa-1;;--i){_2f7=_2f3(_2f5);if(!i){break;}t=_2f8[i];(t._meta?_2da:mix)(_2f7,t.prototype);ctor=new Function;ctor.superclass=_2f5;ctor.prototype=_2f7;_2f5=_2f7.constructor=ctor;}}else{_2f7={};}_2e4.safeMixin(_2f7,_2f6);t=_2f6.constructor;if(t!==op.constructor){t.nom=_2c6;_2f7.constructor=t;}for(i=_2fa-1;i;--i){t=_2f8[i]._meta;if(t&&t.chains){_2f9=mix(_2f9||{},t.chains);}}if(_2f7["-chains-"]){_2f9=mix(_2f9||{},_2f7["-chains-"]);}t=!_2f9||!_2f9.hasOwnProperty(_2c6);_2f8[0]=ctor=(_2f9&&_2f9.constructor==="manual")?_2ee(_2f8):(_2f8.length==1?_2ec(_2f6.constructor,t):_2e7(_2f8,t));ctor._meta={bases:_2f8,hidden:_2f6,chains:_2f9,parents:_2fb,ctor:_2f6.constructor};ctor.superclass=_2f5&&_2f5.prototype;ctor.extend=_2e2;ctor.createSubclass=_2e5;ctor.prototype=_2f7;_2f7.constructor=ctor;_2f7.getInherited=_2d5;_2f7.isInstanceOf=_2d8;_2f7.inherited=_2d7;_2f7.__inherited=_2cf;if(_2f4){_2f7.declaredClass=_2f4;lang.setObject(_2f4,ctor);}if(_2f9){for(name in _2f9){if(_2f7[name]&&typeof _2f9[name]=="string"&&name!=_2c6){t=_2f7[name]=_2f0(name,_2f8,_2f9[name]==="after");t.nom=name;}}}return ctor;};dojo.safeMixin=_2e4.safeMixin=_2de;dojo.declare=_2e4;return _2e4;});},"dojo/dom":function(){define(["./sniff","./_base/lang","./_base/window"],function(has,lang,win){if(has("ie")<=7){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}}var dom={};if(has("ie")){dom.byId=function(id,doc){if(typeof id!="string"){return id;}var _2fc=doc||win.doc,te=id&&_2fc.getElementById(id);if(te&&(te.attributes.id.value==id||te.id==id)){return te;}else{var eles=_2fc.all[id];if(!eles||eles.nodeName){eles=[eles];}var i=0;while((te=eles[i++])){if((te.attributes&&te.attributes.id&&te.attributes.id.value==id)||te.id==id){return te;}}}};}else{dom.byId=function(id,doc){return ((typeof id=="string")?(doc||win.doc).getElementById(id):id)||null;};}dom.isDescendant=function(node,_2fd){try{node=dom.byId(node);_2fd=dom.byId(_2fd);while(node){if(node==_2fd){return true;}node=node.parentNode;}}catch(e){}return false;};dom.setSelectable=function(node,_2fe){node=dom.byId(node);if(has("mozilla")){node.style.MozUserSelect=_2fe?"":"none";}else{if(has("khtml")||has("webkit")){node.style.KhtmlUserSelect=_2fe?"auto":"none";}else{if(has("ie")){var v=(node.unselectable=_2fe?"":"on"),cs=node.getElementsByTagName("*"),i=0,l=cs.length;for(;i<l;++i){cs.item(i).unselectable=v;}}}}};return dom;});},"dojo/_base/browser":function(){if(require.has){require.has.add("config-selectorEngine","acme");}define(["../ready","./kernel","./connect","./unload","./window","./event","./html","./NodeList","../query","./xhr","./fx"],function(dojo){return dojo;});},"dojo/selector/acme":function(){define(["../dom","../sniff","../_base/array","../_base/lang","../_base/window"],function(dom,has,_2ff,lang,win){var trim=lang.trim;var each=_2ff.forEach;var _300=function(){return win.doc;};var _301=(_300().compatMode)=="BackCompat";var _302=">~+";var _303=false;var _304=function(){return true;};var _305=function(_306){if(_302.indexOf(_306.slice(-1))>=0){_306+=" * ";}else{_306+=" ";}var ts=function(s,e){return trim(_306.slice(s,e));};var _307=[];var _308=-1,_309=-1,_30a=-1,_30b=-1,_30c=-1,inId=-1,_30d=-1,_30e,lc="",cc="",_30f;var x=0,ql=_306.length,_310=null,_311=null;var _312=function(){if(_30d>=0){var tv=(_30d==x)?null:ts(_30d,x);_310[(_302.indexOf(tv)<0)?"tag":"oper"]=tv;_30d=-1;}};var _313=function(){if(inId>=0){_310.id=ts(inId,x).replace(/\\/g,"");inId=-1;}};var _314=function(){if(_30c>=0){_310.classes.push(ts(_30c+1,x).replace(/\\/g,""));_30c=-1;}};var _315=function(){_313();_312();_314();};var _316=function(){_315();if(_30b>=0){_310.pseudos.push({name:ts(_30b+1,x)});}_310.loops=(_310.pseudos.length||_310.attrs.length||_310.classes.length);_310.oquery=_310.query=ts(_30f,x);_310.otag=_310.tag=(_310["oper"])?null:(_310.tag||"*");if(_310.tag){_310.tag=_310.tag.toUpperCase();}if(_307.length&&(_307[_307.length-1].oper)){_310.infixOper=_307.pop();_310.query=_310.infixOper.query+" "+_310.query;}_307.push(_310);_310=null;};for(;lc=cc,cc=_306.charAt(x),x<ql;x++){if(lc=="\\"){continue;}if(!_310){_30f=x;_310={query:null,pseudos:[],attrs:[],classes:[],tag:null,oper:null,id:null,getTag:function(){return _303?this.otag:this.tag;}};_30d=x;}if(_30e){if(cc==_30e){_30e=null;}continue;}else{if(cc=="'"||cc=="\""){_30e=cc;continue;}}if(_308>=0){if(cc=="]"){if(!_311.attr){_311.attr=ts(_308+1,x);}else{_311.matchFor=ts((_30a||_308+1),x);}var cmf=_311.matchFor;if(cmf){if((cmf.charAt(0)=="\"")||(cmf.charAt(0)=="'")){_311.matchFor=cmf.slice(1,-1);}}if(_311.matchFor){_311.matchFor=_311.matchFor.replace(/\\/g,"");}_310.attrs.push(_311);_311=null;_308=_30a=-1;}else{if(cc=="="){var _317=("|~^$*".indexOf(lc)>=0)?lc:"";_311.type=_317+cc;_311.attr=ts(_308+1,x-_317.length);_30a=x+1;}}}else{if(_309>=0){if(cc==")"){if(_30b>=0){_311.value=ts(_309+1,x);}_30b=_309=-1;}}else{if(cc=="#"){_315();inId=x+1;}else{if(cc=="."){_315();_30c=x;}else{if(cc==":"){_315();_30b=x;}else{if(cc=="["){_315();_308=x;_311={};}else{if(cc=="("){if(_30b>=0){_311={name:ts(_30b+1,x),value:null};_310.pseudos.push(_311);}_309=x;}else{if((cc==" ")&&(lc!=cc)){_316();}}}}}}}}}return _307;};var _318=function(_319,_31a){if(!_319){return _31a;}if(!_31a){return _319;}return function(){return _319.apply(window,arguments)&&_31a.apply(window,arguments);};};var _31b=function(i,arr){var r=arr||[];if(i){r.push(i);}return r;};var _31c=function(n){return (1==n.nodeType);};var _31d="";var _31e=function(elem,attr){if(!elem){return _31d;}if(attr=="class"){return elem.className||_31d;}if(attr=="for"){return elem.htmlFor||_31d;}if(attr=="style"){return elem.style.cssText||_31d;}return (_303?elem.getAttribute(attr):elem.getAttribute(attr,2))||_31d;};var _31f={"*=":function(attr,_320){return function(elem){return (_31e(elem,attr).indexOf(_320)>=0);};},"^=":function(attr,_321){return function(elem){return (_31e(elem,attr).indexOf(_321)==0);};},"$=":function(attr,_322){return function(elem){var ea=" "+_31e(elem,attr);var _323=ea.lastIndexOf(_322);return _323>-1&&(_323==(ea.length-_322.length));};},"~=":function(attr,_324){var tval=" "+_324+" ";return function(elem){var ea=" "+_31e(elem,attr)+" ";return (ea.indexOf(tval)>=0);};},"|=":function(attr,_325){var _326=_325+"-";return function(elem){var ea=_31e(elem,attr);return ((ea==_325)||(ea.indexOf(_326)==0));};},"=":function(attr,_327){return function(elem){return (_31e(elem,attr)==_327);};}};var _328=(typeof _300().firstChild.nextElementSibling=="undefined");var _329=!_328?"nextElementSibling":"nextSibling";var _32a=!_328?"previousElementSibling":"previousSibling";var _32b=(_328?_31c:_304);var _32c=function(node){while(node=node[_32a]){if(_32b(node)){return false;}}return true;};var _32d=function(node){while(node=node[_329]){if(_32b(node)){return false;}}return true;};var _32e=function(node){var root=node.parentNode;root=root.nodeType!=7?root:root.nextSibling;var i=0,tret=root.children||root.childNodes,ci=(node["_i"]||node.getAttribute("_i")||-1),cl=(root["_l"]||(typeof root.getAttribute!=="undefined"?root.getAttribute("_l"):-1));if(!tret){return -1;}var l=tret.length;if(cl==l&&ci>=0&&cl>=0){return ci;}if(has("ie")&&typeof root.setAttribute!=="undefined"){root.setAttribute("_l",l);}else{root["_l"]=l;}ci=-1;for(var te=root["firstElementChild"]||root["firstChild"];te;te=te[_329]){if(_32b(te)){if(has("ie")){te.setAttribute("_i",++i);}else{te["_i"]=++i;}if(node===te){ci=i;}}}return ci;};var _32f=function(elem){return !((_32e(elem))%2);};var _330=function(elem){return ((_32e(elem))%2);};var _331={"checked":function(name,_332){return function(elem){return !!("checked" in elem?elem.checked:elem.selected);};},"disabled":function(name,_333){return function(elem){return elem.disabled;};},"enabled":function(name,_334){return function(elem){return !elem.disabled;};},"first-child":function(){return _32c;},"last-child":function(){return _32d;},"only-child":function(name,_335){return function(node){return _32c(node)&&_32d(node);};},"empty":function(name,_336){return function(elem){var cn=elem.childNodes;var cnl=elem.childNodes.length;for(var x=cnl-1;x>=0;x--){var nt=cn[x].nodeType;if((nt===1)||(nt==3)){return false;}}return true;};},"contains":function(name,_337){var cz=_337.charAt(0);if(cz=="\""||cz=="'"){_337=_337.slice(1,-1);}return function(elem){return (elem.innerHTML.indexOf(_337)>=0);};},"not":function(name,_338){var p=_305(_338)[0];var _339={el:1};if(p.tag!="*"){_339.tag=1;}if(!p.classes.length){_339.classes=1;}var ntf=_33a(p,_339);return function(elem){return (!ntf(elem));};},"nth-child":function(name,_33b){var pi=parseInt;if(_33b=="odd"){return _330;}else{if(_33b=="even"){return _32f;}}if(_33b.indexOf("n")!=-1){var _33c=_33b.split("n",2);var pred=_33c[0]?((_33c[0]=="-")?-1:pi(_33c[0])):1;var idx=_33c[1]?pi(_33c[1]):0;var lb=0,ub=-1;if(pred>0){if(idx<0){idx=(idx%pred)&&(pred+(idx%pred));}else{if(idx>0){if(idx>=pred){lb=idx-idx%pred;}idx=idx%pred;}}}else{if(pred<0){pred*=-1;if(idx>0){ub=idx;idx=idx%pred;}}}if(pred>0){return function(elem){var i=_32e(elem);return (i>=lb)&&(ub<0||i<=ub)&&((i%pred)==idx);};}else{_33b=idx;}}var _33d=pi(_33b);return function(elem){return (_32e(elem)==_33d);};}};var _33e=(has("ie")&&(has("ie")<9||has("quirks")))?function(cond){var clc=cond.toLowerCase();if(clc=="class"){cond="className";}return function(elem){return (_303?elem.getAttribute(cond):elem[cond]||elem[clc]);};}:function(cond){return function(elem){return (elem&&elem.getAttribute&&elem.hasAttribute(cond));};};var _33a=function(_33f,_340){if(!_33f){return _304;}_340=_340||{};var ff=null;if(!("el" in _340)){ff=_318(ff,_31c);}if(!("tag" in _340)){if(_33f.tag!="*"){ff=_318(ff,function(elem){return (elem&&((_303?elem.tagName:elem.tagName.toUpperCase())==_33f.getTag()));});}}if(!("classes" in _340)){each(_33f.classes,function(_341,idx,arr){var re=new RegExp("(?:^|\\s)"+_341+"(?:\\s|$)");ff=_318(ff,function(elem){return re.test(elem.className);});ff.count=idx;});}if(!("pseudos" in _340)){each(_33f.pseudos,function(_342){var pn=_342.name;if(_331[pn]){ff=_318(ff,_331[pn](pn,_342.value));}});}if(!("attrs" in _340)){each(_33f.attrs,function(attr){var _343;var a=attr.attr;if(attr.type&&_31f[attr.type]){_343=_31f[attr.type](a,attr.matchFor);}else{if(a.length){_343=_33e(a);}}if(_343){ff=_318(ff,_343);}});}if(!("id" in _340)){if(_33f.id){ff=_318(ff,function(elem){return (!!elem&&(elem.id==_33f.id));});}}if(!ff){if(!("default" in _340)){ff=_304;}}return ff;};var _344=function(_345){return function(node,ret,bag){while(node=node[_329]){if(_328&&(!_31c(node))){continue;}if((!bag||_346(node,bag))&&_345(node)){ret.push(node);}break;}return ret;};};var _347=function(_348){return function(root,ret,bag){var te=root[_329];while(te){if(_32b(te)){if(bag&&!_346(te,bag)){break;}if(_348(te)){ret.push(te);}}te=te[_329];}return ret;};};var _349=function(_34a){_34a=_34a||_304;return function(root,ret,bag){var te,x=0,tret=root.children||root.childNodes;while(te=tret[x++]){if(_32b(te)&&(!bag||_346(te,bag))&&(_34a(te,x))){ret.push(te);}}return ret;};};var _34b=function(node,root){var pn=node.parentNode;while(pn){if(pn==root){break;}pn=pn.parentNode;}return !!pn;};var _34c={};var _34d=function(_34e){var _34f=_34c[_34e.query];if(_34f){return _34f;}var io=_34e.infixOper;var oper=(io?io.oper:"");var _350=_33a(_34e,{el:1});var qt=_34e.tag;var _351=("*"==qt);var ecs=_300()["getElementsByClassName"];if(!oper){if(_34e.id){_350=(!_34e.loops&&_351)?_304:_33a(_34e,{el:1,id:1});_34f=function(root,arr){var te=dom.byId(_34e.id,(root.ownerDocument||root));if(!te||!_350(te)){return;}if(9==root.nodeType){return _31b(te,arr);}else{if(_34b(te,root)){return _31b(te,arr);}}};}else{if(ecs&&/\{\s*\[native code\]\s*\}/.test(String(ecs))&&_34e.classes.length&&!_301){_350=_33a(_34e,{el:1,classes:1,id:1});var _352=_34e.classes.join(" ");_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tret=root.getElementsByClassName(_352);while((te=tret[x++])){if(_350(te,root)&&_346(te,bag)){ret.push(te);}}return ret;};}else{if(!_351&&!_34e.loops){_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tag=_34e.getTag(),tret=tag?root.getElementsByTagName(tag):[];while((te=tret[x++])){if(_346(te,bag)){ret.push(te);}}return ret;};}else{_350=_33a(_34e,{el:1,tag:1,id:1});_34f=function(root,arr,bag){var ret=_31b(0,arr),te,x=0;var tag=_34e.getTag(),tret=tag?root.getElementsByTagName(tag):[];while((te=tret[x++])){if(_350(te,root)&&_346(te,bag)){ret.push(te);}}return ret;};}}}}else{var _353={el:1};if(_351){_353.tag=1;}_350=_33a(_34e,_353);if("+"==oper){_34f=_344(_350);}else{if("~"==oper){_34f=_347(_350);}else{if(">"==oper){_34f=_349(_350);}}}}return _34c[_34e.query]=_34f;};var _354=function(root,_355){var _356=_31b(root),qp,x,te,qpl=_355.length,bag,ret;for(var i=0;i<qpl;i++){ret=[];qp=_355[i];x=_356.length-1;if(x>0){bag={};ret.nozip=true;}var gef=_34d(qp);for(var j=0;(te=_356[j]);j++){gef(te,ret,bag);}if(!ret.length){break;}_356=ret;}return ret;};var _357={},_358={};var _359=function(_35a){var _35b=_305(trim(_35a));if(_35b.length==1){var tef=_34d(_35b[0]);return function(root){var r=tef(root,[]);if(r){r.nozip=true;}return r;};}return function(root){return _354(root,_35b);};};var _35c=has("ie")?"commentStrip":"nozip";var qsa="querySelectorAll";var _35d=!!_300()[qsa];var _35e=/\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g;var _35f=function(_360,pre,ch,post){return ch?(pre?pre+" ":"")+ch+(post?" "+post:""):_360;};var _361=/([^[]*)([^\]]*])?/g;var _362=function(_363,_364,att){return _364.replace(_35e,_35f)+(att||"");};var _365=function(_366,_367){_366=_366.replace(_361,_362);if(_35d){var _368=_358[_366];if(_368&&!_367){return _368;}}var _369=_357[_366];if(_369){return _369;}var qcz=_366.charAt(0);var _36a=(-1==_366.indexOf(" "));if((_366.indexOf("#")>=0)&&(_36a)){_367=true;}var _36b=(_35d&&(!_367)&&(_302.indexOf(qcz)==-1)&&(!has("ie")||(_366.indexOf(":")==-1))&&(!(_301&&(_366.indexOf(".")>=0)))&&(_366.indexOf(":contains")==-1)&&(_366.indexOf(":checked")==-1)&&(_366.indexOf("|=")==-1));if(_36b){var tq=(_302.indexOf(_366.charAt(_366.length-1))>=0)?(_366+" *"):_366;return _358[_366]=function(root){try{if(!((9==root.nodeType)||_36a)){throw "";}var r=root[qsa](tq);r[_35c]=true;return r;}catch(e){return _365(_366,true)(root);}};}else{var _36c=_366.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g);return _357[_366]=((_36c.length<2)?_359(_366):function(root){var _36d=0,ret=[],tp;while((tp=_36c[_36d++])){ret=ret.concat(_359(tp)(root));}return ret;});}};var _36e=0;var _36f=has("ie")?function(node){if(_303){return (node.getAttribute("_uid")||node.setAttribute("_uid",++_36e)||_36e);}else{return node.uniqueID;}}:function(node){return (node._uid||(node._uid=++_36e));};var _346=function(node,bag){if(!bag){return 1;}var id=_36f(node);if(!bag[id]){return bag[id]=1;}return 0;};var _370="_zipIdx";var _371=function(arr){if(arr&&arr.nozip){return arr;}var ret=[];if(!arr||!arr.length){return ret;}if(arr[0]){ret.push(arr[0]);}if(arr.length<2){return ret;}_36e++;var x,te;if(has("ie")&&_303){var _372=_36e+"";arr[0].setAttribute(_370,_372);for(x=1;te=arr[x];x++){if(arr[x].getAttribute(_370)!=_372){ret.push(te);}te.setAttribute(_370,_372);}}else{if(has("ie")&&arr.commentStrip){try{for(x=1;te=arr[x];x++){if(_31c(te)){ret.push(te);}}}catch(e){}}else{if(arr[0]){arr[0][_370]=_36e;}for(x=1;te=arr[x];x++){if(arr[x][_370]!=_36e){ret.push(te);}te[_370]=_36e;}}}return ret;};var _373=function(_374,root){root=root||_300();var od=root.ownerDocument||root;_303=(od.createElement("div").tagName==="div");var r=_365(_374)(root);if(r&&r.nozip){return r;}return _371(r);};_373.filter=function(_375,_376,root){var _377=[],_378=_305(_376),_379=(_378.length==1&&!/[^\w#\.]/.test(_376))?_33a(_378[0]):function(node){return _2ff.indexOf(_373(_376,dom.byId(root)),node)!=-1;};for(var x=0,te;te=_375[x];x++){if(_379(te)){_377.push(te);}}return _377;};return _373;});},"dojo/errors/RequestTimeoutError":function(){define("dojo/errors/RequestTimeoutError",["./create","./RequestError"],function(_37a,_37b){return _37a("RequestTimeoutError",null,_37b,{dojoType:"timeout"});});},"dojo/dom-geometry":function(){define(["./sniff","./_base/window","./dom","./dom-style"],function(has,win,dom,_37c){var geom={};geom.boxModel="content-box";if(has("ie")){geom.boxModel=document.compatMode=="BackCompat"?"border-box":"content-box";}geom.getPadExtents=function getPadExtents(node,_37d){node=dom.byId(node);var s=_37d||_37c.getComputedStyle(node),px=_37c.toPixelValue,l=px(node,s.paddingLeft),t=px(node,s.paddingTop),r=px(node,s.paddingRight),b=px(node,s.paddingBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};var none="none";geom.getBorderExtents=function getBorderExtents(node,_37e){node=dom.byId(node);var px=_37c.toPixelValue,s=_37e||_37c.getComputedStyle(node),l=s.borderLeftStyle!=none?px(node,s.borderLeftWidth):0,t=s.borderTopStyle!=none?px(node,s.borderTopWidth):0,r=s.borderRightStyle!=none?px(node,s.borderRightWidth):0,b=s.borderBottomStyle!=none?px(node,s.borderBottomWidth):0;return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getPadBorderExtents=function getPadBorderExtents(node,_37f){node=dom.byId(node);var s=_37f||_37c.getComputedStyle(node),p=geom.getPadExtents(node,s),b=geom.getBorderExtents(node,s);return {l:p.l+b.l,t:p.t+b.t,r:p.r+b.r,b:p.b+b.b,w:p.w+b.w,h:p.h+b.h};};geom.getMarginExtents=function getMarginExtents(node,_380){node=dom.byId(node);var s=_380||_37c.getComputedStyle(node),px=_37c.toPixelValue,l=px(node,s.marginLeft),t=px(node,s.marginTop),r=px(node,s.marginRight),b=px(node,s.marginBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getMarginBox=function getMarginBox(node,_381){node=dom.byId(node);var s=_381||_37c.getComputedStyle(node),me=geom.getMarginExtents(node,s),l=node.offsetLeft-me.l,t=node.offsetTop-me.t,p=node.parentNode,px=_37c.toPixelValue,pcs;if(has("mozilla")){var sl=parseFloat(s.left),st=parseFloat(s.top);if(!isNaN(sl)&&!isNaN(st)){l=sl;t=st;}else{if(p&&p.style){pcs=_37c.getComputedStyle(p);if(pcs.overflow!="visible"){l+=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t+=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}}else{if(has("opera")||(has("ie")==8&&!has("quirks"))){if(p){pcs=_37c.getComputedStyle(p);l-=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t-=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}return {l:l,t:t,w:node.offsetWidth+me.w,h:node.offsetHeight+me.h};};geom.getContentBox=function getContentBox(node,_382){node=dom.byId(node);var s=_382||_37c.getComputedStyle(node),w=node.clientWidth,h,pe=geom.getPadExtents(node,s),be=geom.getBorderExtents(node,s);if(!w){w=node.offsetWidth;h=node.offsetHeight;}else{h=node.clientHeight;be.w=be.h=0;}if(has("opera")){pe.l+=be.l;pe.t+=be.t;}return {l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h};};function _383(node,l,t,w,h,u){u=u||"px";var s=node.style;if(!isNaN(l)){s.left=l+u;}if(!isNaN(t)){s.top=t+u;}if(w>=0){s.width=w+u;}if(h>=0){s.height=h+u;}};function _384(node){return node.tagName.toLowerCase()=="button"||node.tagName.toLowerCase()=="input"&&(node.getAttribute("type")||"").toLowerCase()=="button";};function _385(node){return geom.boxModel=="border-box"||node.tagName.toLowerCase()=="table"||_384(node);};geom.setContentSize=function setContentSize(node,box,_386){node=dom.byId(node);var w=box.w,h=box.h;if(_385(node)){var pb=geom.getPadBorderExtents(node,_386);if(w>=0){w+=pb.w;}if(h>=0){h+=pb.h;}}_383(node,NaN,NaN,w,h);};var _387={l:0,t:0,w:0,h:0};geom.setMarginBox=function setMarginBox(node,box,_388){node=dom.byId(node);var s=_388||_37c.getComputedStyle(node),w=box.w,h=box.h,pb=_385(node)?_387:geom.getPadBorderExtents(node,s),mb=geom.getMarginExtents(node,s);if(has("webkit")){if(_384(node)){var ns=node.style;if(w>=0&&!ns.width){ns.width="4px";}if(h>=0&&!ns.height){ns.height="4px";}}}if(w>=0){w=Math.max(w-pb.w-mb.w,0);}if(h>=0){h=Math.max(h-pb.h-mb.h,0);}_383(node,box.l,box.t,w,h);};geom.isBodyLtr=function isBodyLtr(doc){doc=doc||win.doc;return (win.body(doc).dir||doc.documentElement.dir||"ltr").toLowerCase()=="ltr";};geom.docScroll=function docScroll(doc){doc=doc||win.doc;var node=win.doc.parentWindow||win.doc.defaultView;return "pageXOffset" in node?{x:node.pageXOffset,y:node.pageYOffset}:(node=has("quirks")?win.body(doc):doc.documentElement)&&{x:geom.fixIeBiDiScrollLeft(node.scrollLeft||0,doc),y:node.scrollTop||0};};if(has("ie")){geom.getIeDocumentElementOffset=function getIeDocumentElementOffset(doc){doc=doc||win.doc;var de=doc.documentElement;if(has("ie")<8){var r=de.getBoundingClientRect(),l=r.left,t=r.top;if(has("ie")<7){l+=de.clientLeft;t+=de.clientTop;}return {x:l<0?0:l,y:t<0?0:t};}else{return {x:0,y:0};}};}geom.fixIeBiDiScrollLeft=function fixIeBiDiScrollLeft(_389,doc){doc=doc||win.doc;var ie=has("ie");if(ie&&!geom.isBodyLtr(doc)){var qk=has("quirks"),de=qk?win.body(doc):doc.documentElement,pwin=win.global;if(ie==6&&!qk&&pwin.frameElement&&de.scrollHeight>de.clientHeight){_389+=de.clientLeft;}return (ie<8||qk)?(_389+de.clientWidth-de.scrollWidth):-_389;}return _389;};geom.position=function(node,_38a){node=dom.byId(node);var db=win.body(node.ownerDocument),ret=node.getBoundingClientRect();ret={x:ret.left,y:ret.top,w:ret.right-ret.left,h:ret.bottom-ret.top};if(has("ie")){var _38b=geom.getIeDocumentElementOffset(node.ownerDocument);ret.x-=_38b.x+(has("quirks")?db.clientLeft+db.offsetLeft:0);ret.y-=_38b.y+(has("quirks")?db.clientTop+db.offsetTop:0);}if(_38a){var _38c=geom.docScroll(node.ownerDocument);ret.x+=_38c.x;ret.y+=_38c.y;}return ret;};geom.getMarginSize=function getMarginSize(node,_38d){node=dom.byId(node);var me=geom.getMarginExtents(node,_38d||_37c.getComputedStyle(node));var size=node.getBoundingClientRect();return {w:(size.right-size.left)+me.w,h:(size.bottom-size.top)+me.h};};geom.normalizeEvent=function(_38e){if(!("layerX" in _38e)){_38e.layerX=_38e.offsetX;_38e.layerY=_38e.offsetY;}if(!has("dom-addeventlistener")){var se=_38e.target;var doc=(se&&se.ownerDocument)||document;var _38f=has("quirks")?doc.body:doc.documentElement;var _390=geom.getIeDocumentElementOffset(doc);_38e.pageX=_38e.clientX+geom.fixIeBiDiScrollLeft(_38f.scrollLeft||0,doc)-_390.x;_38e.pageY=_38e.clientY+(_38f.scrollTop||0)-_390.y;}};return geom;});},"dojo/dom-style":function(){define("dojo/dom-style",["./sniff","./dom"],function(has,dom){var _391,_392={};if(has("webkit")){_391=function(node){var s;if(node.nodeType==1){var dv=node.ownerDocument.defaultView;s=dv.getComputedStyle(node,null);if(!s&&node.style){node.style.display="";s=dv.getComputedStyle(node,null);}}return s||{};};}else{if(has("ie")&&(has("ie")<9||has("quirks"))){_391=function(node){return node.nodeType==1&&node.currentStyle?node.currentStyle:{};};}else{_391=function(node){return node.nodeType==1?node.ownerDocument.defaultView.getComputedStyle(node,null):{};};}}_392.getComputedStyle=_391;var _393;if(!has("ie")){_393=function(_394,_395){return parseFloat(_395)||0;};}else{_393=function(_396,_397){if(!_397){return 0;}if(_397=="medium"){return 4;}if(_397.slice&&_397.slice(-2)=="px"){return parseFloat(_397);}var s=_396.style,rs=_396.runtimeStyle,cs=_396.currentStyle,_398=s.left,_399=rs.left;rs.left=cs.left;try{s.left=_397;_397=s.pixelLeft;}catch(e){_397=0;}s.left=_398;rs.left=_399;return _397;};}_392.toPixelValue=_393;var astr="DXImageTransform.Microsoft.Alpha";var af=function(n,f){try{return n.filters.item(astr);}catch(e){return f?{}:null;}};var _39a=has("ie")<9||(has("ie")&&has("quirks"))?function(node){try{return af(node).Opacity/100;}catch(e){return 1;}}:function(node){return _391(node).opacity;};var _39b=has("ie")<9||(has("ie")&&has("quirks"))?function(node,_39c){var ov=_39c*100,_39d=_39c==1;node.style.zoom=_39d?"":1;if(!af(node)){if(_39d){return _39c;}node.style.filter+=" progid:"+astr+"(Opacity="+ov+")";}else{af(node,1).Opacity=ov;}af(node,1).Enabled=!_39d;if(node.tagName.toLowerCase()=="tr"){for(var td=node.firstChild;td;td=td.nextSibling){if(td.tagName.toLowerCase()=="td"){_39b(td,_39c);}}}return _39c;}:function(node,_39e){return node.style.opacity=_39e;};var _39f={left:true,top:true};var _3a0=/margin|padding|width|height|max|min|offset/;function _3a1(node,type,_3a2){type=type.toLowerCase();if(has("ie")){if(_3a2=="auto"){if(type=="height"){return node.offsetHeight;}if(type=="width"){return node.offsetWidth;}}if(type=="fontweight"){switch(_3a2){case 700:return "bold";case 400:default:return "normal";}}}if(!(type in _39f)){_39f[type]=_3a0.test(type);}return _39f[type]?_393(node,_3a2):_3a2;};var _3a3=has("ie")?"styleFloat":"cssFloat",_3a4={"cssFloat":_3a3,"styleFloat":_3a3,"float":_3a3};_392.get=function getStyle(node,name){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");if(l==2&&op){return _39a(n);}name=_3a4[name]||name;var s=_392.getComputedStyle(n);return (l==1)?s:_3a1(n,name,s[name]||n.style[name]);};_392.set=function setStyle(node,name,_3a5){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");name=_3a4[name]||name;if(l==3){return op?_39b(n,_3a5):n.style[name]=_3a5;}for(var x in name){_392.set(node,x,name[x]);}return _392.getComputedStyle(n);};return _392;});},"dojo/dom-prop":function(){define(["exports","./_base/kernel","./sniff","./_base/lang","./dom","./dom-style","./dom-construct","./_base/connect"],function(_3a6,dojo,has,lang,dom,_3a7,ctr,conn){var _3a8={},_3a9=0,_3aa=dojo._scopeName+"attrid";_3a6.names={"class":"className","for":"htmlFor",tabindex:"tabIndex",readonly:"readOnly",colspan:"colSpan",frameborder:"frameBorder",rowspan:"rowSpan",valuetype:"valueType"};_3a6.get=function getProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3ab=_3a6.names[lc]||name;return node[_3ab];};_3a6.set=function setProp(node,name,_3ac){node=dom.byId(node);var l=arguments.length;if(l==2&&typeof name!="string"){for(var x in name){_3a6.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_3ad=_3a6.names[lc]||name;if(_3ad=="style"&&typeof _3ac!="string"){_3a7.set(node,_3ac);return node;}if(_3ad=="innerHTML"){if(has("ie")&&node.tagName.toLowerCase() in {col:1,colgroup:1,table:1,tbody:1,tfoot:1,thead:1,tr:1,title:1}){ctr.empty(node);node.appendChild(ctr.toDom(_3ac,node.ownerDocument));}else{node[_3ad]=_3ac;}return node;}if(lang.isFunction(_3ac)){var _3ae=node[_3aa];if(!_3ae){_3ae=_3a9++;node[_3aa]=_3ae;}if(!_3a8[_3ae]){_3a8[_3ae]={};}var h=_3a8[_3ae][_3ad];if(h){conn.disconnect(h);}else{try{delete node[_3ad];}catch(e){}}if(_3ac){_3a8[_3ae][_3ad]=conn.connect(node,_3ad,_3ac);}else{node[_3ad]=null;}return node;}node[_3ad]=_3ac;return node;};});},"dojo/when":function(){define(["./Deferred","./promise/Promise"],function(_3af,_3b0){"use strict";return function when(_3b1,_3b2,_3b3,_3b4){var _3b5=_3b1&&typeof _3b1.then==="function";var _3b6=_3b5&&_3b1 instanceof _3b0;if(!_3b5){if(_3b2){return _3b2(_3b1);}else{return new _3af().resolve(_3b1);}}else{if(!_3b6){var _3b7=new _3af(_3b1.cancel);_3b1.then(_3b7.resolve,_3b7.reject,_3b7.progress);_3b1=_3b7.promise;}}if(_3b2||_3b3||_3b4){return _3b1.then(_3b2,_3b3,_3b4);}return _3b1;};});},"dojo/dom-attr":function(){define(["exports","./sniff","./_base/lang","./dom","./dom-style","./dom-prop"],function(_3b8,has,lang,dom,_3b9,prop){var _3ba={innerHTML:1,className:1,htmlFor:has("ie"),value:1},_3bb={classname:"class",htmlfor:"for",tabindex:"tabIndex",readonly:"readOnly"};function _3bc(node,name){var attr=node.getAttributeNode&&node.getAttributeNode(name);return attr&&attr.specified;};_3b8.has=function hasAttr(node,name){var lc=name.toLowerCase();return _3ba[prop.names[lc]||name]||_3bc(dom.byId(node),_3bb[lc]||name);};_3b8.get=function getAttr(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3bd=prop.names[lc]||name,_3be=_3ba[_3bd],_3bf=node[_3bd];if(_3be&&typeof _3bf!="undefined"){return _3bf;}if(_3bd!="href"&&(typeof _3bf=="boolean"||lang.isFunction(_3bf))){return _3bf;}var _3c0=_3bb[lc]||name;return _3bc(node,_3c0)?node.getAttribute(_3c0):null;};_3b8.set=function setAttr(node,name,_3c1){node=dom.byId(node);if(arguments.length==2){for(var x in name){_3b8.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_3c2=prop.names[lc]||name,_3c3=_3ba[_3c2];if(_3c2=="style"&&typeof _3c1!="string"){_3b9.set(node,_3c1);return node;}if(_3c3||typeof _3c1=="boolean"||lang.isFunction(_3c1)){return prop.set(node,name,_3c1);}node.setAttribute(_3bb[lc]||name,_3c1);return node;};_3b8.remove=function removeAttr(node,name){dom.byId(node).removeAttribute(_3bb[name.toLowerCase()]||name);};_3b8.getNodeProp=function getNodeProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_3c4=prop.names[lc]||name;if((_3c4 in node)&&_3c4!="href"){return node[_3c4];}var _3c5=_3bb[lc]||name;return _3bc(node,_3c5)?node.getAttribute(_3c5):null;};});},"dojo/dom-construct":function(){define(["exports","./_base/kernel","./sniff","./_base/window","./dom","./dom-attr","./on"],function(_3c6,dojo,has,win,dom,attr,on){var _3c7={option:["select"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","thead","tr"],legend:["fieldset"],caption:["table"],colgroup:["table"],col:["table","colgroup"],li:["ul"]},_3c8=/<\s*([\w\:]+)/,_3c9={},_3ca=0,_3cb="__"+dojo._scopeName+"ToDomId";for(var _3cc in _3c7){if(_3c7.hasOwnProperty(_3cc)){var tw=_3c7[_3cc];tw.pre=_3cc=="option"?"<select multiple=\"multiple\">":"<"+tw.join("><")+">";tw.post="</"+tw.reverse().join("></")+">";}}function _3cd(node,ref){var _3ce=ref.parentNode;if(_3ce){_3ce.insertBefore(node,ref);}};function _3cf(node,ref){var _3d0=ref.parentNode;if(_3d0){if(_3d0.lastChild==ref){_3d0.appendChild(node);}else{_3d0.insertBefore(node,ref.nextSibling);}}};var _3d1=null,_3d2;on(window,"unload",function(){_3d1=null;});_3c6.toDom=function toDom(frag,doc){doc=doc||win.doc;var _3d3=doc[_3cb];if(!_3d3){doc[_3cb]=_3d3=++_3ca+"";_3c9[_3d3]=doc.createElement("div");}frag+="";var _3d4=frag.match(_3c8),tag=_3d4?_3d4[1].toLowerCase():"",_3d5=_3c9[_3d3],wrap,i,fc,df;if(_3d4&&_3c7[tag]){wrap=_3c7[tag];_3d5.innerHTML=wrap.pre+frag+wrap.post;for(i=wrap.length;i;--i){_3d5=_3d5.firstChild;}}else{_3d5.innerHTML=frag;}if(_3d5.childNodes.length==1){return _3d5.removeChild(_3d5.firstChild);}df=doc.createDocumentFragment();while(fc=_3d5.firstChild){df.appendChild(fc);}return df;};_3c6.place=function place(node,_3d6,_3d7){_3d6=dom.byId(_3d6);if(typeof node=="string"){node=/^\s*</.test(node)?_3c6.toDom(node,_3d6.ownerDocument):dom.byId(node);}if(typeof _3d7=="number"){var cn=_3d6.childNodes;if(!cn.length||cn.length<=_3d7){_3d6.appendChild(node);}else{_3cd(node,cn[_3d7<0?0:_3d7]);}}else{switch(_3d7){case "before":_3cd(node,_3d6);break;case "after":_3cf(node,_3d6);break;case "replace":_3d6.parentNode.replaceChild(node,_3d6);break;case "only":_3c6.empty(_3d6);_3d6.appendChild(node);break;case "first":if(_3d6.firstChild){_3cd(node,_3d6.firstChild);break;}default:_3d6.appendChild(node);}}return node;};_3c6.create=function create(tag,_3d8,_3d9,pos){var doc=win.doc;if(_3d9){_3d9=dom.byId(_3d9);doc=_3d9.ownerDocument;}if(typeof tag=="string"){tag=doc.createElement(tag);}if(_3d8){attr.set(tag,_3d8);}if(_3d9){_3c6.place(tag,_3d9,pos);}return tag;};_3c6.empty=has("ie")?function(node){node=dom.byId(node);for(var c;c=node.lastChild;){_3c6.destroy(c);}}:function(node){dom.byId(node).innerHTML="";};_3c6.destroy=function destroy(node){node=dom.byId(node);try{var doc=node.ownerDocument;if(!_3d1||_3d2!=doc){_3d1=doc.createElement("div");_3d2=doc;}_3d1.appendChild(node.parentNode?node.parentNode.removeChild(node):node);_3d1.innerHTML="";}catch(e){}};});},"dojo/request/xhr":function(){define("dojo/request/xhr",["../errors/RequestError","./watch","./handlers","./util","../has"],function(_3da,_3db,_3dc,util,has){has.add("native-xhr",function(){return typeof XMLHttpRequest!=="undefined";});has.add("dojo-force-activex-xhr",function(){return has("activex")&&!document.addEventListener&&window.location.protocol==="file:";});has.add("native-xhr2",function(){if(!has("native-xhr")){return;}var x=new XMLHttpRequest();return typeof x["addEventListener"]!=="undefined"&&(typeof opera==="undefined"||typeof x["upload"]!=="undefined");});has.add("native-formdata",function(){return typeof FormData==="function";});function _3dd(_3de,_3df){var _3e0=_3de.xhr;_3de.status=_3de.xhr.status;_3de.text=_3e0.responseText;if(_3de.options.handleAs==="xml"){_3de.data=_3e0.responseXML;}if(!_3df){try{_3dc(_3de);}catch(e){_3df=e;}}if(_3df){this.reject(_3df);}else{if(util.checkStatus(_3e0.status)){this.resolve(_3de);}else{_3df=new _3da("Unable to load "+_3de.url+" status: "+_3e0.status,_3de);this.reject(_3df);}}};var _3e1,_3e2,_3e3,_3e4;if(has("native-xhr2")){_3e1=function(_3e5){return !this.isFulfilled();};_3e4=function(dfd,_3e6){_3e6.xhr.abort();};_3e3=function(_3e7,dfd,_3e8){function _3e9(evt){dfd.handleResponse(_3e8);};function _3ea(evt){var _3eb=evt.target;var _3ec=new _3da("Unable to load "+_3e8.url+" status: "+_3eb.status,_3e8);dfd.handleResponse(_3e8,_3ec);};function _3ed(evt){if(evt.lengthComputable){_3e8.loaded=evt.loaded;_3e8.total=evt.total;dfd.progress(_3e8);}};_3e7.addEventListener("load",_3e9,false);_3e7.addEventListener("error",_3ea,false);_3e7.addEventListener("progress",_3ed,false);return function(){_3e7.removeEventListener("load",_3e9,false);_3e7.removeEventListener("error",_3ea,false);_3e7.removeEventListener("progress",_3ed,false);};};}else{_3e1=function(_3ee){return _3ee.xhr.readyState;};_3e2=function(_3ef){return 4===_3ef.xhr.readyState;};_3e4=function(dfd,_3f0){var xhr=_3f0.xhr;var _3f1=typeof xhr.abort;if(_3f1==="function"||_3f1==="object"||_3f1==="unknown"){xhr.abort();}};}var _3f2,_3f3={data:null,query:null,sync:false,method:"GET",headers:{"Content-Type":"application/x-www-form-urlencoded"}};function xhr(url,_3f4,_3f5){var _3f6=util.parseArgs(url,util.deepCreate(_3f3,_3f4),has("native-formdata")&&_3f4&&_3f4.data&&_3f4.data instanceof FormData);url=_3f6.url;_3f4=_3f6.options;var _3f7,last=function(){_3f7&&_3f7();};var dfd=util.deferred(_3f6,_3e4,_3e1,_3e2,_3dd,last);var _3f8=_3f6.xhr=xhr._create();if(!_3f8){dfd.cancel(new _3da("XHR was not created"));return _3f5?dfd:dfd.promise;}_3f6.getHeader=function(_3f9){return this.xhr.getResponseHeader(_3f9);};if(_3e3){_3f7=_3e3(_3f8,dfd,_3f6);}var data=_3f4.data,_3fa=!_3f4.sync,_3fb=_3f4.method;try{_3f8.open(_3fb,url,_3fa,_3f4.user||_3f2,_3f4.password||_3f2);if(_3f4.withCredentials){_3f8.withCredentials=_3f4.withCredentials;}var _3fc=_3f4.headers,_3fd;if(_3fc){for(var hdr in _3fc){if(hdr.toLowerCase()==="content-type"){_3fd=_3fc[hdr];}else{if(_3fc[hdr]){_3f8.setRequestHeader(hdr,_3fc[hdr]);}}}}if(_3fd&&_3fd!==false){_3f8.setRequestHeader("Content-Type",_3fd);}if(!_3fc||!("X-Requested-With" in _3fc)){_3f8.setRequestHeader("X-Requested-With","XMLHttpRequest");}if(util.notify){util.notify.emit("send",_3f6,dfd.promise.cancel);}_3f8.send(data);}catch(e){dfd.reject(e);}_3db(dfd);_3f8=null;return _3f5?dfd:dfd.promise;};xhr._create=function(){throw new Error("XMLHTTP not available");};if(has("native-xhr")&&!has("dojo-force-activex-xhr")){xhr._create=function(){return new XMLHttpRequest();};}else{if(has("activex")){try{new ActiveXObject("Msxml2.XMLHTTP");xhr._create=function(){return new ActiveXObject("Msxml2.XMLHTTP");};}catch(e){try{new ActiveXObject("Microsoft.XMLHTTP");xhr._create=function(){return new ActiveXObject("Microsoft.XMLHTTP");};}catch(e){}}}}util.addCommonMethods(xhr);return xhr;});},"dojo/text":function(){define(["./_base/kernel","require","./has","./_base/xhr"],function(dojo,_3fe,has,xhr){var _3ff;if(1){_3ff=function(url,sync,load){xhr("GET",{url:url,sync:!!sync,load:load,headers:dojo.config.textPluginHeaders||{}});};}else{if(_3fe.getText){_3ff=_3fe.getText;}else{console.error("dojo/text plugin failed to load because loader does not support getText");}}var _400={},_401=function(text){if(text){text=text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");var _402=text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(_402){text=_402[1];}}else{text="";}return text;},_403={},_404={};dojo.cache=function(_405,url,_406){var key;if(typeof _405=="string"){if(/\//.test(_405)){key=_405;_406=url;}else{key=_3fe.toUrl(_405.replace(/\./g,"/")+(url?("/"+url):""));}}else{key=_405+"";_406=url;}var val=(_406!=undefined&&typeof _406!="string")?_406.value:_406,_407=_406&&_406.sanitize;if(typeof val=="string"){_400[key]=val;return _407?_401(val):val;}else{if(val===null){delete _400[key];return null;}else{if(!(key in _400)){_3ff(key,true,function(text){_400[key]=text;});}return _407?_401(_400[key]):_400[key];}}};return {dynamic:true,normalize:function(id,_408){var _409=id.split("!"),url=_409[0];return (/^\./.test(url)?_408(url):url)+(_409[1]?"!"+_409[1]:"");},load:function(id,_40a,load){var _40b=id.split("!"),_40c=_40b.length>1,_40d=_40b[0],url=_40a.toUrl(_40b[0]),_40e="url:"+url,text=_403,_40f=function(text){load(_40c?_401(text):text);};if(_40d in _400){text=_400[_40d];}else{if(_40e in _40a.cache){text=_40a.cache[_40e];}else{if(url in _400){text=_400[url];}}}if(text===_403){if(_404[url]){_404[url].push(_40f);}else{var _410=_404[url]=[_40f];_3ff(url,!_40a.async,function(text){_400[_40d]=_400[url]=text;for(var i=0;i<_410.length;){_410[i++](text);}delete _404[url];});}}else{_40f(text);}}};});},"dojo/keys":function(){define("dojo/keys",["./_base/kernel","./sniff"],function(dojo,has){return dojo.keys={BACKSPACE:8,TAB:9,CLEAR:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,META:has("webkit")?91:224,PAUSE:19,CAPS_LOCK:20,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,INSERT:45,DELETE:46,HELP:47,LEFT_WINDOW:91,RIGHT_WINDOW:92,SELECT:93,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,NUMPAD_MULTIPLY:106,NUMPAD_PLUS:107,NUMPAD_ENTER:108,NUMPAD_MINUS:109,NUMPAD_PERIOD:110,NUMPAD_DIVIDE:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,NUM_LOCK:144,SCROLL_LOCK:145,UP_DPAD:175,DOWN_DPAD:176,LEFT_DPAD:177,RIGHT_DPAD:178,copyKey:has("mac")&&!has("air")?(has("safari")?91:224):17};});},"dojo/domReady":function(){define(["./has"],function(has){var _411=this,doc=document,_412={"loaded":1,"complete":1},_413=typeof doc.readyState!="string",_414=!!_412[doc.readyState];if(_413){doc.readyState="loading";}if(!_414){var _415=[],_416=[],_417=function(evt){evt=evt||_411.event;if(_414||(evt.type=="readystatechange"&&!_412[doc.readyState])){return;}_414=1;if(_413){doc.readyState="complete";}while(_415.length){(_415.shift())(doc);}},on=function(node,_418){node.addEventListener(_418,_417,false);_415.push(function(){node.removeEventListener(_418,_417,false);});};if(!has("dom-addeventlistener")){on=function(node,_419){_419="on"+_419;node.attachEvent(_419,_417);_415.push(function(){node.detachEvent(_419,_417);});};var div=doc.createElement("div");try{if(div.doScroll&&_411.frameElement===null){_416.push(function(){try{div.doScroll("left");return 1;}catch(e){}});}}catch(e){}}on(doc,"DOMContentLoaded");on(_411,"load");if("onreadystatechange" in doc){on(doc,"readystatechange");}else{if(!_413){_416.push(function(){return _412[doc.readyState];});}}if(_416.length){var _41a=function(){if(_414){return;}var i=_416.length;while(i--){if(_416[i]()){_417("poller");return;}}setTimeout(_41a,30);};_41a();}}function _41b(_41c){if(_414){_41c(doc);}else{_415.push(_41c);}};_41b.load=function(id,req,load){_41b(load);};return _41b;});},"dojo/_base/lang":function(){define("dojo/_base/lang",["./kernel","../has","../sniff"],function(dojo,has){has.add("bug-for-in-skips-shadowed",function(){for(var i in {toString:1}){return 0;}return 1;});var _41d=has("bug-for-in-skips-shadowed")?"hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split("."):[],_41e=_41d.length,_41f=function(_420,_421,_422){var p,i=0,_423=dojo.global;if(!_422){if(!_420.length){return _423;}else{p=_420[i++];try{_422=dojo.scopeMap[p]&&dojo.scopeMap[p][1];}catch(e){}_422=_422||(p in _423?_423[p]:(_421?_423[p]={}:undefined));}}while(_422&&(p=_420[i++])){_422=(p in _422?_422[p]:(_421?_422[p]={}:undefined));}return _422;},opts=Object.prototype.toString,_424=function(obj,_425,_426){return (_426||[]).concat(Array.prototype.slice.call(obj,_425||0));},_427=/\{([^\}]+)\}/g;var lang={_extraNames:_41d,_mixin:function(dest,_428,_429){var name,s,i,_42a={};for(name in _428){s=_428[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _42a)||_42a[name]!==s))){dest[name]=_429?_429(s):s;}}if(has("bug-for-in-skips-shadowed")){if(_428){for(i=0;i<_41e;++i){name=_41d[i];s=_428[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _42a)||_42a[name]!==s))){dest[name]=_429?_429(s):s;}}}}return dest;},mixin:function(dest,_42b){if(!dest){dest={};}for(var i=1,l=arguments.length;i<l;i++){lang._mixin(dest,arguments[i]);}return dest;},setObject:function(name,_42c,_42d){var _42e=name.split("."),p=_42e.pop(),obj=_41f(_42e,true,_42d);return obj&&p?(obj[p]=_42c):undefined;},getObject:function(name,_42f,_430){return _41f(name.split("."),_42f,_430);},exists:function(name,obj){return lang.getObject(name,false,obj)!==undefined;},isString:function(it){return (typeof it=="string"||it instanceof String);},isArray:function(it){return it&&(it instanceof Array||typeof it=="array");},isFunction:function(it){return opts.call(it)==="[object Function]";},isObject:function(it){return it!==undefined&&(it===null||typeof it=="object"||lang.isArray(it)||lang.isFunction(it));},isArrayLike:function(it){return it&&it!==undefined&&!lang.isString(it)&&!lang.isFunction(it)&&!(it.tagName&&it.tagName.toLowerCase()=="form")&&(lang.isArray(it)||isFinite(it.length));},isAlien:function(it){return it&&!lang.isFunction(it)&&/\{\s*\[native code\]\s*\}/.test(String(it));},extend:function(ctor,_431){for(var i=1,l=arguments.length;i<l;i++){lang._mixin(ctor.prototype,arguments[i]);}return ctor;},_hitchArgs:function(_432,_433){var pre=lang._toArray(arguments,2);var _434=lang.isString(_433);return function(){var args=lang._toArray(arguments);var f=_434?(_432||dojo.global)[_433]:_433;return f&&f.apply(_432||this,pre.concat(args));};},hitch:function(_435,_436){if(arguments.length>2){return lang._hitchArgs.apply(dojo,arguments);}if(!_436){_436=_435;_435=null;}if(lang.isString(_436)){_435=_435||dojo.global;if(!_435[_436]){throw (["lang.hitch: scope[\"",_436,"\"] is null (scope=\"",_435,"\")"].join(""));}return function(){return _435[_436].apply(_435,arguments||[]);};}return !_435?_436:function(){return _436.apply(_435,arguments||[]);};},delegate:(function(){function TMP(){};return function(obj,_437){TMP.prototype=obj;var tmp=new TMP();TMP.prototype=null;if(_437){lang._mixin(tmp,_437);}return tmp;};})(),_toArray:has("ie")?(function(){function slow(obj,_438,_439){var arr=_439||[];for(var x=_438||0;x<obj.length;x++){arr.push(obj[x]);}return arr;};return function(obj){return ((obj.item)?slow:_424).apply(this,arguments);};})():_424,partial:function(_43a){var arr=[null];return lang.hitch.apply(dojo,arr.concat(lang._toArray(arguments)));},clone:function(src){if(!src||typeof src!="object"||lang.isFunction(src)){return src;}if(src.nodeType&&"cloneNode" in src){return src.cloneNode(true);}if(src instanceof Date){return new Date(src.getTime());}if(src instanceof RegExp){return new RegExp(src);}var r,i,l;if(lang.isArray(src)){r=[];for(i=0,l=src.length;i<l;++i){if(i in src){r.push(lang.clone(src[i]));}}}else{r=src.constructor?new src.constructor():{};}return lang._mixin(r,src,lang.clone);},trim:String.prototype.trim?function(str){return str.trim();}:function(str){return str.replace(/^\s\s*/,"").replace(/\s\s*$/,"");},replace:function(tmpl,map,_43b){return tmpl.replace(_43b||_427,lang.isFunction(map)?map:function(_43c,k){return lang.getObject(k,false,map);});}};1&&lang.mixin(dojo,lang);return lang;});},"dojo/request/util":function(){define("dojo/request/util",["exports","../errors/RequestError","../errors/CancelError","../Deferred","../io-query","../_base/array","../_base/lang"],function(_43d,_43e,_43f,_440,_441,_442,lang){_43d.deepCopy=function deepCopy(_443,_444){for(var name in _444){var tval=_443[name],sval=_444[name];if(tval!==sval){if(tval&&typeof tval==="object"&&sval&&typeof sval==="object"){_43d.deepCopy(tval,sval);}else{_443[name]=sval;}}}return _443;};_43d.deepCreate=function deepCreate(_445,_446){_446=_446||{};var _447=lang.delegate(_445),name,_448;for(name in _445){_448=_445[name];if(_448&&typeof _448==="object"){_447[name]=_43d.deepCreate(_448,_446[name]);}}return _43d.deepCopy(_447,_446);};var _449=Object.freeze||function(obj){return obj;};function _44a(_44b){return _449(_44b);};_43d.deferred=function deferred(_44c,_44d,_44e,_44f,_450,last){var def=new _440(function(_451){_44d&&_44d(def,_44c);if(!_451||!(_451 instanceof _43e)&&!(_451 instanceof _43f)){return new _43f("Request canceled",_44c);}return _451;});def.response=_44c;def.isValid=_44e;def.isReady=_44f;def.handleResponse=_450;function _452(_453){_453.response=_44c;throw _453;};var _454=def.then(_44a).otherwise(_452);if(_43d.notify){_454.then(lang.hitch(_43d.notify,"emit","load"),lang.hitch(_43d.notify,"emit","error"));}var _455=_454.then(function(_456){return _456.data||_456.text;});var _457=_449(lang.delegate(_455,{response:_454}));if(last){def.then(function(_458){last.call(def,_458);},function(_459){last.call(def,_44c,_459);});}def.promise=_457;def.then=_457.then;return def;};_43d.addCommonMethods=function addCommonMethods(_45a,_45b){_442.forEach(_45b||["GET","POST","PUT","DELETE"],function(_45c){_45a[(_45c==="DELETE"?"DEL":_45c).toLowerCase()]=function(url,_45d){_45d=lang.delegate(_45d||{});_45d.method=_45c;return _45a(url,_45d);};});};_43d.parseArgs=function parseArgs(url,_45e,_45f){var data=_45e.data,_460=_45e.query;if(data&&!_45f){if(typeof data==="object"){_45e.data=_441.objectToQuery(data);}}if(_460){if(typeof _460==="object"){_460=_441.objectToQuery(_460);}if(_45e.preventCache){_460+=(_460?"&":"")+"request.preventCache="+(+(new Date));}}else{if(_45e.preventCache){_460="request.preventCache="+(+(new Date));}}if(url&&_460){url+=(~url.indexOf("?")?"&":"?")+_460;}return {url:url,options:_45e,getHeader:function(_461){return null;}};};_43d.checkStatus=function(stat){stat=stat||0;return (stat>=200&&stat<300)||stat===304||stat===1223||!stat;};});},"dojo/Evented":function(){define("dojo/Evented",["./aspect","./on"],function(_462,on){"use strict";var _463=_462.after;function _464(){};_464.prototype={on:function(type,_465){return on.parse(this,type,_465,function(_466,type){return _463(_466,"on"+type,_465,true);});},emit:function(type,_467){var args=[this];args.push.apply(args,arguments);return on.emit.apply(on,args);}};return _464;});},"dojo/mouse":function(){define("dojo/mouse",["./_base/kernel","./on","./has","./dom","./_base/window"],function(dojo,on,has,dom,win){has.add("dom-quirks",win.doc&&win.doc.compatMode=="BackCompat");has.add("events-mouseenter",win.doc&&"onmouseenter" in win.doc.createElement("div"));has.add("events-mousewheel",win.doc&&"onmousewheel" in win.doc);var _468;if(has("dom-quirks")||!has("dom-addeventlistener")){_468={LEFT:1,MIDDLE:4,RIGHT:2,isButton:function(e,_469){return e.button&_469;},isLeft:function(e){return e.button&1;},isMiddle:function(e){return e.button&4;},isRight:function(e){return e.button&2;}};}else{_468={LEFT:0,MIDDLE:1,RIGHT:2,isButton:function(e,_46a){return e.button==_46a;},isLeft:function(e){return e.button==0;},isMiddle:function(e){return e.button==1;},isRight:function(e){return e.button==2;}};}dojo.mouseButtons=_468;function _46b(type,_46c){var _46d=function(node,_46e){return on(node,type,function(evt){if(_46c){return _46c(evt,_46e);}if(!dom.isDescendant(evt.relatedTarget,node)){return _46e.call(this,evt);}});};_46d.bubble=function(_46f){return _46b(type,function(evt,_470){var _471=_46f(evt.target);var _472=evt.relatedTarget;if(_471&&(_471!=(_472&&_472.nodeType==1&&_46f(_472)))){return _470.call(_471,evt);}});};return _46d;};var _473;if(has("events-mousewheel")){_473="mousewheel";}else{_473=function(node,_474){return on(node,"DOMMouseScroll",function(evt){evt.wheelDelta=-evt.detail;_474.call(this,evt);});};}return {_eventHandler:_46b,enter:_46b("mouseover"),leave:_46b("mouseout"),wheel:_473,isLeft:_468.isLeft,isMiddle:_468.isMiddle,isRight:_468.isRight};});},"dojo/_base/xhr":function(){define("dojo/_base/xhr",["./kernel","./sniff","require","../io-query","../dom","../dom-form","./Deferred","./config","./json","./lang","./array","../on","../aspect","../request/watch","../request/xhr","../request/util"],function(dojo,has,_475,ioq,dom,_476,_477,_478,json,lang,_479,on,_47a,_47b,_47c,util){dojo._xhrObj=_47c._create;var cfg=dojo.config;dojo.objectToQuery=ioq.objectToQuery;dojo.queryToObject=ioq.queryToObject;dojo.fieldToObject=_476.fieldToObject;dojo.formToObject=_476.toObject;dojo.formToQuery=_476.toQuery;dojo.formToJson=_476.toJson;dojo._blockAsync=false;var _47d=dojo._contentHandlers=dojo.contentHandlers={"text":function(xhr){return xhr.responseText;},"json":function(xhr){return json.fromJson(xhr.responseText||null);},"json-comment-filtered":function(xhr){if(!_478.useCommentedJson){console.warn("Consider using the standard mimetype:application/json."+" json-commenting can introduce security issues. To"+" decrease the chances of hijacking, use the standard the 'json' handler and"+" prefix your json with: {}&&\n"+"Use djConfig.useCommentedJson=true to turn off this message.");}var _47e=xhr.responseText;var _47f=_47e.indexOf("/*");var _480=_47e.lastIndexOf("*/");if(_47f==-1||_480==-1){throw new Error("JSON was not comment filtered");}return json.fromJson(_47e.substring(_47f+2,_480));},"javascript":function(xhr){return dojo.eval(xhr.responseText);},"xml":function(xhr){var _481=xhr.responseXML;if(has("ie")){if((!_481||!_481.documentElement)){var ms=function(n){return "MSXML"+n+".DOMDocument";};var dp=["Microsoft.XMLDOM",ms(6),ms(4),ms(3),ms(2)];_479.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(xhr.responseText);_481=dom;}catch(e){return false;}return true;});}}return _481;},"json-comment-optional":function(xhr){if(xhr.responseText&&/^[^{\[]*\/\*/.test(xhr.responseText)){return _47d["json-comment-filtered"](xhr);}else{return _47d["json"](xhr);}}};dojo._ioSetArgs=function(args,_482,_483,_484){var _485={args:args,url:args.url};var _486=null;if(args.form){var form=dom.byId(args.form);var _487=form.getAttributeNode("action");_485.url=_485.url||(_487?_487.value:null);_486=_476.toObject(form);}var _488=[{}];if(_486){_488.push(_486);}if(args.content){_488.push(args.content);}if(args.preventCache){_488.push({"dojo.preventCache":new Date().valueOf()});}_485.query=ioq.objectToQuery(lang.mixin.apply(null,_488));_485.handleAs=args.handleAs||"text";var d=new _477(function(dfd){dfd.canceled=true;_482&&_482(dfd);var err=dfd.ioArgs.error;if(!err){err=new Error("request cancelled");err.dojoType="cancel";dfd.ioArgs.error=err;}return err;});d.addCallback(_483);var ld=args.load;if(ld&&lang.isFunction(ld)){d.addCallback(function(_489){return ld.call(args,_489,_485);});}var err=args.error;if(err&&lang.isFunction(err)){d.addErrback(function(_48a){return err.call(args,_48a,_485);});}var _48b=args.handle;if(_48b&&lang.isFunction(_48b)){d.addBoth(function(_48c){return _48b.call(args,_48c,_485);});}d.addErrback(function(_48d){return _484(_48d,d);});if(cfg.ioPublish&&dojo.publish&&_485.args.ioPublish!==false){d.addCallbacks(function(res){dojo.publish("/dojo/io/load",[d,res]);return res;},function(res){dojo.publish("/dojo/io/error",[d,res]);return res;});d.addBoth(function(res){dojo.publish("/dojo/io/done",[d,res]);return res;});}d.ioArgs=_485;return d;};var _48e=function(dfd){var ret=_47d[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);return ret===undefined?null:ret;};var _48f=function(_490,dfd){if(!dfd.ioArgs.args.failOk){console.error(_490);}return _490;};var _491=function(dfd){if(_492<=0){_492=0;if(cfg.ioPublish&&dojo.publish&&(!dfd||dfd&&dfd.ioArgs.args.ioPublish!==false)){dojo.publish("/dojo/io/stop");}}};var _492=0;_47a.after(_47b,"_onAction",function(){_492-=1;});_47a.after(_47b,"_onInFlight",_491);dojo._ioCancelAll=_47b.cancelAll;dojo._ioNotifyStart=function(dfd){if(cfg.ioPublish&&dojo.publish&&dfd.ioArgs.args.ioPublish!==false){if(!_492){dojo.publish("/dojo/io/start");}_492+=1;dojo.publish("/dojo/io/send",[dfd]);}};dojo._ioWatch=function(dfd,_493,_494,_495){var args=dfd.ioArgs.options=dfd.ioArgs.args;lang.mixin(dfd,{response:dfd.ioArgs,isValid:function(_496){return _493(dfd);},isReady:function(_497){return _494(dfd);},handleResponse:function(_498){return _495(dfd);}});_47b(dfd);_491(dfd);};var _499="application/x-www-form-urlencoded";dojo._ioAddQueryToUrl=function(_49a){if(_49a.query.length){_49a.url+=(_49a.url.indexOf("?")==-1?"?":"&")+_49a.query;_49a.query=null;}};dojo.xhr=function(_49b,args,_49c){var rDfd;var dfd=dojo._ioSetArgs(args,function(dfd){rDfd&&rDfd.cancel();},_48e,_48f);var _49d=dfd.ioArgs;if("postData" in args){_49d.query=args.postData;}else{if("putData" in args){_49d.query=args.putData;}else{if("rawBody" in args){_49d.query=args.rawBody;}else{if((arguments.length>2&&!_49c)||"POST|PUT".indexOf(_49b.toUpperCase())===-1){dojo._ioAddQueryToUrl(_49d);}}}}var _49e={method:_49b,handleAs:"text",timeout:args.timeout,withCredentials:args.withCredentials,ioArgs:_49d};if(typeof args.headers!=="undefined"){_49e.headers=args.headers;}if(typeof args.contentType!=="undefined"){if(!_49e.headers){_49e.headers={};}_49e.headers["Content-Type"]=args.contentType;}if(typeof _49d.query!=="undefined"){_49e.data=_49d.query;}if(typeof args.sync!=="undefined"){_49e.sync=args.sync;}dojo._ioNotifyStart(dfd);try{rDfd=_47c(_49d.url,_49e,true);}catch(e){dfd.cancel();return dfd;}dfd.ioArgs.xhr=rDfd.response.xhr;rDfd.then(function(){dfd.resolve(dfd);}).otherwise(function(_49f){_49d.error=_49f;dfd.reject(_49f);});return dfd;};dojo.xhrGet=function(args){return dojo.xhr("GET",args);};dojo.rawXhrPost=dojo.xhrPost=function(args){return dojo.xhr("POST",args,true);};dojo.rawXhrPut=dojo.xhrPut=function(args){return dojo.xhr("PUT",args,true);};dojo.xhrDelete=function(args){return dojo.xhr("DELETE",args);};dojo._isDocumentOk=function(x){return util.checkStatus(x.status);};dojo._getText=function(url){var _4a0;dojo.xhrGet({url:url,sync:true,load:function(text){_4a0=text;}});return _4a0;};lang.mixin(dojo.xhr,{_xhrObj:dojo._xhrObj,fieldToObject:_476.fieldToObject,formToObject:_476.toObject,objectToQuery:ioq.objectToQuery,formToQuery:_476.toQuery,formToJson:_476.toJson,queryToObject:ioq.queryToObject,contentHandlers:_47d,_ioSetArgs:dojo._ioSetArgs,_ioCancelAll:dojo._ioCancelAll,_ioNotifyStart:dojo._ioNotifyStart,_ioWatch:dojo._ioWatch,_ioAddQueryToUrl:dojo._ioAddQueryToUrl,_isDocumentOk:dojo._isDocumentOk,_getText:dojo._getText,get:dojo.xhrGet,post:dojo.xhrPost,put:dojo.xhrPut,del:dojo.xhrDelete});return dojo.xhr;});},"dojo/topic":function(){define("dojo/topic",["./Evented"],function(_4a1){var hub=new _4a1;return {publish:function(_4a2,_4a3){return hub.emit.apply(hub,arguments);},subscribe:function(_4a4,_4a5){return hub.on.apply(hub,arguments);}};});},"dojo/loadInit":function(){define("dojo/loadInit",["./_base/loader"],function(_4a6){return {dynamic:0,normalize:function(id){return id;},load:_4a6.loadInit};});},"dojo/_base/unload":function(){define(["./kernel","./lang","../on"],function(dojo,lang,on){var win=window;var _4a7={addOnWindowUnload:function(obj,_4a8){if(!dojo.windowUnloaded){on(win,"unload",(dojo.windowUnloaded=function(){}));}on(win,"unload",lang.hitch(obj,_4a8));},addOnUnload:function(obj,_4a9){on(win,"beforeunload",lang.hitch(obj,_4a9));}};dojo.addOnWindowUnload=_4a7.addOnWindowUnload;dojo.addOnUnload=_4a7.addOnUnload;return _4a7;});},"dojo/Deferred":function(){define(["./has","./_base/lang","./errors/CancelError","./promise/Promise","./promise/instrumentation"],function(has,lang,_4aa,_4ab,_4ac){"use strict";var _4ad=0,_4ae=1,_4af=2;var _4b0="This deferred has already been fulfilled.";var _4b1=Object.freeze||function(){};var _4b2=function(_4b3,type,_4b4,_4b5,_4b6){if(1){if(type===_4af&&_4b7.instrumentRejected&&_4b3.length===0){_4b7.instrumentRejected(_4b4,false,_4b5,_4b6);}}for(var i=0;i<_4b3.length;i++){_4b8(_4b3[i],type,_4b4,_4b5);}};var _4b8=function(_4b9,type,_4ba,_4bb){var func=_4b9[type];var _4bc=_4b9.deferred;if(func){try{var _4bd=func(_4ba);if(_4bd&&typeof _4bd.then==="function"){_4b9.cancel=_4bd.cancel;_4bd.then(_4be(_4bc,_4ae),_4be(_4bc,_4af),_4be(_4bc,_4ad));return;}_4bf(_4bc,_4ae,_4bd);}catch(error){_4bf(_4bc,_4af,error);}}else{_4bf(_4bc,type,_4ba);}if(1){if(type===_4af&&_4b7.instrumentRejected){_4b7.instrumentRejected(_4ba,!!func,_4bb,_4bc.promise);}}};var _4be=function(_4c0,type){return function(_4c1){_4bf(_4c0,type,_4c1);};};var _4bf=function(_4c2,type,_4c3){if(!_4c2.isCanceled()){switch(type){case _4ad:_4c2.progress(_4c3);break;case _4ae:_4c2.resolve(_4c3);break;case _4af:_4c2.reject(_4c3);break;}}};var _4b7=function(_4c4){var _4c5=this.promise=new _4ab();var _4c6=this;var _4c7,_4c8,_4c9;var _4ca=false;var _4cb=[];if(1&&Error.captureStackTrace){Error.captureStackTrace(_4c6,_4b7);Error.captureStackTrace(_4c5,_4b7);}this.isResolved=_4c5.isResolved=function(){return _4c7===_4ae;};this.isRejected=_4c5.isRejected=function(){return _4c7===_4af;};this.isFulfilled=_4c5.isFulfilled=function(){return !!_4c7;};this.isCanceled=_4c5.isCanceled=function(){return _4ca;};this.progress=function(_4cc,_4cd){if(!_4c7){_4b2(_4cb,_4ad,_4cc,null,_4c6);return _4c5;}else{if(_4cd===true){throw new Error(_4b0);}else{return _4c5;}}};this.resolve=function(_4ce,_4cf){if(!_4c7){_4b2(_4cb,_4c7=_4ae,_4c8=_4ce,null,_4c6);_4cb=null;return _4c5;}else{if(_4cf===true){throw new Error(_4b0);}else{return _4c5;}}};var _4d0=this.reject=function(_4d1,_4d2){if(!_4c7){if(1&&Error.captureStackTrace){Error.captureStackTrace(_4c9={},_4d0);}_4b2(_4cb,_4c7=_4af,_4c8=_4d1,_4c9,_4c6);_4cb=null;return _4c5;}else{if(_4d2===true){throw new Error(_4b0);}else{return _4c5;}}};this.then=_4c5.then=function(_4d3,_4d4,_4d5){var _4d6=[_4d5,_4d3,_4d4];_4d6.cancel=_4c5.cancel;_4d6.deferred=new _4b7(function(_4d7){return _4d6.cancel&&_4d6.cancel(_4d7);});if(_4c7&&!_4cb){_4b8(_4d6,_4c7,_4c8,_4c9);}else{_4cb.push(_4d6);}return _4d6.deferred.promise;};this.cancel=_4c5.cancel=function(_4d8,_4d9){if(!_4c7){if(_4c4){var _4da=_4c4(_4d8);_4d8=typeof _4da==="undefined"?_4d8:_4da;}_4ca=true;if(!_4c7){if(typeof _4d8==="undefined"){_4d8=new _4aa();}_4d0(_4d8);return _4d8;}else{if(_4c7===_4af&&_4c8===_4d8){return _4d8;}}}else{if(_4d9===true){throw new Error(_4b0);}}};_4b1(_4c5);};_4b7.prototype.toString=function(){return "[object Deferred]";};if(_4ac){_4ac(_4b7);}return _4b7;});},"dojo/_base/NodeList":function(){define("dojo/_base/NodeList",["./kernel","../query","./array","./html","../NodeList-dom"],function(dojo,_4db,_4dc){var _4dd=_4db.NodeList,nlp=_4dd.prototype;nlp.connect=_4dd._adaptAsForEach(function(){return dojo.connect.apply(this,arguments);});nlp.coords=_4dd._adaptAsMap(dojo.coords);_4dd.events=["blur","focus","change","click","error","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","submit"];_4dc.forEach(_4dd.events,function(evt){var _4de="on"+evt;nlp[_4de]=function(a,b){return this.connect(_4de,a,b);};});dojo.NodeList=_4dd;return _4dd;});},"dojo/_base/Color":function(){define(["./kernel","./lang","./array","./config"],function(dojo,lang,_4df,_4e0){var _4e1=dojo.Color=function(_4e2){if(_4e2){this.setColor(_4e2);}};_4e1.named={"black":[0,0,0],"silver":[192,192,192],"gray":[128,128,128],"white":[255,255,255],"maroon":[128,0,0],"red":[255,0,0],"purple":[128,0,128],"fuchsia":[255,0,255],"green":[0,128,0],"lime":[0,255,0],"olive":[128,128,0],"yellow":[255,255,0],"navy":[0,0,128],"blue":[0,0,255],"teal":[0,128,128],"aqua":[0,255,255],"transparent":_4e0.transparentColor||[0,0,0,0]};lang.extend(_4e1,{r:255,g:255,b:255,a:1,_set:function(r,g,b,a){var t=this;t.r=r;t.g=g;t.b=b;t.a=a;},setColor:function(_4e3){if(lang.isString(_4e3)){_4e1.fromString(_4e3,this);}else{if(lang.isArray(_4e3)){_4e1.fromArray(_4e3,this);}else{this._set(_4e3.r,_4e3.g,_4e3.b,_4e3.a);if(!(_4e3 instanceof _4e1)){this.sanitize();}}}return this;},sanitize:function(){return this;},toRgb:function(){var t=this;return [t.r,t.g,t.b];},toRgba:function(){var t=this;return [t.r,t.g,t.b,t.a];},toHex:function(){var arr=_4df.map(["r","g","b"],function(x){var s=this[x].toString(16);return s.length<2?"0"+s:s;},this);return "#"+arr.join("");},toCss:function(_4e4){var t=this,rgb=t.r+", "+t.g+", "+t.b;return (_4e4?"rgba("+rgb+", "+t.a:"rgb("+rgb)+")";},toString:function(){return this.toCss(true);}});_4e1.blendColors=dojo.blendColors=function(_4e5,end,_4e6,obj){var t=obj||new _4e1();_4df.forEach(["r","g","b","a"],function(x){t[x]=_4e5[x]+(end[x]-_4e5[x])*_4e6;if(x!="a"){t[x]=Math.round(t[x]);}});return t.sanitize();};_4e1.fromRgb=dojo.colorFromRgb=function(_4e7,obj){var m=_4e7.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);return m&&_4e1.fromArray(m[1].split(/\s*,\s*/),obj);};_4e1.fromHex=dojo.colorFromHex=function(_4e8,obj){var t=obj||new _4e1(),bits=(_4e8.length==4)?4:8,mask=(1<<bits)-1;_4e8=Number("0x"+_4e8.substr(1));if(isNaN(_4e8)){return null;}_4df.forEach(["b","g","r"],function(x){var c=_4e8&mask;_4e8>>=bits;t[x]=bits==4?17*c:c;});t.a=1;return t;};_4e1.fromArray=dojo.colorFromArray=function(a,obj){var t=obj||new _4e1();t._set(Number(a[0]),Number(a[1]),Number(a[2]),Number(a[3]));if(isNaN(t.a)){t.a=1;}return t.sanitize();};_4e1.fromString=dojo.colorFromString=function(str,obj){var a=_4e1.named[str];return a&&_4e1.fromArray(a,obj)||_4e1.fromRgb(str,obj)||_4e1.fromHex(str,obj);};return _4e1;});},"dojo/promise/instrumentation":function(){define(["./tracer","../has","../_base/lang","../_base/array"],function(_4e9,has,lang,_4ea){function _4eb(_4ec,_4ed,_4ee){var _4ef="";if(_4ec&&_4ec.stack){_4ef+=_4ec.stack;}if(_4ed&&_4ed.stack){_4ef+="\n ----------------------------------------\n rejected"+_4ed.stack.split("\n").slice(1).join("\n").replace(/^\s+/," ");}if(_4ee&&_4ee.stack){_4ef+="\n ----------------------------------------\n"+_4ee.stack;}console.error(_4ec,_4ef);};function _4f0(_4f1,_4f2,_4f3,_4f4){if(!_4f2){_4eb(_4f1,_4f3,_4f4);}};var _4f5=[];var _4f6=false;var _4f7=1000;function _4f8(_4f9,_4fa,_4fb,_4fc){if(_4fa){_4ea.some(_4f5,function(obj,ix){if(obj.error===_4f9){_4f5.splice(ix,1);return true;}});}else{if(!_4ea.some(_4f5,function(obj){return obj.error===_4f9;})){_4f5.push({error:_4f9,rejection:_4fb,deferred:_4fc,timestamp:new Date().getTime()});}}if(!_4f6){_4f6=setTimeout(_4fd,_4f7);}};function _4fd(){var now=new Date().getTime();var _4fe=now-_4f7;_4f5=_4ea.filter(_4f5,function(obj){if(obj.timestamp<_4fe){_4eb(obj.error,obj.rejection,obj.deferred);return false;}return true;});if(_4f5.length){_4f6=setTimeout(_4fd,_4f5[0].timestamp+_4f7-now);}};return function(_4ff){var _500=has("config-useDeferredInstrumentation");if(_500){_4e9.on("resolved",lang.hitch(console,"log","resolved"));_4e9.on("rejected",lang.hitch(console,"log","rejected"));_4e9.on("progress",lang.hitch(console,"log","progress"));var args=[];if(typeof _500==="string"){args=_500.split(",");_500=args.shift();}if(_500==="report-rejections"){_4ff.instrumentRejected=_4f0;}else{if(_500==="report-unhandled-rejections"||_500===true||_500===1){_4ff.instrumentRejected=_4f8;_4f7=parseInt(args[0],10)||_4f7;}else{throw new Error("Unsupported instrumentation usage <"+_500+">");}}}};});},"dojo/selector/_loader":function(){define(["../has","require"],function(has,_501){"use strict";var _502=document.createElement("div");has.add("dom-qsa2.1",!!_502.querySelectorAll);has.add("dom-qsa3",function(){try{_502.innerHTML="<p class='TEST'></p>";return _502.querySelectorAll(".TEST:empty").length==1;}catch(e){}});var _503;var acme="./acme",lite="./lite";return {load:function(id,_504,_505,_506){var req=_501;id=id=="default"?has("config-selectorEngine")||"css3":id;id=id=="css2"||id=="lite"?lite:id=="css2.1"?has("dom-qsa2.1")?lite:acme:id=="css3"?has("dom-qsa3")?lite:acme:id=="acme"?acme:(req=_504)&&id;if(id.charAt(id.length-1)=="?"){id=id.substring(0,id.length-1);var _507=true;}if(_507&&(has("dom-compliant-qsa")||_503)){return _505(_503);}req([id],function(_508){if(id!="./lite"){_503=_508;}_505(_508);});}};});},"dojo/promise/Promise":function(){define(["../_base/lang"],function(lang){"use strict";function _509(){throw new TypeError("abstract");};return lang.extend(function Promise(){},{then:function(_50a,_50b,_50c){_509();},cancel:function(_50d,_50e){_509();},isResolved:function(){_509();},isRejected:function(){_509();},isFulfilled:function(){_509();},isCanceled:function(){_509();},always:function(_50f){return this.then(_50f,_50f);},otherwise:function(_510){return this.then(null,_510);},trace:function(){return this;},traceRejected:function(){return this;},toString:function(){return "[object Promise]";}});});},"dojo/request/watch":function(){define(["./util","../errors/RequestTimeoutError","../errors/CancelError","../_base/array","../_base/window","../has!host-browser?dom-addeventlistener?:../on:"],function(util,_511,_512,_513,win,on){var _514=null,_515=[];function _516(){var now=+(new Date);for(var i=0,dfd;i<_515.length&&(dfd=_515[i]);i++){var _517=dfd.response,_518=_517.options;if((dfd.isCanceled&&dfd.isCanceled())||(dfd.isValid&&!dfd.isValid(_517))){_515.splice(i--,1);_519._onAction&&_519._onAction();}else{if(dfd.isReady&&dfd.isReady(_517)){_515.splice(i--,1);dfd.handleResponse(_517);_519._onAction&&_519._onAction();}else{if(dfd.startTime){if(dfd.startTime+(_518.timeout||0)<now){_515.splice(i--,1);dfd.cancel(new _511(_517));_519._onAction&&_519._onAction();}}}}}_519._onInFlight&&_519._onInFlight(dfd);if(!_515.length){clearInterval(_514);_514=null;}};function _519(dfd){if(dfd.response.options.timeout){dfd.startTime=+(new Date);}if(dfd.isFulfilled()){return;}_515.push(dfd);if(!_514){_514=setInterval(_516,50);}if(dfd.response.options.sync){_516();}};_519.cancelAll=function cancelAll(){try{_513.forEach(_515,function(dfd){try{dfd.cancel(new _512("All requests canceled."));}catch(e){}});}catch(e){}};if(win&&on&&win.doc.attachEvent){on(win.global,"unload",function(){_519.cancelAll();});}return _519;});},"dojo/on":function(){define(["./has!dom-addeventlistener?:./aspect","./_base/kernel","./has"],function(_51a,dojo,has){"use strict";if(1){var _51b=window.ScriptEngineMajorVersion;has.add("jscript",_51b&&(_51b()+ScriptEngineMinorVersion()/10));has.add("event-orientationchange",has("touch")&&!has("android"));has.add("event-stopimmediatepropagation",window.Event&&!!window.Event.prototype&&!!window.Event.prototype.stopImmediatePropagation);}var on=function(_51c,type,_51d,_51e){if(_51c.on&&typeof type!="function"){return _51c.on(type,_51d);}return on.parse(_51c,type,_51d,_51f,_51e,this);};on.pausable=function(_520,type,_521,_522){var _523;var _524=on(_520,type,function(){if(!_523){return _521.apply(this,arguments);}},_522);_524.pause=function(){_523=true;};_524.resume=function(){_523=false;};return _524;};on.once=function(_525,type,_526,_527){var _528=on(_525,type,function(){_528.remove();return _526.apply(this,arguments);});return _528;};on.parse=function(_529,type,_52a,_52b,_52c,_52d){if(type.call){return type.call(_52d,_529,_52a);}if(type.indexOf(",")>-1){var _52e=type.split(/\s*,\s*/);var _52f=[];var i=0;var _530;while(_530=_52e[i++]){_52f.push(_52b(_529,_530,_52a,_52c,_52d));}_52f.remove=function(){for(var i=0;i<_52f.length;i++){_52f[i].remove();}};return _52f;}return _52b(_529,type,_52a,_52c,_52d);};var _531=/^touch/;function _51f(_532,type,_533,_534,_535){var _536=type.match(/(.*):(.*)/);if(_536){type=_536[2];_536=_536[1];return on.selector(_536,type).call(_535,_532,_533);}if(has("touch")){if(_531.test(type)){_533=_537(_533);}if(!has("event-orientationchange")&&(type=="orientationchange")){type="resize";_532=window;_533=_537(_533);}}if(_538){_533=_538(_533);}if(_532.addEventListener){var _539=type in _53a,_53b=_539?_53a[type]:type;_532.addEventListener(_53b,_533,_539);return {remove:function(){_532.removeEventListener(_53b,_533,_539);}};}type="on"+type;if(_53c&&_532.attachEvent){return _53c(_532,type,_533);}throw new Error("Target must be an event emitter");};on.selector=function(_53d,_53e,_53f){return function(_540,_541){var _542=typeof _53d=="function"?{matches:_53d}:this,_543=_53e.bubble;function _544(_545){_542=_542&&_542.matches?_542:dojo.query;while(!_542.matches(_545,_53d,_540)){if(_545==_540||_53f===false||!(_545=_545.parentNode)||_545.nodeType!=1){return;}}return _545;};if(_543){return on(_540,_543(_544),_541);}return on(_540,_53e,function(_546){var _547=_544(_546.target);return _547&&_541.call(_547,_546);});};};function _548(){this.cancelable=false;};function _549(){this.bubbles=false;};var _54a=[].slice,_54b=on.emit=function(_54c,type,_54d){var args=_54a.call(arguments,2);var _54e="on"+type;if("parentNode" in _54c){var _54f=args[0]={};for(var i in _54d){_54f[i]=_54d[i];}_54f.preventDefault=_548;_54f.stopPropagation=_549;_54f.target=_54c;_54f.type=type;_54d=_54f;}do{_54c[_54e]&&_54c[_54e].apply(_54c,args);}while(_54d&&_54d.bubbles&&(_54c=_54c.parentNode));return _54d&&_54d.cancelable&&_54d;};var _53a={};if(!has("event-stopimmediatepropagation")){var _550=function(){this.immediatelyStopped=true;this.modified=true;};var _538=function(_551){return function(_552){if(!_552.immediatelyStopped){_552.stopImmediatePropagation=_550;return _551.apply(this,arguments);}};};}if(has("dom-addeventlistener")){_53a={focusin:"focus",focusout:"blur"};if(has("opera")){_53a.keydown="keypress";}on.emit=function(_553,type,_554){if(_553.dispatchEvent&&document.createEvent){var _555=_553.ownerDocument.createEvent("HTMLEvents");_555.initEvent(type,!!_554.bubbles,!!_554.cancelable);for(var i in _554){var _556=_554[i];if(!(i in _555)){_555[i]=_554[i];}}return _553.dispatchEvent(_555)&&_555;}return _54b.apply(on,arguments);};}else{on._fixEvent=function(evt,_557){if(!evt){var w=_557&&(_557.ownerDocument||_557.document||_557).parentWindow||window;evt=w.event;}if(!evt){return evt;}if(_558&&evt.type==_558.type){evt=_558;}if(!evt.target){evt.target=evt.srcElement;evt.currentTarget=(_557||evt.srcElement);if(evt.type=="mouseover"){evt.relatedTarget=evt.fromElement;}if(evt.type=="mouseout"){evt.relatedTarget=evt.toElement;}if(!evt.stopPropagation){evt.stopPropagation=_559;evt.preventDefault=_55a;}switch(evt.type){case "keypress":var c=("charCode" in evt?evt.charCode:evt.keyCode);if(c==10){c=0;evt.keyCode=13;}else{if(c==13||c==27){c=0;}else{if(c==3){c=99;}}}evt.charCode=c;_55b(evt);break;}}return evt;};var _558,_55c=function(_55d){this.handle=_55d;};_55c.prototype.remove=function(){delete _dojoIEListeners_[this.handle];};var _55e=function(_55f){return function(evt){evt=on._fixEvent(evt,this);var _560=_55f.call(this,evt);if(evt.modified){if(!_558){setTimeout(function(){_558=null;});}_558=evt;}return _560;};};var _53c=function(_561,type,_562){_562=_55e(_562);if(((_561.ownerDocument?_561.ownerDocument.parentWindow:_561.parentWindow||_561.window||window)!=top||has("jscript")<5.8)&&!has("config-_allow_leaks")){if(typeof _dojoIEListeners_=="undefined"){_dojoIEListeners_=[];}var _563=_561[type];if(!_563||!_563.listeners){var _564=_563;_563=Function("event","var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}");_563.listeners=[];_561[type]=_563;_563.global=this;if(_564){_563.listeners.push(_dojoIEListeners_.push(_564)-1);}}var _565;_563.listeners.push(_565=(_563.global._dojoIEListeners_.push(_562)-1));return new _55c(_565);}return _51a.after(_561,type,_562,true);};var _55b=function(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _559=function(){this.cancelBubble=true;};var _55a=on._preventDefault=function(){this.bubbledKeyCode=this.keyCode;if(this.ctrlKey){try{this.keyCode=0;}catch(e){}}this.defaultPrevented=true;this.returnValue=false;};}if(has("touch")){var _566=function(){};var _567=window.orientation;var _537=function(_568){return function(_569){var _56a=_569.corrected;if(!_56a){var type=_569.type;try{delete _569.type;}catch(e){}if(_569.type){_566.prototype=_569;var _56a=new _566;_56a.preventDefault=function(){_569.preventDefault();};_56a.stopPropagation=function(){_569.stopPropagation();};}else{_56a=_569;_56a.type=type;}_569.corrected=_56a;if(type=="resize"){if(_567==window.orientation){return null;}_567=window.orientation;_56a.type="orientationchange";return _568.call(this,_56a);}if(!("rotation" in _56a)){_56a.rotation=0;_56a.scale=1;}var _56b=_56a.changedTouches[0];for(var i in _56b){delete _56a[i];_56a[i]=_56b[i];}}return _568.call(this,_56a);};};}return on;});},"dojo/_base/sniff":function(){define(["./kernel","./lang","../sniff"],function(dojo,lang,has){if(!1){return has;}dojo._name="browser";lang.mixin(dojo,{isBrowser:true,isFF:has("ff"),isIE:has("ie"),isKhtml:has("khtml"),isWebKit:has("webkit"),isMozilla:has("mozilla"),isMoz:has("mozilla"),isOpera:has("opera"),isSafari:has("safari"),isChrome:has("chrome"),isMac:has("mac"),isIos:has("ios"),isAndroid:has("android"),isWii:has("wii"),isQuirks:has("quirks"),isAir:has("air")});dojo.locale=dojo.locale||(has("ie")?navigator.userLanguage:navigator.language).toLowerCase();return has;});},"dojo/errors/create":function(){define(["../_base/lang"],function(lang){return function(name,ctor,base,_56c){base=base||Error;var _56d=function(_56e){if(base===Error){if(Error.captureStackTrace){Error.captureStackTrace(this,_56d);}var err=Error.call(this,_56e),prop;for(prop in err){if(err.hasOwnProperty(prop)){this[prop]=err[prop];}}this.message=_56e;this.stack=err.stack;}else{base.apply(this,arguments);}if(ctor){ctor.apply(this,arguments);}};_56d.prototype=lang.delegate(base.prototype,_56c);_56d.prototype.name=name;_56d.prototype.constructor=_56d;return _56d;};});},"dojo/_base/array":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var _56f={},u;function _570(fn){return _56f[fn]=new Function("item","index","array",fn);};function _571(some){var _572=!some;return function(a,fn,o){var i=0,l=a&&a.length||0,_573;if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_56f[fn]||_570(fn);}if(o){for(;i<l;++i){_573=!fn.call(o,a[i],i,a);if(some^_573){return !_573;}}}else{for(;i<l;++i){_573=!fn(a[i],i,a);if(some^_573){return !_573;}}}return _572;};};function _574(up){var _575=1,_576=0,_577=0;if(!up){_575=_576=_577=-1;}return function(a,x,from,last){if(last&&_575>0){return _578.lastIndexOf(a,x,from);}var l=a&&a.length||0,end=up?l+_577:_576,i;if(from===u){i=up?_576:l+_577;}else{if(from<0){i=l+from;if(i<0){i=_576;}}else{i=from>=l?l+_577:from;}}if(l&&typeof a=="string"){a=a.split("");}for(;i!=end;i+=_575){if(a[i]==x){return i;}}return -1;};};var _578={every:_571(false),some:_571(true),indexOf:_574(true),lastIndexOf:_574(false),forEach:function(arr,_579,_57a){var i=0,l=arr&&arr.length||0;if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _579=="string"){_579=_56f[_579]||_570(_579);}if(_57a){for(;i<l;++i){_579.call(_57a,arr[i],i,arr);}}else{for(;i<l;++i){_579(arr[i],i,arr);}}},map:function(arr,_57b,_57c,Ctr){var i=0,l=arr&&arr.length||0,out=new (Ctr||Array)(l);if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _57b=="string"){_57b=_56f[_57b]||_570(_57b);}if(_57c){for(;i<l;++i){out[i]=_57b.call(_57c,arr[i],i,arr);}}else{for(;i<l;++i){out[i]=_57b(arr[i],i,arr);}}return out;},filter:function(arr,_57d,_57e){var i=0,l=arr&&arr.length||0,out=[],_57f;if(l&&typeof arr=="string"){arr=arr.split("");}if(typeof _57d=="string"){_57d=_56f[_57d]||_570(_57d);}if(_57e){for(;i<l;++i){_57f=arr[i];if(_57d.call(_57e,_57f,i,arr)){out.push(_57f);}}}else{for(;i<l;++i){_57f=arr[i];if(_57d(_57f,i,arr)){out.push(_57f);}}}return out;},clearCache:function(){_56f={};}};1&&lang.mixin(dojo,_578);return _578;});},"dojo/_base/json":function(){define(["./kernel","../json"],function(dojo,json){dojo.fromJson=function(js){return eval("("+js+")");};dojo._escapeString=json.stringify;dojo.toJsonIndentStr="\t";dojo.toJson=function(it,_580){return json.stringify(it,function(key,_581){if(_581){var tf=_581.__json__||_581.json;if(typeof tf=="function"){return tf.call(_581);}}return _581;},_580&&dojo.toJsonIndentStr);};return dojo;});},"dojo/_base/window":function(){define("dojo/_base/window",["./kernel","./lang","../sniff"],function(dojo,lang,has){var ret={global:dojo.global,doc:this["document"]||null,body:function(doc){doc=doc||dojo.doc;return doc.body||doc.getElementsByTagName("body")[0];},setContext:function(_582,_583){dojo.global=ret.global=_582;dojo.doc=ret.doc=_583;},withGlobal:function(_584,_585,_586,_587){var _588=dojo.global;try{dojo.global=ret.global=_584;return ret.withDoc.call(null,_584.document,_585,_586,_587);}finally{dojo.global=ret.global=_588;}},withDoc:function(_589,_58a,_58b,_58c){var _58d=ret.doc,oldQ=has("quirks"),_58e=has("ie"),isIE,mode,pwin;try{dojo.doc=ret.doc=_589;dojo.isQuirks=has.add("quirks",dojo.doc.compatMode=="BackCompat",true,true);if(has("ie")){if((pwin=_589.parentWindow)&&pwin.navigator){isIE=parseFloat(pwin.navigator.appVersion.split("MSIE ")[1])||undefined;mode=_589.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}dojo.isIE=has.add("ie",isIE,true,true);}}if(_58b&&typeof _58a=="string"){_58a=_58b[_58a];}return _58a.apply(_58b,_58c||[]);}finally{dojo.doc=ret.doc=_58d;dojo.isQuirks=has.add("quirks",oldQ,true,true);dojo.isIE=has.add("ie",_58e,true,true);}}};1&&lang.mixin(dojo,ret);return ret;});},"dojo/dom-class":function(){define(["./_base/lang","./_base/array","./dom"],function(lang,_58f,dom){var _590="className";var cls,_591=/\s+/,a1=[""];function _592(s){if(typeof s=="string"||s instanceof String){if(s&&!_591.test(s)){a1[0]=s;return a1;}var a=s.split(_591);if(a.length&&!a[0]){a.shift();}if(a.length&&!a[a.length-1]){a.pop();}return a;}if(!s){return [];}return _58f.filter(s,function(x){return x;});};var _593={};cls={contains:function containsClass(node,_594){return ((" "+dom.byId(node)[_590]+" ").indexOf(" "+_594+" ")>=0);},add:function addClass(node,_595){node=dom.byId(node);_595=_592(_595);var cls=node[_590],_596;cls=cls?" "+cls+" ":" ";_596=cls.length;for(var i=0,len=_595.length,c;i<len;++i){c=_595[i];if(c&&cls.indexOf(" "+c+" ")<0){cls+=c+" ";}}if(_596<cls.length){node[_590]=cls.substr(1,cls.length-2);}},remove:function removeClass(node,_597){node=dom.byId(node);var cls;if(_597!==undefined){_597=_592(_597);cls=" "+node[_590]+" ";for(var i=0,len=_597.length;i<len;++i){cls=cls.replace(" "+_597[i]+" "," ");}cls=lang.trim(cls);}else{cls="";}if(node[_590]!=cls){node[_590]=cls;}},replace:function replaceClass(node,_598,_599){node=dom.byId(node);_593[_590]=node[_590];cls.remove(_593,_599);cls.add(_593,_598);if(node[_590]!==_593[_590]){node[_590]=_593[_590];}},toggle:function toggleClass(node,_59a,_59b){node=dom.byId(node);if(_59b===undefined){_59a=_592(_59a);for(var i=0,len=_59a.length,c;i<len;++i){c=_59a[i];cls[cls.contains(node,c)?"remove":"add"](node,c);}}else{cls[_59b?"add":"remove"](node,_59a);}return _59b;}};return cls;});},"dojo/_base/config":function(){define(["../has","require"],function(has,_59c){var _59d={};if(1){var src=_59c.rawConfig,p;for(p in src){_59d[p]=src[p];}}else{var _59e=function(_59f,_5a0,_5a1){for(p in _59f){p!="has"&&has.add(_5a0+p,_59f[p],0,_5a1);}};_59d=1?_59c.rawConfig:this.dojoConfig||this.djConfig||{};_59e(_59d,"config",1);_59e(_59d.has,"",1);}return _59d;});},"dojo/main":function(){define(["./_base/kernel","./has","require","./sniff","./_base/lang","./_base/array","./_base/config","./ready","./_base/declare","./_base/connect","./_base/Deferred","./_base/json","./_base/Color","./has!dojo-firebug?./_firebug/firebug","./_base/browser","./_base/loader"],function(_5a2,has,_5a3,_5a4,lang,_5a5,_5a6,_5a7){if(_5a6.isDebug){_5a3(["./_firebug/firebug"]);}1||has.add("dojo-config-require",1);if(1){var deps=_5a6.require;if(deps){deps=_5a5.map(lang.isArray(deps)?deps:[deps],function(item){return item.replace(/\./g,"/");});if(_5a2.isAsync){_5a3(deps);}else{_5a7(1,function(){_5a3(deps);});}}}return _5a2;});},"dojo/_base/event":function(){define("dojo/_base/event",["./kernel","../on","../has","../dom-geometry"],function(dojo,on,has,dom){if(on._fixEvent){var _5a8=on._fixEvent;on._fixEvent=function(evt,se){evt=_5a8(evt,se);if(evt){dom.normalizeEvent(evt);}return evt;};}var ret={fix:function(evt,_5a9){if(on._fixEvent){return on._fixEvent(evt,_5a9);}return evt;},stop:function(evt){if(has("dom-addeventlistener")||(evt&&evt.preventDefault)){evt.preventDefault();evt.stopPropagation();}else{evt=evt||window.event;evt.cancelBubble=true;on._preventDefault.call(evt);}}};if(1){dojo.fixEvent=ret.fix;dojo.stopEvent=ret.stop;}return ret;});},"dojo/sniff":function(){define(["./has"],function(has){if(1){var n=navigator,dua=n.userAgent,dav=n.appVersion,tv=parseFloat(dav);has.add("air",dua.indexOf("AdobeAIR")>=0),has.add("khtml",dav.indexOf("Konqueror")>=0?tv:undefined);has.add("webkit",parseFloat(dua.split("WebKit/")[1])||undefined);has.add("chrome",parseFloat(dua.split("Chrome/")[1])||undefined);has.add("safari",dav.indexOf("Safari")>=0&&!has("chrome")?parseFloat(dav.split("Version/")[1]):undefined);has.add("mac",dav.indexOf("Macintosh")>=0);has.add("quirks",document.compatMode=="BackCompat");has.add("ios",/iPhone|iPod|iPad/.test(dua));has.add("android",parseFloat(dua.split("Android ")[1])||undefined);if(!has("webkit")){if(dua.indexOf("Opera")>=0){has.add("opera",tv>=9.8?parseFloat(dua.split("Version/")[1])||tv:tv);}if(dua.indexOf("Gecko")>=0&&!has("khtml")&&!has("webkit")){has.add("mozilla",tv);}if(has("mozilla")){has.add("ff",parseFloat(dua.split("Firefox/")[1]||dua.split("Minefield/")[1])||undefined);}if(document.all&&!has("opera")){var isIE=parseFloat(dav.split("MSIE ")[1])||undefined;var mode=document.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}has.add("ie",isIE);}has.add("wii",typeof opera!="undefined"&&opera.wiiremote);}}return has;});},"dojo/request/handlers":function(){define(["../json","../_base/kernel","../_base/array","../has"],function(JSON,_5aa,_5ab,has){has.add("activex",typeof ActiveXObject!=="undefined");var _5ac;if(has("activex")){var dp=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML.DOMDocument"];_5ac=function(_5ad){var _5ae=_5ad.data;if(!_5ae||!_5ae.documentElement){var text=_5ad.text;_5ab.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(text);_5ae=dom;}catch(e){return false;}return true;});}return _5ae;};}var _5af={"javascript":function(_5b0){return _5aa.eval(_5b0.text||"");},"json":function(_5b1){return JSON.parse(_5b1.text||null);},"xml":_5ac};function _5b2(_5b3){var _5b4=_5af[_5b3.options.handleAs];_5b3.data=_5b4?_5b4(_5b3):(_5b3.data||_5b3.text);return _5b3;};_5b2.register=function(name,_5b5){_5af[name]=_5b5;};return _5b2;});},"dojo/aspect":function(){define("dojo/aspect",[],function(){"use strict";var _5b6,_5b7=0;function _5b8(_5b9,type,_5ba,_5bb){var _5bc=_5b9[type];var _5bd=type=="around";var _5be;if(_5bd){var _5bf=_5ba(function(){return _5bc.advice(this,arguments);});_5be={remove:function(){_5be.cancelled=true;},advice:function(_5c0,args){return _5be.cancelled?_5bc.advice(_5c0,args):_5bf.apply(_5c0,args);}};}else{_5be={remove:function(){var _5c1=_5be.previous;var next=_5be.next;if(!next&&!_5c1){delete _5b9[type];}else{if(_5c1){_5c1.next=next;}else{_5b9[type]=next;}if(next){next.previous=_5c1;}}},id:_5b7++,advice:_5ba,receiveArguments:_5bb};}if(_5bc&&!_5bd){if(type=="after"){var next=_5bc;while(next){_5bc=next;next=next.next;}_5bc.next=_5be;_5be.previous=_5bc;}else{if(type=="before"){_5b9[type]=_5be;_5be.next=_5bc;_5bc.previous=_5be;}}}else{_5b9[type]=_5be;}return _5be;};function _5c2(type){return function(_5c3,_5c4,_5c5,_5c6){var _5c7=_5c3[_5c4],_5c8;if(!_5c7||_5c7.target!=_5c3){_5c3[_5c4]=_5c8=function(){var _5c9=_5b7;var args=arguments;var _5ca=_5c8.before;while(_5ca){args=_5ca.advice.apply(this,args)||args;_5ca=_5ca.next;}if(_5c8.around){var _5cb=_5c8.around.advice(this,args);}var _5cc=_5c8.after;while(_5cc&&_5cc.id<_5c9){if(_5cc.receiveArguments){var _5cd=_5cc.advice.apply(this,args);_5cb=_5cd===_5b6?_5cb:_5cd;}else{_5cb=_5cc.advice.call(this,_5cb,args);}_5cc=_5cc.next;}return _5cb;};if(_5c7){_5c8.around={advice:function(_5ce,args){return _5c7.apply(_5ce,args);}};}_5c8.target=_5c3;}var _5cf=_5b8((_5c8||_5c7),type,_5c5,_5c6);_5c5=null;return _5cf;};};var _5d0=_5c2("after");var _5d1=_5c2("before");var _5d2=_5c2("around");return {before:_5d1,around:_5d2,after:_5d0};});},"dojo/ready":function(){define("dojo/ready",["./_base/kernel","./has","require","./domReady","./_base/lang"],function(dojo,has,_5d3,_5d4,lang){var _5d5=0,_5d6,_5d7=[],_5d8=0,_5d9=function(){_5d5=1;dojo._postLoad=dojo.config.afterOnLoad=true;if(_5d7.length){_5d6(_5da);}},_5da=function(){if(_5d5&&!_5d8&&_5d7.length){_5d8=1;var f=_5d7.shift();try{f();}finally{_5d8=0;}_5d8=0;if(_5d7.length){_5d6(_5da);}}};_5d3.on("idle",_5da);_5d6=function(){if(_5d3.idle()){_5da();}};var _5db=dojo.ready=dojo.addOnLoad=function(_5dc,_5dd,_5de){var _5df=lang._toArray(arguments);if(typeof _5dc!="number"){_5de=_5dd;_5dd=_5dc;_5dc=1000;}else{_5df.shift();}_5de=_5de?lang.hitch.apply(dojo,_5df):function(){_5dd();};_5de.priority=_5dc;for(var i=0;i<_5d7.length&&_5dc>=_5d7[i].priority;i++){}_5d7.splice(i,0,_5de);_5d6();};1||has.add("dojo-config-addOnLoad",1);if(1){var dca=dojo.config.addOnLoad;if(dca){_5db[(lang.isArray(dca)?"apply":"call")](dojo,dca);}}if(1&&dojo.config.parseOnLoad&&!dojo.isAsync){_5db(99,function(){if(!dojo.parser){dojo.deprecated("Add explicit require(['dojo/parser']);","","2.0");_5d3(["dojo/parser"]);}});}if(1){_5d4(_5d9);}else{_5d9();}return _5db;});},"dojo/_base/connect":function(){define(["./kernel","../on","../topic","../aspect","./event","../mouse","./sniff","./lang","../keys"],function(dojo,on,hub,_5e0,_5e1,_5e2,has,lang){has.add("events-keypress-typed",function(){var _5e3={charCode:0};try{_5e3=document.createEvent("KeyboardEvent");(_5e3.initKeyboardEvent||_5e3.initKeyEvent).call(_5e3,"keypress",true,true,null,false,false,false,false,9,3);}catch(e){}return _5e3.charCode==0&&!has("opera");});function _5e4(obj,_5e5,_5e6,_5e7,_5e8){_5e7=lang.hitch(_5e6,_5e7);if(!obj||!(obj.addEventListener||obj.attachEvent)){return _5e0.after(obj||dojo.global,_5e5,_5e7,true);}if(typeof _5e5=="string"&&_5e5.substring(0,2)=="on"){_5e5=_5e5.substring(2);}if(!obj){obj=dojo.global;}if(!_5e8){switch(_5e5){case "keypress":_5e5=_5e9;break;case "mouseenter":_5e5=_5e2.enter;break;case "mouseleave":_5e5=_5e2.leave;break;}}return on(obj,_5e5,_5e7,_5e8);};var _5ea={106:42,111:47,186:59,187:43,188:44,189:45,190:46,191:47,192:96,219:91,220:92,221:93,222:39,229:113};var _5eb=has("mac")?"metaKey":"ctrlKey";var _5ec=function(evt,_5ed){var faux=lang.mixin({},evt,_5ed);_5ee(faux);faux.preventDefault=function(){evt.preventDefault();};faux.stopPropagation=function(){evt.stopPropagation();};return faux;};function _5ee(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _5e9;if(has("events-keypress-typed")){var _5ef=function(e,code){try{return (e.keyCode=code);}catch(e){return 0;}};_5e9=function(_5f0,_5f1){var _5f2=on(_5f0,"keydown",function(evt){var k=evt.keyCode;var _5f3=(k!=13)&&k!=32&&(k!=27||!has("ie"))&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222)&&k!=229;if(_5f3||evt.ctrlKey){var c=_5f3?0:k;if(evt.ctrlKey){if(k==3||k==13){return _5f1.call(evt.currentTarget,evt);}else{if(c>95&&c<106){c-=48;}else{if((!evt.shiftKey)&&(c>=65&&c<=90)){c+=32;}else{c=_5ea[c]||c;}}}}var faux=_5ec(evt,{type:"keypress",faux:true,charCode:c});_5f1.call(evt.currentTarget,faux);if(has("ie")){_5ef(evt,faux.keyCode);}}});var _5f4=on(_5f0,"keypress",function(evt){var c=evt.charCode;c=c>=32?c:0;evt=_5ec(evt,{charCode:c,faux:true});return _5f1.call(this,evt);});return {remove:function(){_5f2.remove();_5f4.remove();}};};}else{if(has("opera")){_5e9=function(_5f5,_5f6){return on(_5f5,"keypress",function(evt){var c=evt.which;if(c==3){c=99;}c=c<32&&!evt.shiftKey?0:c;if(evt.ctrlKey&&!evt.shiftKey&&c>=65&&c<=90){c+=32;}return _5f6.call(this,_5ec(evt,{charCode:c}));});};}else{_5e9=function(_5f7,_5f8){return on(_5f7,"keypress",function(evt){_5ee(evt);return _5f8.call(this,evt);});};}}var _5f9={_keypress:_5e9,connect:function(obj,_5fa,_5fb,_5fc,_5fd){var a=arguments,args=[],i=0;args.push(typeof a[0]=="string"?null:a[i++],a[i++]);var a1=a[i+1];args.push(typeof a1=="string"||typeof a1=="function"?a[i++]:null,a[i++]);for(var l=a.length;i<l;i++){args.push(a[i]);}return _5e4.apply(this,args);},disconnect:function(_5fe){if(_5fe){_5fe.remove();}},subscribe:function(_5ff,_600,_601){return hub.subscribe(_5ff,lang.hitch(_600,_601));},publish:function(_602,args){return hub.publish.apply(hub,[_602].concat(args));},connectPublisher:function(_603,obj,_604){var pf=function(){_5f9.publish(_603,arguments);};return _604?_5f9.connect(obj,_604,pf):_5f9.connect(obj,pf);},isCopyKey:function(e){return e[_5eb];}};_5f9.unsubscribe=_5f9.disconnect;1&&lang.mixin(dojo,_5f9);return _5f9;});},"dojo/errors/CancelError":function(){define(["./create"],function(_605){return _605("CancelError",null,null,{dojoType:"cancel"});});}}});(function(){var _606=this.require;_606({cache:{}});!_606.async&&_606(["dojo"]);_606.boot&&_606.apply(null,_606.boot);})(); \ No newline at end of file
--- a/server/src/main/webapp/js/main_coweb.js Fri Aug 17 18:36:12 2012 +0200 +++ b/server/src/main/webapp/js/main_coweb.js Mon Aug 20 16:07:15 2012 +0200 @@ -18,5 +18,7 @@ // on page load, prepare, join, and update in a session var sess = coweb.initSession(); sess.prepare(); + this.collab = coweb.initCollab({id:'renkan'}); }); }); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/js/models.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,148 @@ +(function() { + + var root = this; + + var Backbone = root.Backbone; + + var Models = root.Rkns.Models = {}; + + + Models.getUID = function(obj) { + var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); + return obj.type + "-" + guid; + }; + + + var RenkanModel = Backbone.RelationalModel.extend({ + idAttribute : "_id", + constructor: function(options) { + + if (typeof options !== "undefined") { + options._id = options.id || Models.getUID(this); + options.title = options.title || "(untitled " + this.type + ")"; + options.description = options.description || ""; + options.uri = options.uri || ""; + + if(typeof this.prepare === "function") { + options = this.prepare(options); + } + } + Backbone.RelationalModel.prototype.constructor.call(this, options); + }, + validate: function() { + if(!this.type) { + return "object has no type"; + } + }, + addReference : function(_options, _propName, _list, _id, _default) { + var _element = _list.get(_id); + if (typeof _element === "undefined" && typeof _default !== "undefined") { + _options[_propName ] = _default; + } + else { + _options[_propName ] = _element; + } + } + }); + + + // USER + var User = Models.User = root.Rkns.Models.User = RenkanModel.extend({ + type: "user", + prepare: function(options) { + options.color = options.color || "#666666"; + return options; + } + + }); + + // NODE + var Node = Models.Node = root.Rkns.Models.Node = RenkanModel.extend({ + type: "node", + relations: [{ + type: Backbone.HasOne, + key: "created_by", + relatedModel: User + }], + prepare: function(options) { + project = options.project; + this.addReference(options, "created_by", project.get("users"), options.created_by, project.current_user); + options.description = options.description || ""; + return options; + } + + }); + + // EDGE + var Edge = Models.Edge = root.Rkns.Models.Edge = RenkanModel.extend({ + type: "edge", + relations: [ + { + type: Backbone.HasOne, + key: "created_by", + relatedModel: User + }, + { + type: Backbone.HasOne, + key: "from", + relatedModel: Node + }, + { + type: Backbone.HasOne, + key: "to", + relatedModel: Node + }, + ], + prepare: function(options) { + project = options.project; + this.addReference(options, "created_by", options.created_by, project.get("users"), project.current_user); + this.addReference(options, "from", options.from, project.get("nodes")); + this.addReference(options, "to", options.to, project.get("nodes")); + return options; + } + }); + + // PROJECT + var Project = Models.Project = root.Rkns.Models.Project = RenkanModel.extend({ + type: "project", + relations: [ + { + type: Backbone.HasMany, + key: "users", + relatedModel: User, + reverseRelation: { + key: 'project', + includeInJSON: '_id' + }, + }, + { + type: Backbone.HasMany, + key: "nodes", + relatedModel: Node, + reverseRelation: { + key: 'project', + includeInJSON: '_id' + }, + }, + { + type: Backbone.HasMany, + key: "edges", + relatedModel: Edge, + reverseRelation: { + key: 'project', + includeInJSON: '_id' + }, + } + ], + addNode: function(_props) { + _props.project = this; + this.get("nodes").push(_props); + } + }); + + +}).call(this); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/js/underscore.js Mon Aug 20 16:07:15 2012 +0200 @@ -0,0 +1,32 @@ +// Underscore.js 1.3.3 +// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore +(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== +c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break; +g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a, +c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&& +a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a, +c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b, +a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= +function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&& +(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]}; +j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a, +0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a, +e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a= +i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<= +1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c= +i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h= +g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0)); +return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&& +c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty= +function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"}; +b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a, +b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId= +function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape|| +u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c}; +b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d, +this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
--- a/server/src/main/webapp/render-test.html Fri Aug 17 18:36:12 2012 +0200 +++ b/server/src/main/webapp/render-test.html Mon Aug 20 16:07:15 2012 +0200 @@ -9,13 +9,19 @@ <script src="lib/jquery.min.js"></script> <script src="lib/jquery.mousewheel.min.js"></script> <script src="lib/underscore-min.js"></script> + <script src="js/backbone.js"></script> + <script src="js/backbone-relational.js"></script> <script src="lib/paper.js"></script> <script src="js/main.js"></script> + <script src="js/models.js"></script> <script src="js/i18n.js"></script> <script src="js/model.js"></script> <script src="js/json-serializer.js"></script> <script src="js/random-data.js"></script> <script src="js/paper-renderer.js"></script> + <script type="text/javascript" src="js/config.js"></script> + <script type="text/javascript" src="js/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script> + <script data-main="main" src="js/main_coweb.js"></script> <script type="text/javascript"> var _proj; $(function() { @@ -29,7 +35,7 @@ color: "#0000ff" } }); - }); + }); </script> <link rel="stylesheet" href="css/renkan.css" /> <style type="text/css">