Javascript templating shootoff (extended) (v51)

Revision 51 of this benchmark created by Kyle Simpson on


Description

Many engines gathered across all revisions of the original shoot off.

DO NOT LINK TO RAW.GITHUB.COM -- It will NOT work in latest firefox versions

Please:

  • All new test cases should use pre-compiled templates when able.
  • Do not remove test cases unless broken (try to fix before removal).
  • Do not cheat by using faster script blocks unless the engine accepts no other input.
  • If hard including a new library, or linking to a specific revision, please note the version.
  • Do not include home brew code; engines should be published prior for peer review.
  • Do not link directly to raw.github.com
  • Test your modifications in firefox 9 and IE7 at a minimum before publishing. Links to github raw will fail in one or both of these browsers.

Libraries (in no particular order):

Preparation HTML

<!---------------------------------------->
<!-- EXTERNAL LIBRARIES HOSTED BY A CDN -->
<!---------------------------------------->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="http://cdn.kendostatic.com/2011.2.804/js/kendo.all.min.js"></script>
<script src="http://twitter.github.com/hogan.js/builds/1.0.3/hogan.js"></script>
<script src="http://beebole.com/pure/wp-content/themes/BeeBole-pure/libs/pure.js"></script>
<script src="http://linkedin.github.com/dustjs/dist/dust-full-1.0.0.js"></script>
<script src="http://sstephenson.github.com/eco/dist/eco.js"></script>
<script src="http://embeddedjs.com/javascripts/ejs_production.js"></script>
<script src="https://github.com/downloads/donyantony/cdnjs/runtime.min.js"></script>
<script src="http://terrainformatica.com/kite/kite.js"></script>
<script src="http://borismoore.github.com/jsrender/jsrender.js"></script>
<script src="http://satchmorun.github.com/mote/mote.js"></script>
<script src="http://sandbox.thewikies.com/test/template.js"></script>
<script src="http://getify.github.com/grips/deploy_0.3.3-a/grips-full.min.js"></script>

<!--------------------------->
<!-- DOM TEMPLATES         -->
<!--------------------------->
<div class="pure">
        <h1 class='header'></h1>
        <h2 class='header2'></h2>
        <h3 class='header3'></h3>
        <h4 class='header4'></h4>
        <h5 class='header5'></h5>
        <h6 class='header6'></h6>
</div>

<script>
/****************************************
 MASTER TEMPLATE DATA
 ****************************************/
window.tpl = {};
window.tpl.vars = {
   header: "Header",
   header2: "Header2",
   header3: "Header3",
   header4: "Header4",
   header5: "Header5",
   header6: "Header6",
   list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
};
window.tpl.vars2 = {
   header: "Header",
   header2: "Header2",
   header3: "Header3",
   header4: "Header4",
   header5: "Header5",
   header6: "Header6",
   list: [{i:'1'}, {i:'2'}, {i:'3'}, {i:'4'}, {i:'5'}, {i:'6'}, {i:'7'}, {i:'8'}, {i:'9'}, {i:'10'}]
};  

/****************************************
 TEMPLATE ENGINES NOT HOSTED BY A CDN (github)
 ****************************************/
//Please minify any hard included library and note the version.

//Resig Template Function (modified to support ')
function rtmpl(a){var b="var p=[];"+"with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").replace(/'(?=[^#]*#>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<#=(.+?)#>/g,"',$1,'").split("<#").join("');").split("#>").join("p.push('")+"');}return p.join('');";return new Function("obj",b)}

//Resig modified template function (no "with" block)
function rtmpl2(a){var b="var p=[];"+"p.push('"+a.replace(/[\r\t\n]/g," ").replace(/'(?=[^#]*#>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<#=(.+?)#>/g,"',$1,'").split("<#").join("');").split("#>").join("p.push('")+"');return p.join('');";return new Function("data",b)}

//Mustache 5.0 dev
var Mustache=(typeof module!=="undefined"&&module.exports)||{};(function(w){w.name="mustache.js";w.version="0.5.0-dev";w.tags=["{{","}}"];w.parse=m;w.compile=e;w.render=v;w.clearCache=u;w.to_html=function(A,y,z,B){var x=v(A,y,z);if(typeof B==="function"){B(x)}else{return x}};var s=Object.prototype.toString;var f=Array.isArray;var b=Array.prototype.forEach;var g=String.prototype.trim;var i;if(f){i=f}else{i=function(x){return s.call(x)==="[object Array]"}}var r;if(b){r=function(y,z,x){return b.call(y,z,x)}}else{r=function(A,B,z){for(var y=0,x=A.length;y<x;++y){B.call(z,A[y],y,A)}}}var k=/^\s*$/;function c(x){return k.test(x)}var p;if(g){p=function(x){return x==null?"":g.call(x)}}else{var n,h;if(c("\xA0")){n=/^\s+/;h=/\s+$/}else{n=/^[\s\xA0]+/;h=/[\s\xA0]+$/}p=function(x){return x==null?"":String(x).replace(n,"").replace(h,"")}}var d={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function o(x){return String(x).replace(/&(?!\w+;)|[<>"']/g,function(y){return d[y]||y})}function l(D,F,G,z){z=z||"<template>";var H=F.split("\n"),x=Math.max(G-3,0),A=Math.min(H.length,G+3),y=H.slice(x,A);var E;for(var B=0,C=y.length;B<C;++B){E=B+x+1;y[B]=(E===G?" >> ":"    ")+y[B]}D.template=F;D.line=G;D.file=z;D.message=[z+":"+G,y.join("\n"),"",D.message].join("\n");return D}function t(x,F,E){if(x==="."){return F[F.length-1]}var D=x.split(".");var B=D.length-1;var C=D[B];var G,y,A=F.length,z,H;while(A){H=F.slice(0);y=F[--A];z=0;while(z<B){y=y[D[z++]];if(y==null){break}H.push(y)}if(y&&C in y){G=y[C];break}}if(typeof G==="function"){G=G.call(H[H.length-1])}if(G==null){return E}return G}function j(A,x,E,z){var y="";var C=t(A,x);if(z){if(C==null||C===false||(i(C)&&C.length===0)){y+=E()}}else{if(i(C)){r(C,function(F){x.push(F);y+=E();x.pop()})}else{if(typeof C==="object"){x.push(C);y+=E();x.pop()}else{if(typeof C==="function"){var B=x[x.length-1];var D=function(F){return v(F,B)};y+=C.call(B,E(),D)||""}else{if(C){y+=E()}}}}}return y}function m(Z,B){B=B||{};var K=B.tags||w.tags,L=K[0],G=K[K.length-1];var y=['var buffer = "";',"\nvar line = 1;","\ntry {",'\nbuffer += "'];var F=[],aa=false,X=false;var V=function(){if(aa&&!X&&!B.space){while(F.length){y.splice(F.pop(),1)}}else{F=[]}aa=false;X=false};var S=[],P,C,M;var U=function(ab){K=p(ab).split(/\s+/);C=K[0];M=K[K.length-1]};var J=function(ab){y.push('";',P,'\nvar partial = partials["'+p(ab)+'"];',"\nif (partial) {","\n  buffer += render(partial,stack[stack.length - 1],partials);","\n}",'\nbuffer += "')};var x=function(ad,ab){var ac=p(ad);if(ac===""){throw l(new Error("Section name may not be empty"),Z,I,B.file)}S.push({name:ac,inverted:ab});y.push('";',P,'\nvar name = "'+ac+'";',"\nvar callback = (function () {","\n  return function () {",'\n    var buffer = "";','\nbuffer += "')};var E=function(ab){x(ab,true)};var T=function(ac){var ab=p(ac);var ae=S.length!=0&&S[S.length-1].name;if(!ae||ab!=ae){throw l(new Error('Section named "'+ab+'" was never opened'),Z,I,B.file)}var ad=S.pop();y.push('";',"\n    return buffer;","\n  };","\n})();");if(ad.inverted){y.push("\nbuffer += renderSection(name,stack,callback,true);")}else{y.push("\nbuffer += renderSection(name,stack,callback);")}y.push('\nbuffer += "')};var W=function(ab){y.push('";',P,'\nbuffer += lookup("'+p(ab)+'",stack,"");','\nbuffer += "')};var z=function(ab){y.push('";',P,'\nbuffer += escapeHTML(lookup("'+p(ab)+'",stack,""));','\nbuffer += "')};var I=1,Y,D;for(var Q=0,R=Z.length;Q<R;++Q){if(Z.slice(Q,Q+L.length)===L){Q+=L.length;Y=Z.substr(Q,1);P="\nline = "+I+";";C=L;M=G;aa=true;switch(Y){case"!":Q++;D=null;break;case"=":Q++;G="="+G;D=U;break;case">":Q++;D=J;break;case"#":Q++;D=x;break;case"^":Q++;D=E;break;case"/":Q++;D=T;break;case"{":G="}"+G;case"&":Q++;X=true;D=W;break;default:X=true;D=z}var A=Z.indexOf(G,Q);if(A===-1){throw l(new Error('Tag "'+L+'" was not closed properly'),Z,I,B.file)}var O=Z.substring(Q,A);if(D){D(O)}var N=0;while(~(N=O.indexOf("\n",N))){I++;N++}Q=A+G.length-1;L=C;G=M}else{Y=Z.substr(Q,1);switch(Y){case'"':case"\\":X=true;y.push("\\"+Y);break;case"\r":break;case"\n":F.push(y.length);y.push("\\n");V();I++;break;default:if(c(Y)){F.push(y.length)}else{X=true}y.push(Y)}}}if(S.length!=0){throw l(new Error('Section "'+S[S.length-1].name+'" was not closed properly'),Z,I,B.file)}V();y.push('";',"\nreturn buffer;","\n} catch (e) { throw {error: e, line: line}; }");var H=y.join("").replace(/buffer \+= "";\n/g,"");if(B.debug){if(typeof console!="undefined"&&console.log){console.log(H)}else{if(typeof print==="function"){print(H)}}}return H}function q(B,z){var y="view,partials,stack,lookup,escapeHTML,renderSection,render";var x=m(B,z);var A=new Function(y,x);return function(D,E){E=E||{};var C=[D];try{return A(D,E,C,t,o,j,v)}catch(F){throw l(F.error,B,F.line,z.file)}}}var a={};function u(){a={}}function e(y,x){x=x||{};if(x.cache!==false){if(!a[y]){a[y]=q(y,x)}return a[y]}return q(y,x)}function v(z,x,y){return e(z)(x,y)}})(Mustache);

//jQote2 (10/21/2010)
(function($){var _=false,E1="UndefinedTemplateError",E2="TemplateCompilationError",E3="TemplateExecutionError",A="[object Array]",S="[object String]",F="[object Function]",n=1,c="%",q=/^[^<]*(<[\w\W]+>)[^>]*$/,ts=Object.prototype.toString;function r(e,x){throw ($.extend(e,x),e)}function dns(f) {var a=[];if(ts.call(f)!==A)return _;for(var i=0,l=f.length;i<l;i++)a[i]=f[i].jqote_id;return a.length?a.sort().join('.').replace(/(\b\d+\b)\.(?:\1(\.|$))+/g,"$1$2"):_}function l(s,t){var f,g=[],t=t||c,x=ts.call(s);if(x===F)return s.jqote_id?[s]:_;if(x!==A)return[$.jqotec(s,t)];if(x===A)for(var i=0,l=s.length;i<l;i++)return g.length?g:_}$.fn.extend({jqote:function(x,y){var x=ts.call(x)===A?x:[x],d="";this.each(function(i){var f=$.jqotec(this,y);for(var j=0;j<x.length;j++)d+=f.call(x[j],i,j,x,f)});return d}});$.each({app:"append",pre:"prepend",sub:"html"},function(x,y){$.fn["jqote"+x]=function(e,d,t){var p,r,s=$.jqote(e,d,t),$$=!q.test(s)?function(s){return $(document.createTextNode(s))}:$;if(!!(p=dns(l(e))))r=new RegExp("(^|\\.)"+p.split(".").join("\\.(.*)?")+"(\\.|$)");return this.each(function(){var z=$$(s);$(this)[y](z);(z[0].nodeType===3?$(this):z).trigger("jqote."+x,[z,r])})}});
$.extend({jqote:function(e,d,t){var s="",t=t||c,f=l(e);if(f===_)r(new Error("Empty or undefined template passed to $.jqote"),{type:E1});d=ts.call(d)!==A?[d]:d;for(var i=0,m=f.length;i<m;i++)for(var j=0;j<d.length;j++)s+=f[i].call(d[j],i,j,d,f[i]);return s},jqotec:function(x,t){var h,e,y,t=t||c,z=ts.call(x);if(z===S&&q.test(x)){e=y=x;if(h=$.jqotecache[x])return h}else{e=z===S||x.nodeType?$(x):x instanceof jQuery?x:null;if(!e[0]||!(y=e[0].innerHTML)&&!(y=e.text()))r(new Error("Empty or undefined template passed to $.jqotec"),{type:E1});if(h=$.jqotecache[$.data(e[0],"jqote_id")])return h}var s="",i,a=y.replace(/\s*<!\[CDATA\[\s*|\s*\]\]>\s*|[\r\n\t]/g,"").split("<"+t).join(t+">\x1b").split(t+">");for(var m=0,k=a.length;m<k;m++)s+=a[m].charAt(0)!=="\x1b"?"out+='"+a[m].replace(/(\\|["'])/g,"\\$1")+"'":(a[m].charAt(1)==="="?";out+=("+a[m].substr(2)+");":(a[m].charAt(1)==="!"?";out+=$.jqotenc(("+a[m].substr(2)+"));":";"+a[m].substr(1)));s="try{"+('var out="";'+s+";return out;").split("out+='';").join("").split('var out="";out+=').join("var out=")+'}catch(e){e.type="'+E3+'";e.args=arguments;e.template=arguments.callee.toString();throw e;}';try{var f=new Function("i, j, data, fn",s)}catch(e){r(e,{type:E2})}i=e instanceof jQuery?$.data(e[0],"jqote_id",n):e;return $.jqotecache[i]=(f.jqote_id=n++,f)},
jqotefn:function(e){var t=ts.call(e),i=t===S&&q.test(e)?e:$.data($(e)[0],"jqote_id");return $.jqotecache[i]||_},jqotetag:function(s){if(ts.call(s)===S)c=s},jqotenc:function(s){return s.toString().replace(/&(?!\w+;)/g,'&#38;').split('<').join('&#60;').split('>').join('&#62;').split('"').join('&#34;').split("'").join('&#39;')},jqotecache:{}});$.event.special.jqote={add:function(o){var n,h=o.handler,d=!o.data?[]:ts.call(o.data)!==A?[o.data]:o.data;if(!o.namespace)o.namespace="app.pre.sub";if(!d.length||!(n=dns(l(d))))return;o.handler=function(e,m,r){return !r||r.test(n)?h.apply(this,[e,m]):null}}}})(jQuery);

//dot 0.2.0
// Laura Doktorova https://github.com/olado/doT
(function(){function o(){var b={"&":"&#38;","<":"&#60;",">":"&#62;",'"':"&#34;","'":"&#39;","/":"&#47;"},a=/&(?!\\w+;)|<|>|"|'|\//g;return function(f){return f?f.toString().replace(a,function(g){return b[g]||g}):f}}function p(b,a,f){return(typeof a==="string"?a:a.toString()).replace(b.define||h,function(g,e,c,i){if(e.indexOf("def.")===0)e=e.substring(4);if(!(e in f))if(c===":")f[e]=i;else eval("def['"+e+"']="+i);return""}).replace(b.use||h,function(g,e){var c=eval(e);return c?p(b,c,f):c})}function l(b){return b.replace(/\\('|\\)/g,
"$1").replace(/[\r\t\n]/g," ")}var j={version:"0.2.0",templateSettings:{evaluate:/\{\{([\s\S]+?)\}\}/g,interpolate:/\{\{=([\s\S]+?)\}\}/g,encode:/\{\{!([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,conditional:/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,varname:"it",strip:true,append:true,selfcontained:false},template:undefined,compile:undefined},m=function(){return this||(0,eval)("this")}();
if(typeof module!=="undefined"&&module.exports)module.exports=j;else if(typeof define==="function"&&define.amd)define(function(){return j});else m.doT=j;m.encodeHTML=o();var q={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},h=/$^/;j.template=function(b,a,f){a=a||j.templateSettings;var g=a.append?q.append:q.split,e,c=0,i;if(a.use||a.define){var r=m.def;m.def=f||{};b=p(a,b,m.def);m.def=r}b=("var out='"+(a.strip?b.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g,
" ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):b).replace(/'|\\/g,"\\$&").replace(a.interpolate||h,function(n,d){return g.start+l(d)+g.end}).replace(a.encode||h,function(n,d){e=true;return g.startencode+l(d)+g.end}).replace(a.conditional||h,function(n,d,k){return d?k?"';}else if("+l(k)+"){out+='":"';}else{out+='":k?"';if("+l(k)+"){out+='":"';}out+='"}).replace(a.iterate||h,function(n,d,k,s){if(!d)return"';} } out+='";c+=1;i=s||"i"+c;d=l(d);return"';var arr"+c+"="+d+";if(arr"+c+"){var "+k+","+i+"=-1,l"+
c+"=arr"+c+".length-1;while("+i+"<l"+c+"){"+k+"=arr"+c+"["+i+"+=1];out+='"}).replace(a.evaluate||h,function(n,d){return"';"+l(d)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|}|^|{)out\+='';/g,"$1").replace(/\+''/g,"").replace(/(\s|;|}|^|{)out\+=''\+/g,"$1out+=");if(e&&a.selfcontained)b="var encodeHTML=("+o.toString()+"());"+b;try{return new Function(a.varname,b)}catch(t){typeof console!=="undefined"&&console.log("Could not create a template function: "+
b);throw t;}};j.compile=function(b,a){return j.template(b,null,a)}})();


//doT 2
(function(){var a={version:"0.1.2"};typeof module!="undefined"&&module.exports?module.exports=a:this.doU=a,a.templateSettings={begin:"{{",end:"}}",varname:"it"},a.template=function(b,c){c=c||a.templateSettings;var d="",e=c.begin,f=c.end,g,h,i=b.replace(/\s*<!\[CDATA\[\s*|\s*\]\]>\s*|[\r\n\t]|(\/\*[\s\S]*?\*\/)/g,"").split(e).join(f+"").split(f);for(g=0,h=i.length;g<h;g++)d+=i[g].charAt(0)!==""?"out+='"+i[g].replace(/(\\|["'])/g,"\\$1")+"'":i[g].charAt(1)==="="?";out+=("+i[g].substr(2)+");":i[g].charAt(1)==="!"?";out+=("+i[g].substr(2)+").toString().replace(/&(?!\\w+;)/g, '&#38;').split('<').join('&#60;').split('>').join('&#62;').split('"+'"'+"').join('&#34;').split("+'"'+"'"+'"'+").join('&#39;').split('/').join('&#x2F;');":";"+i[g].substr(1);d=('var out="";'+d+";return out;").split("out+='';").join("").split('var out="";out+=').join("var out=");try{return new Function(c.varname,d)}catch(j){throw typeof console!="undefined"&&console.log("Could not create a template function: "+d),j}}})();


//Haml (July 16 2011)
var Haml;(function(){var matchers,self_close_tags,embedder,forceXML,escaperName,escapeHtmlByDefault;function html_escape(text){return(text+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;")}function render_attribs(attribs){var key,value,result=[];for(key in attribs){if(key!=="_content"&&attribs.hasOwnProperty(key)){switch(attribs[key]){case"undefined":case"false":case"null":case'""':break;default:try{value=JSON.parse("["+attribs[key]+"]")[0];if(value===true){value=key}else{if(typeof value==="string"&&embedder.test(value)){value='" +\n'+parse_interpol(html_escape(value))+' +\n"'}else{value=html_escape(value)}}result.push(" "+key+'=\\"'+value+'\\"')}catch(e){result.push(" "+key+'=\\"" + '+escaperName+"("+attribs[key]+') + "\\"')}}}}return result.join("")}function parse_attribs(line){var attributes={},l=line.length,i,c,count=1,quote=false,skip=false,open,close,joiner,seperator,pair={start:1,middle:null,end:null};if(!(l>0&&(line.charAt(0)==="{"||line.charAt(0)==="("))){return{_content:line[0]===" "?line.substr(1,l):line}}open=line.charAt(0);close=(open==="{")?"}":")";joiner=(open==="{")?":":"=";seperator=(open==="{")?",":" ";function process_pair(){if(typeof pair.start==="number"&&typeof pair.middle==="number"&&typeof pair.end==="number"){var key=line.substr(pair.start,pair.middle-pair.start).trim(),value=line.substr(pair.middle+1,pair.end-pair.middle-1).trim();attributes[key]=value}pair={start:null,middle:null,end:null}}for(i=1;count>0;i+=1){if(i>l){throw"Malformed attribute block"}c=line.charAt(i);if(skip){skip=false}else{if(quote){if(c==="\\"){skip=true}if(c===quote){quote=false}}else{if(c==='"'||c==="'"){quote=c}if(count===1){if(c===joiner){pair.middle=i}if(c===seperator||c===close){pair.end=i;process_pair();if(c===seperator){pair.start=i+1}}}if(c===open||c==="("){count+=1}if(c===close||(count>1&&c===")")){count-=1}}}}attributes._content=line.substr(i,line.length);return attributes}function parse_interpol(value){var items=[],pos=0,next=0,match;while(true){next=value.substr(pos).search(embedder);if(next<0){if(pos<value.length){items.push(JSON.stringify(value.substr(pos)))}break}items.push(JSON.stringify(value.substr(pos,next)));pos+=next;match=value.substr(pos).match(embedder);next=match[0].length;if(next<0){break}if(match[1]==="#"){items.push(escaperName+"("+(match[2]||match[3])+")")}else{items.push(match[2]||match[3])}pos+=next}return items.filter(function(part){return part&&part.length>0}).join(" +\n")}embedder=/([#!])\{([^}]*)\}/;self_close_tags=["meta","img","link","br","hr","input","area","base"];matchers=[{name:"html tags",regexp:/^(\s*)((?:[.#%][a-z_\-][a-z0-9_:\-]*)+)(.*)$/i,process:function(){var line_beginning,tag,classes,ids,attribs,content,whitespaceSpecifier,whitespace={},output;line_beginning=this.matches[2];classes=line_beginning.match(/\.([a-z_\-][a-z0-9_\-]*)/gi);ids=line_beginning.match(/\#([a-z_\-][a-z0-9_\-]*)/gi);tag=line_beginning.match(/\%([a-z_\-][a-z0-9_:\-]*)/gi);tag=tag?tag[0].substr(1,tag[0].length):"div";attribs=this.matches[3];if(attribs){attribs=parse_attribs(attribs);if(attribs._content){var leader0=attribs._content.charAt(0),leader1=attribs._content.charAt(1),leaderLength=0;if(leader0=="<"){leaderLength++;whitespace.inside=true;if(leader1==">"){leaderLength++;whitespace.around=true}}else{if(leader0==">"){leaderLength++;whitespace.around=true;if(leader1=="<"){leaderLength++;whitespace.inside=true}}}attribs._content=attribs._content.substr(leaderLength);this.contents.unshift(attribs._content.trim());delete (attribs._content)}}else{attribs={}}if(classes){classes=classes.map(function(klass){return klass.substr(1,klass.length)}).join(" ");if(attribs["class"]){try{attribs["class"]=JSON.stringify(classes+" "+JSON.parse(attribs["class"]))}catch(e){attribs["class"]=JSON.stringify(classes+" ")+" + "+attribs["class"]}}else{attribs["class"]=JSON.stringify(classes)}}if(ids){ids=ids.map(function(id){return id.substr(1,id.length)}).join(" ");if(attribs.id){attribs.id=JSON.stringify(ids+" ")+attribs.id}else{attribs.id=JSON.stringify(ids)}}attribs=render_attribs(attribs);content=this.render_contents();if(content==='""'){content=""}if(whitespace.inside){if(content.length==0){content='"  "'}else{try{content='" '+JSON.parse(content)+' "'}catch(e){content='" "+\n'+content+'+\n" "'}}}if(forceXML?content.length>0:self_close_tags.indexOf(tag)==-1){output='"<'+tag+attribs+'>"'+(content.length>0?" + \n"+content:"")+' + \n"</'+tag+'>"'}else{output='"<'+tag+attribs+' />"'}if(whitespace.around){output='" '+output.substr(1,output.length-2)+' "'}return output}},{name:"each loop",regexp:/^(\s*)(?::for|:each)\s+(?:([a-z_][a-z_\-]*),\s*)?([a-z_][a-z_\-]*)\s+in\s+(.*)(\s*)$/i,process:function(){var ivar=this.matches[2]||"__key__",vvar=this.matches[3],avar=this.matches[4],rvar="__result__";if(this.matches[5]){this.contents.unshift(this.matches[5])}return"(function () { var "+rvar+" = [], "+ivar+", "+vvar+"; for ("+ivar+" in "+avar+") { if ("+avar+".hasOwnProperty("+ivar+")) { "+vvar+" = "+avar+"["+ivar+"]; "+rvar+".push(\n"+(this.render_contents()||"''")+"\n); } } return "+rvar+'.join(""); }).call(this)'}},{name:"if",regexp:/^(\s*):if\s+(.*)\s*$/i,process:function(){var condition=this.matches[2];return"(function () { if ("+condition+") { return (\n"+(this.render_contents()||"")+'\n);} else { return ""; } }).call(this)'}},{name:"silent-comments",regexp:/^(\s*)-#\s*(.*)\s*$/i,process:function(){return'""'}},{name:"silent-comments",regexp:/^(\s*)\/\s*(.*)\s*$/i,process:function(){this.contents.unshift(this.matches[2]);return'"<!--'+this.contents.join("\\n")+'-->"'}},{name:"rawjs",regexp:/^(\s*)-\s*(.*)\s*$/i,process:function(){this.contents.unshift(this.matches[2]);return'"";'+this.contents.join("\n")+"; _$output = _$output "}},{name:"pre",regexp:/^(\s*):pre(\s+(.*)|$)/i,process:function(){this.contents.unshift(this.matches[2]);return'"<pre>"+\n'+JSON.stringify(this.contents.join("\n"))+'+\n"</pre>"'}},{name:"doctype",regexp:/^()!!!(?:\s*(.*))\s*$/,process:function(){var line="";switch((this.matches[2]||"").toLowerCase()){case"":line='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';break;case"strict":case"1.0":line='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';break;case"frameset":line='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';break;case"5":line="<!DOCTYPE html>";break;case"1.1":line='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';break;case"basic":line='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">';break;case"mobile":line='<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">';break;case"xml":line="<?xml version='1.0' encoding='utf-8' ?>";break;case"xml iso-8859-1":line="<?xml version='1.0' encoding='iso-8859-1' ?>";break}return JSON.stringify(line+"\n")}},{name:"markdown",regexp:/^(\s*):markdown\s*$/i,process:function(){return parse_interpol(exports.Markdown.encode(this.contents.join("\n")))}},{name:"script",regexp:/^(\s*):(?:java)?script\s*$/,process:function(){return parse_interpol('\n<script>\n//<![CDATA[\n'+this.contents.join("\n")+"\n//]]>\n<\/script>\n")}},{name:"css",regexp:/^(\s*):css\s*$/,process:function(){return JSON.stringify('<style type="text/css">\n'+this.contents.join("\n")+"\n</style>")}}];function compile(lines){var block=false,output=[];if(typeof lines==="string"){lines=lines.trim().replace(/\n\r|\r/g,"\n").split("\n")}lines.forEach(function(line){var match,found=false;if(block){match=block.check_indent.exec(line);if(match){block.contents.push(match[1]||"");return}else{output.push(block.process());block=false}}matchers.forEach(function(matcher){if(!found){match=matcher.regexp.exec(line);if(match){block={contents:[],indent_level:(match[1]),matches:match,check_indent:new RegExp("^(?:\\s*|"+match[1]+"  (.*))$"),process:matcher.process,render_contents:function(){return compile(this.contents)}};found=true}}});if(!found){output.push(function(){if(line[0]==="\\"){return parse_interpol(line.substr(1,line.length))}function escapedLine(){try{return escaperName+"("+JSON.stringify(JSON.parse(line))+")"}catch(e2){return escaperName+"("+line+")"}}function unescapedLine(){try{return parse_interpol(JSON.parse(line))}catch(e){return line}}if((line.substr(0,2)==="&=")){line=line.substr(2,line.length).trim();return escapedLine()}if((line.substr(0,2)==="!=")){line=line.substr(2,line.length).trim();return unescapedLine()}if((line[0]==="=")){line=line.substr(1,line.length).trim();if(escapeHtmlByDefault){return escapedLine()}else{return unescapedLine()}}return parse_interpol(line)}())}});if(block){output.push(block.process())}var txt=output.filter(function(part){return part&&part.length>0}).join(" +\n");if(txt.length==0){txt='""'}return txt}function optimize(js){var new_js=[],buffer=[],part,end;function flush(){if(buffer.length>0){new_js.push(JSON.stringify(buffer.join(""))+end);buffer=[]}}js.replace(/\n\r|\r/g,"\n").split("\n").forEach(function(line){part=line.match(/^(\".*\")(\s*\+\s*)?$/);if(!part){flush();new_js.push(line);return}end=part[2]||"";part=part[1];try{buffer.push(JSON.parse(part))}catch(e){flush();new_js.push(line)}});flush();return new_js.join("\n")}function render(text,options){options=options||{};text=text||"";var js=compile(text,options);if(options.optimize){js=Haml.optimize(js)}return execute(js,options.context||Haml,options.locals)}function execute(js,self,locals){return(function(){with(locals||{}){try{var _$output;eval("_$output ="+js);return _$output}catch(e){return"\n<pre class='error'>"+html_escape(e.stack)+"</pre>\n"}}}).call(self)}Haml=function Haml(haml,config){if(typeof(config)!="object"){forceXML=config;config={}}var escaper;if(config.customEscape){escaper="";escaperName=config.customEscape}else{escaper=html_escape.toString()+"\n";escaperName="html_escape"}escapeHtmlByDefault=(config.escapeHtmlByDefault||config.escapeHTML||config.escape_html);var js=optimize(compile(haml));var str="with(locals || {}) {\n  try {\n   var _$output="+js+";\n return _$output;  } catch (e) {\n    return \"\\n<pre class='error'>\" + "+escaperName+'(e.stack) + "</pre>\\n";\n  }\n}';try{var f=new Function("locals",escaper+str);return f}catch(e){console.error(str);throw e}};Haml.compile=compile;Haml.optimize=optimize;Haml.render=render;Haml.execute=execute;Haml.html_escape=html_escape}());if(typeof module!=="undefined"){module.exports=Haml};

//blueimp 1.0.2
(function(e){var a=function(b,d){var c=!/[^\-\w]/.test(b)?a.cache[b]=a.cache[b]||a(a.load(b)):new Function(a.arg,("var _s=''"+a.helper+";_s+='"+b.replace(a.regexp,a.func)+"';return _s;").split("_s+='';").join(""));c.tmpl=c.tmpl||a;return d?c(d):c};a.cache={};a.load=function(a){return document.getElementById(a).innerHTML};a.regexp=/(\s+)|('|\\)(?![^%]*%\})|(?:\{%(=|#)(.+?)%\})|(\{%)|(%\})/g;a.func=function(a,d,c,f,g,e,i,h,j){if(d)return h&&h+a.length!==j.length?" ":"";if(c)return"\\"+a;if(f)return"="===
f?"'+_e("+g+")+'":"'+("+g+"||'')+'";if(e)return"';";if(i)return"_s+='"};a.encReg=/[<>&"\x00]/g;a.encMap={"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","\x00":""};a.encode=function(b){return(""+(b||"")).replace(a.encReg,function(b){return a.encMap[b]})};a.arg="o";a.helper=",_t=arguments.callee.tmpl,_e=_t.encode,print=function(s,e){_s+=e&&(s||'')||_e(s);},include=function(s,d){_s+=_t(s,d);}";"function"===typeof define&&define.amd?define("tmpl",function(){return a}):e.tmpl=a})(this);

// vash v0.4.4-931, 05-01-2012
(function(a){typeof define=="function"&&define.amd?define(a):typeof module=="object"&&module.exports?module.exports=a:window.vash=a})(function(a){function R(a,b){this.ast=a,this.originalMarkup=b||""}function M(a,b){this.options=b||{},this.tokens=a,this.ast=L(N),this.prevTokens=[]}function K(a){this.input=this.originalInput=a.replace(/\r\n|\r/g,"\n"),this.lineno=1,this.charno=0}var b=a;a.version="0.4.4-931",a.config={useWith:!1,modelName:"model",htmlEscape:!0,debug:!1,debugParser:!1,debugCompiler:!1};var c="AT",d="ASSIGN_OPERATOR",e="AT_COLON",f="AT_STAR_CLOSE",g="AT_STAR_OPEN",h="BACKSLASH",i="BRACE_CLOSE",j="BRACE_OPEN",k="CONTENT",l="DOUBLE_QUOTE",m="EMAIL",n="FAT_ARROW",o="FUNCTION",p="HARD_PAREN_CLOSE",q="HARD_PAREN_OPEN",r="HTML_RAW",s="HTML_TAG_CLOSE",t="HTML_TAG_OPEN",u="HTML_TAG_SELFCLOSE",v="IDENTIFIER",w="KEYWORD",x="LOGICAL",y="NEWLINE",z="NUMERIC_CONTENT",A="OPERATOR",B="PAREN_CLOSE",C="PAREN_OPEN",D="PERIOD",E="SINGLE_QUOTE",F="TEXT_TAG_CLOSE",G="TEXT_TAG_OPEN",H="WHITESPACE",I={};I[g]=f,I[j]=i,I[l]=l,I[q]=p,I[C]=B,I[E]=E;var J=[m,/^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})\b/,g,/^(@\*)/,f,/^(\*@)/,e,/^@\:/,c,/^(@)/,n,/^(\(.*?\)?\s*?=>)/,C,/^(\()/,B,/^(\))/,q,/^(\[)/,p,/^(\])/,j,/^(\{)/,i,/^(\})/,G,/^(<text>)/,F,/^(<\/text>)/,u,function(){return this.scan(/^(<[^@>]+?\/>)/,u)},t,function(){return this.spewIf(this.scan(/^(<[^\/ >]+?[^>]*?>)/,t),"@")},s,function(){return this.scan(/^(<\/[^>@\b]+?>)/,s)},D,/^(\.)/,y,function(){var a=this.scan(/^(\n)/,y);a&&(this.lineno++,this.charno=0);return a},H,/^(\s)/,o,/^(function)(?![\d\w])/,w,/^(case|catch|do|else|finally|for|function|goto|if|instanceof|return|switch|try|typeof|var|while|with)(?![\d\w])/,r,/^(vash\.raw)(?![\d\w])/,v,/^([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)/,A,/^(===|!==|==|!==|>>>|<<|>>|>=|<=|>|<|\+|-|\/|\*|\^|%|\:|\?)/,d,/^(\|=|\^=|&=|>>>=|>>=|<<=|-=|\+=|%=|\/=|\*=|=)/,x,/^(&&|\|\||&|\||\^)/,h,/^(\\)/,l,/^(\")/,E,/^(\')/,z,/^([0-9]+)/,k,/^([^\s})@.]+?)/];K.prototype={tok:function(a,b){return{type:a,line:this.lineno,chr:this.charno,val:b,toString:function(){return"["+this.type+" ("+this.line+","+this.chr+"): "+this.val+"]"}}},scan:function(a,b){var c,d;if(c=a.exec(this.input)){this.input=this.input.substr(c[0].length),d=this.tok(b,c[1]),this.charno+=c[0].length;return d}},spewIf:function(a,b){var c,d;a&&(c=a.val.split(b),c.length>1&&(a.val=c.shift(),d=b+c.join(b),this.input=d+this.input,this.charno-=d.length));return a},advance:function(){var a,b,c,d;for(a=0;a<J.length;a+=2){c=J[a+1],c.displayName=J[a],typeof c=="function"&&(d=c.call(this)),typeof c.exec=="function"&&(d=this.scan(c,J[a]));if(d)return d}}};var L=function(a){return new L.fn.init(a)};L.prototype.init=function(a){typeof a=="string"&&(this.mode=a),this.maxCheck()},L.fn=L.prototype.init.prototype=L.prototype,L.fn.vquery="yep",L.fn.constructor=L,L.fn.length=0,L.fn.parent=null,L.fn.mode=null,L.fn.tagName=null,L.fn.beget=function(a,b){var c=L(a);c.parent=this,this.push(c),b&&(c.tagName=b),this.maxCheck();return c},L.fn.closest=function(a,b){var c=this;while(c)if(c.tagName!==b&&c.parent)c=c.parent;else break;return c},L.fn.pushFlatten=function(a){var b=a,c,d;while(b.length===1&&b[0].vquery)b=b[0];if(b.mode!==N)this.push(b);else for(c=0;c<b.length;c++)this.push(b[c]);this.maxCheck();return this},L.fn.push=function(a){L.isArray(a)?(a.vquery&&a.forEach(function(a){a.parent=this},this),Array.prototype.push.apply(this,a)):(a.vquery&&(a.parent=this),Array.prototype.push.call(this,a)),this.maxCheck();return this.length},L.fn.root=function(){var a=this;while(a&&a.parent&&(a=a.parent));return a},L.fn.toTreeString=function(){function c(d){var e,f;a.push(Array(b).join(" |")+" +"+d.mode+" "+(d.tagName||"")),b+=1,e=d.slice();while(f=e.shift())f.vquery===L.fn.vquery?c(f):a.push(Array(b).join(" |")+" "+(f?f.toString():"[empty]"));b-=1}var a=[],b=1;c(this);return a.join("\n")},L.fn.maxCheck=function(){if(this.length>=L.maxSize){var a=new Error;a.message="Maximum number of elements exceeded",a.name="vQueryDepthException";throw a}},L.maxSize=1e3,L.isArray=function(a){return Object.prototype.toString.call(a)=="[object Array]"},L.copyObj=function(a){var b={};for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b},L.takeMethodsFromArray=function(){var a=["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","indexOf","lastIndexOf","filter","forEach","every","map","some","reduce","reduceRight"],b=[],c;for(var d=0;d<a.length;d++){c=a[d];if(typeof b[c]=="function")L.fn[c]||function(a){var c=Array.prototype.slice;L.fn[a]=function(){return b[a].apply(this,c.call(arguments,0))}}(c);else throw new Error("Vash requires ES5 array iteration methods, missing: "+c)}},L.takeMethodsFromArray();var N="PROGRAM",O="MARKUP",P="BLOCK",Q="EXPRESSION";M.prototype={parse:function(){var a,b,c,d;while(this.prevTokens.push(a),a=this.tokens.pop()){this.options.debugParser&&console.log(this.ast&&this.ast.mode,a.type,a,a.val);if(this.ast.mode===N||this.ast.mode===null)this.ast=this.ast.beget(this.options.initialMode||O),this.options.initialMode===Q&&(this.ast=this.ast.beget(Q));if(this.ast.mode===O){this.handleMKP(a);continue}if(this.ast.mode===P){this.handleBLK(a);continue}if(this.ast.mode===Q){this.handleEXP(a);continue}}this.ast=this.ast.root(),this.options.debugParser&&!this.options.initialMode&&(console.log(this.ast),console.log(this.ast.toTreeString()));return this.ast},exceptionFactory:function(a,b,c){b=="UNMATCHED"&&(a.name="UnmatchedCharacterError",this.ast=this.ast.root(),c&&(a.message="Unmatched "+c.type+" at line "+c.line+", character "+c.chr+". Value: "+c.val+"\n "+this.ast.toTreeString(),a.lineNumber=c.line));return a},advanceUntilNot:function(a){var b,c,d=[];while(c=this.tokens[this.tokens.length-1])if(c.type===a)b=this.tokens.pop(),d.push(b);else break;return d},advanceUntilMatched:function(a,b,c,d,e){var f=a,g=null,h=0,i=0,j=[];while(f){f.type===b?g&&g.type!==escape&&b!==c||!g?h++:b===c&&i++:f.type===c&&(i++,g&&g.type===e&&i--),j.push(f);if(h===i)break;g=f,f=this.tokens.pop();if(!f)throw this.exceptionFactory(new Error,"UNMATCHED",a)}return j.reverse()},subParse:function(a,b){var d,e,f,g=L.copyObj(this.options);g.initialMode=b,d=this.advanceUntilMatched(a,a.type,I[a.type],null,c),d.pop(),e=d.shift(),this.ast.push(a),f=new M(d,g),f.parse(),this.ast.pushFlatten(f.ast),this.ast.push(e)},handleMKP:function(a){var b=this.tokens[this.tokens.length-1],d=this.tokens[this.tokens.length-2],e=null,h;switch(a.type){case g:this.advanceUntilMatched(a,g,f,c,c);break;case c:if(b)switch(b.type){case C:case v:case r:this.ast.length===0&&(this.ast=this.ast.parent,this.ast.pop()),this.ast=this.ast.beget(Q);break;case w:case o:case j:this.ast.length===0&&(this.ast=this.ast.parent,this.ast.pop()),this.ast=this.ast.beget(P);break;default:this.ast.push(this.tokens.pop())}break;case j:this.ast=this.ast.beget(P),this.tokens.push(a);break;case i:this.ast=this.ast.parent,this.tokens.push(a);break;case G:case t:e=a.val.match(/^<([^\/ >]+)/i),e===null&&b&&b.type===c&&d&&(e=d.val.match(/(.*)/)),this.ast.tagName?this.ast=this.ast.beget(O,e[1]):this.ast.tagName=e[1],t===a.type&&this.ast.push(a);break;case F:case s:e=a.val.match(/^<\/([^>]+)/i),e===null&&b&&b.type===c&&d&&(e=d.val.match(/(.*)/)),h=this.ast.closest(O,e[1]),h!==null&&h.tagName===e[1]&&(this.ast=h),s===a.type&&this.ast.push(a),this.ast.parent&&this.ast.parent.mode===P&&(b.type===H||b.type===y)&&(this.ast=this.ast.parent);break;case u:this.ast.push(a),this.ast.parent&&this.ast.parent.mode===P&&(b.type===H||b.type===y)&&(this.ast=this.ast.parent);break;default:this.ast.push(a)}},handleBLK:function(a){var b=this.tokens[this.tokens.length-1],d,f,g,h,i,k;switch(a.type){case c:b.type!==c&&(this.tokens.push(a),this.ast=this.ast.beget(O));break;case e:this.ast=this.ast.beget(O);break;case G:case F:case u:case t:case s:this.ast=this.ast.beget(O),this.tokens.push(a);break;case n:this.ast=this.ast.beget(P);break;case j:case C:this.subParse(a,P),g=this.advanceUntilNot(H),b=this.tokens[this.tokens.length-1],b&&b.type!==w&&b.type!==o&&b.type!==j&&a.type!==C?(this.tokens.push.apply(this.tokens,g.reverse()),this.ast=this.ast.parent):this.ast.push(g);break;case H:this.ast.push(a),this.advanceUntilNot(H);break;default:this.ast.push(a)}},handleEXP:function(a){var b=null,e,f,g,i,k,m,p;switch(a.type){case w:case o:this.ast=this.ast.beget(P),this.tokens.push(a);break;case H:case x:case d:case A:case z:this.ast.parent&&this.ast.parent.mode===Q?this.ast.push(a):(this.ast=this.ast.parent,this.tokens.push(a));break;case v:case r:this.ast.push(a);break;case E:case l:this.ast.parent&&this.ast.parent.mode===Q?(k=this.advanceUntilMatched(a,a.type,I[a.type],h,h),this.ast.pushFlatten(k.reverse())):(this.ast=this.ast.parent,this.tokens.push(a));break;case q:case C:m=this.prevTokens[this.prevTokens.length-1],this.subParse(a,Q),b=this.tokens[this.tokens.length-1];if(m&&m.type===c||b&&b.type===v)this.ast=this.ast.parent;break;case j:this.tokens.push(a),this.ast=this.ast.beget(P);break;case n:this.tokens.push(a),this.ast=this.ast.beget(P);break;case D:b=this.tokens[this.tokens.length-1],!b||b.type!==v&&b.type!==w&&b.type!==o&&b.type!==D?(this.ast=this.ast.parent,this.tokens.push(a)):this.ast.push(a);break;default:this.ast.parent&&this.ast.parent.mode!==Q?(this.ast=this.ast.parent,this.tokens.push(a)):this.ast.push(a)}}};var S=R.prototype;S.assemble=function(a){function n(a){return a.vquery&&a.mode===Q?a.filter(n).length>0:a.vquery&&a.mode!==Q?!0:!1}function m(a){var b,c=a.slice(0),d,e,f;a.mode===Q&&a.parent&&a.parent.mode!==Q&&(d=a.filter(n).length);for(e=0;e<c.length;e++)f=c[e],f.vquery?m(f):a.mode===O?j(f,a,e):a.mode===P?k(f,a,e):a.mode===Q&&l(f,a,e,d>0?!1:!0)}function l(f,g,h,j){var k="",l="",m=g.parent&&g.parent.mode!==Q;a.htmlEscape!==!1&&(f.type===r&&c.push(!0),m&&h===0&&j&&c.length===0&&(k+="( typeof (__vt = "),m&&h===g.length-1&&j&&(c.length>0?c.pop():l+=") !== 'undefined' ? __vt : '' ).toString()\n.replace(/&(?!\\w+;)/g, '&amp;')\n.replace(/</g, '&lt;')\n.replace(/>/g, '&gt;')\n.replace(/\"/g, '&quot;') \n")),m&&(h===0||h===1&&g[0].type===r)&&(i(f),k="__vo.push("+k),m&&(h===g.length-1||h===g.length-2&&g[g.length-1].type===r)&&(l+="); \n"),f.type!==r&&b.push(k+f.val.replace(d,'"').replace(e,'"')+l),m&&h===g.length-1&&i(f)}function k(a,c,e){b.push(a.val.replace(d,'"'))}function j(a,c,e){i(a),b.push("__vo.push('"+a.val.replace(d,'"').replace(f,"\\n")+"'); \n")}function i(c){a.debug&&(b.push("__vl = "+c.line+", "),b.push("__vc = "+c.chr+"; \n"))}a=a||{};var b=[],c=[],d=/["']/gi,e=/(\\?)(["'])/gi,f=/[\n\r]/gi,g,h;b.push("var __vo = [], __vt; \n"),a.debug&&b.push("var __vl = 0, __vc = 0; \n"),m(this.ast),a.useWith===!0&&(b.unshift("with("+a.modelName+" || {}){ \n"),b.push("}")),a.debug&&(b.unshift("try { \n"),b.push("} catch(e){ (",S.reportError.toString(),")(e, __vl, __vc, ",'"'+this.originalMarkup.replace(f,"!LB!").replace(e,"\\$2")+'"',") } \n")),b.push("return __vo.join('');"),g=b.join(""),a.debugCompiler&&console.log(g);try{h=new Function(a.modelName,g)}catch(o){o.message+=" -> "+g;throw o}return h},S.reportError=function(a,b,c,d){var e=d.split("!LB!"),f=3,g=Math.max(0,b-f),h=Math.min(e.length,b+f),i=e.slice(g,h).map(function(a,c,d){var e=c+g+1;return(e===b?"  > ":"    ")+e+" | "+a}).join("\n");a.message="Problem while rendering template at line "+b+", character "+c+".\nOriginal message: "+a.message+"."+"\nContext: \n\n"+i+"\n\n";throw a},a.VLexer=K,a.VParser=M,a.VCompiler=R,a.compile=function(b,c){if(b===""||typeof b!="string")throw new Error("Empty or non-string cannot be compiled");var d,e,f=[],g,h,i,j;c=c||{};for(j in a.config)a.config.hasOwnProperty(j)&&typeof c[j]=="undefined"&&(c[j]=a.config[j]);d=new K(b);while(e=d.advance())f.push(e);f.reverse(),g=new M(f,c),g.parse(),h=new R(g.ast,b),i=h.assemble(c),i.displayName="render";return i};return a}({}));

/********************************
  PRE-COMPILED TEMPLATES
 ********************************/
// Underscore
window.tpl.underscore = _.template("<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6><ul class='list'><% for (var i = 0, l = list.length; i < l; i++) { %><li class='item'><%= list[i] %></li><% } %></ul></div>");

// Underscore - no with
window.tpl.underscoreNoWith = _.template("<div><h1 class='header'><%= data.header %></h1><h2 class='header2'><%= data.header2 %></h2><h3 class='header3'><%= data.header3 %></h3><h4 class='header4'><%= data.header4 %></h4><h5 class='header5'><%= data.header5 %></h5><h6 class='header6'><%= data.header6 %></h6><ul class='list'><% for (var i = 0, l = data.list.length; i < l; i++) { %><li class='item'><%= data.list[i] %></li><% } %></ul></div>", null, {variable: 'data'});

// Mustache
window.tpl.mustache = Mustache.compile("<div><h1 class='header'>{{{header}}}</h1><h2 class='header2'>{{{header2}}}</h2><h3 class='header3'>{{{header3}}}</h3><h4 class='header4'>{{{header4}}}</h4><h5 class='header5'>{{{header5}}}</h5><h6 class='header6'>{{{header6}}}</h6><ul class='list'>{{#list}}<li class='item'>{{{.}}}</li>{{/list}}</ul></div>");

// Handlebars
window.tpl.handlebars = Handlebars.compile("<div><h1 class='header'>{{header}}</h1><h2 class='header2'>{{header2}}</h2><h3 class='header3'>{{header3}}</h3><h4 class='header4'>{{header4}}</h4><h5 class='header5'>{{header5}}</h5><h6 class='header6'>{{header6}}</h6><ul class='list'>{{#each list}}<li class='item'>{{this}}</li>{{/each}}</ul></div>");

// Kendo
window.tpl.kendo = kendo.template("<div><h1 class='header'><#= data.header #></h1><h2 class='header2'><#= data.header2 #></h2><h3 class='header3'><#= data.header3 #></h3><h4 class='header4'><#= data.header4 #></h4><h5 class='header5'><#= data.header5 #></h5><h6 class='header6'><#= data.header6 #></h6><ul class='list'><# for (var i = 0, l = data.list.length; i < l; i++) { #><li class='item'><#= data.list[i] #></li><# } #></ul></div>", {useWithBlock:true});
  
window.tpl.kendo2 = kendo.template("<div><h1 class='header'><#= data.header #></h1><h2 class='header2'><#= data.header2 #></h2><h3 class='header3'><#= data.header3 #></h3><h4 class='header4'><#= data.header4 #></h4><h5 class='header5'><#= data.header5 #></h5><h6 class='header6'><#= data.header6 #></h6><ul class='list'><# for (var i = 0, l = data.list.length; i < l; i++) { #><li class='item'><#= data.list[i] #></li><# } #></ul></div>", {useWithBlock:false});

//John Resig's approach
window.tpl.resig = rtmpl("<div><h1 class='header'><#= header #></h1><h2 class='header2'><#= header2 #></h2><h3 class='header3'><#= header3 #></h3><h4 class='header4'><#= header4 #></h4><h5 class='header5'><#= header5 #></h5><h6 class='header6'><#= header6 #></h6><ul class='list'><# for (var i = 0, l = list.length; i < l; i++) { #><li class='item'><#= list[i] #></li><# } #></ul></div>");

window.tpl.resig2 = rtmpl2("<div><h1 class='header'><#= data.header #></h1><h2 class='header2'><#= data.header2 #></h2><h3 class='header3'><#= data.header3 #></h3><h4 class='header4'><#= data.header4 #></h4><h5 class='header5'><#= data.header5 #></h5><h6 class='header6'><#= data.header6 #></h6><ul class='list'><# for (var i = 0, l = data.list.length; i < l; i++) { #><li class='item'><#= data.list[i] #></li><# } #></ul></div>");

//jqote2
window.tpl.jqote = $.jqotec("<div><h1 class='header'><%= this.header %></h1><h2 class='header2'><%= this.header2 %></h2><h3 class='header3'><%= this.header3 %></h3><h4 class='header4'><%= this.header4 %></h4><h5 class='header5'><%= this.header5 %></h5><h6 class='header6'><%= this.header6 %></h6><ul class='list'><% for (var n = 0, l = this.list.length; n < l; n++) { %><li class='item'><%= this.list[n] %></li><% } %></ul></div>");

//Dot
window.tpl.dot = doT.template("<div><h1 class='header'>{{= it.header }}</h1><h2 class='header2'>{{= it.header2 }}</h2><h3 class='header3'>{{= it.header3 }}</h3><h4 class='header4'>{{= it.header4 }}</h4><h5 class='header5'>{{= it.header5 }}</h5><h6 class='header6'>{{= it.header6 }}</h6><ul class='list'>{{ for (var i = 0, l = it.list.length; i < l; i++) { }}<li class='item'>{{= it.list[i] }}</li>{{ } }}</ul></div>");

//doU
window.tpl.doU = doU.template("<div><h1 class='header'>{{= it.header }}</h1><h2 class='header2'>{{= it.header2 }}</h2><h3 class='header3'>{{= it.header3 }}</h3><h4 class='header4'>{{= it.header4 }}</h4><h5 class='header5'>{{= it.header5 }}</h5><h6 class='header6'>{{= it.header6 }}</h6><ul class='list'>{{ for (var i = 0, l = it.list.length; i < l; i++) { }}<li class='item'>{{= it.list[i] }}</li>{{ } }}</ul></div>");


//hogan
window.tpl.hogan = Hogan.compile("<div><h1 class='header'>{{header}}</h1><h2 class='header2'>{{header2}}</h2><h3 class='header3'>{{header3}}</h3><h4 class='header4'>{{header4}}</h4><h5 class='header5'>{{header5}}</h5><h6 class='header6'>{{header6}}</h6><ul class='list'>{{#list}}<li class='item'>{{.}}</li>{{/list}}</ul></div>");

//haml
try {
window.tpl.haml = Haml("%div\n  %h1.header= header\n  %h2.header2= header2\n  %h3.header3= header3\n  %h4.header4= header4\n  %h5.header5= header5\n  %h6.header6= header6\n");
} catch(ex) {
$(".user-output").append("WARNING: HAML could not be compiled on this browser!<br/>");
}

//pure
window.tpl.pure = $p('div.pure').compile({
  h1: 'header',
  h2: 'header2',
  h3: 'header3',
  h4: 'header4',
  h5: 'header5',
  h6: 'header6'
});

//dust
(function(){dust.register("dusttmp",body_0);function body_0(chk,ctx){return chk.write("<h1 class='header'>").reference(ctx.get("header"),ctx,"h").write("</h1><h2 class='header2'>").reference(ctx.get("header2"),ctx,"h").write("</h2><h3 class='header3'>").reference(ctx.get("header3"),ctx,"h").write("</h3><h4 class='header4'>").reference(ctx.get("header4"),ctx,"h").write("</h4><h5 class='header5'>").reference(ctx.get("header5"),ctx,"h").write("</h5><h6 class='header6'>").reference(ctx.get("header6"),ctx,"h").write("</h6>");}return body_0;})();

//blueimp
window.tpl.blueimp = tmpl("<div><h1 class='header'>{%=o.header%}</h1><h2 class='header2'>{%=o.header2%}</h2><h3 class='header3'>{%=o.header3%}</h3><h4 class='header4'>{%=o.header4%}</h4><h5 class='header5'>{%=o.header5%}</h5><h6 class='header6'>{%=o.header6%}</h6></div>");

//eco
window.tpl.eco = eco("<div><h1 class='header'><%- @header %></h1><h2 class='header2'><%- @header2 %></h2><h3 class='header3'><%- @header3 %></h3><h4 class='header4'><%- @header4 %></h4><h5 class='header5'><%- @header5 %></h5><h6 class='header6'><%- @header6 %></h6></div>");

//Ejs
window.tpl.ejs = new EJS({text: "<div><h1 class='header'><%= header %></h1><h2 class='header2'><%= header2 %></h2><h3 class='header3'><%= header3 %></h3><h4 class='header4'><%= header4 %></h4><h5 class='header5'><%= header5 %></h5><h6 class='header6'><%= header6 %></h6></div>"});

//Jade JavaScript output of jade template compiled using node
window.tpl.jadeCmpld=function anonymous(locals,attrs,escape,rethrow){var attrs=jade.attrs,escape=jade.escape,rethrow=jade.rethrow;var buf=[];with(locals||{}){var interp;buf.push("<div><h1");buf.push(attrs({"class":("header")}));buf.push(">");var __val__=header;buf.push(escape(null==__val__?"":__val__));buf.push("</h1><h2");buf.push(attrs({"class":("header2")}));buf.push(">");var __val__=header2;buf.push(escape(null==__val__?"":__val__));buf.push("</h2><h3");buf.push(attrs({"class":("header3")}));buf.push(">");var __val__=header3;buf.push(escape(null==__val__?"":__val__));buf.push("</h3><h4");buf.push(attrs({"class":("header4")}));buf.push(">");var __val__=header4;buf.push(escape(null==__val__?"":__val__));buf.push("</h4><h5");buf.push(attrs({"class":("header5")}));buf.push(">");var __val__=header5;buf.push(escape(null==__val__?"":__val__));buf.push("</h5><h6");buf.push(attrs({"class":("header6")}));buf.push(">");var __val__=header6;buf.push(escape(null==__val__?"":__val__));buf.push("</h6></div><ul>");for(var item in list){buf.push("<li>");var __val__=item;buf.push(escape(null==__val__?"":__val__));buf.push("</li>")}buf.push("</ul>")}return buf.join("")};

//KiTe
window.tpl.kite = kite("<div><h1 class='header'>{{header}}</h1><h2 class='header2'>{{header2}}</h2><h3 class='header3'>{{header3}}</h3><h4 class='header4'>{{header4}}</h4><h5 class='header5'>{{header5}}</h5><h6 class='header6'>{{header6}}</h6><ul class='list'>{{#list}}<li class='item'>{{.}}</li>{{/list}}</ul></div>");

//jsRender
$.templates({ jsr: "<div><h1 class='header'>{{:header}}</h1><h2 class='header'>{{:header2}}</h2><h3 class='header'>{{:header3}}</h3><h4 class='header'>{{:header4}}</h4><h5 class='header'>{{:header5}}</h5><h6 class='header'>{{:header6}}</h6><ul class='list'>{{for list}}<li class='item'>{{:#data}}</li>{{/for}}</ul></div>" });

// Mote
window.tpl.mote = mote.compile("<div><h1 class='header'>{{{header}}}</h1><h2 class='header2'>{{{header2}}}</h2><h3 class='header3'>{{{header3}}}</h3><h4 class='header4'>{{{header4}}}</h4><h5 class='header5'>{{{header5}}}</h5><h6 class='header6'>{{{header6}}}</h6><ul class='list'>{{#list}}<li class='item'>{{{.}}}</li>{{/list}}</ul></div>");

// Template
window.tpl.template = new Template('<div><h1 class="header"><%= header %></h1><h2 class="header2"><%= header2 %></h2><h3 class="header3"><%= header3 %></h3><h4 class="header4"><%= header4 %></h4><h5 class="header5"><%= header5 %></h5><h6 class="header6"><%= header6 %></h6><ul class="list"><% for (var i = 0, l = list.length; i < l; i++) { %><li class="item"><%= list[i] %></li><% } %></ul></div>');

// vash 
window.tpl.vash1 = vash.compile("<div><h1 class='header'>@model.header</h1><h2 class='header2'>@model.header2</h2><h3 class='header3'>@model.header3</h3><h4 class='header4'>@model.header4</h4><h5 class='header5'>@model.header5</h5><h6 class='header6'>@model.header6</h6><ul class='list'>@for (var i = 0, l = model.list.length; i < l; i++) { <li class='item'>@model.list[i]</li> } </ul></div>");

// vash without html escaping
window.tpl.vash2 = vash.compile("<div><h1 class='header'>@model.header</h1><h2 class='header2'>@model.header2</h2><h3 class='header3'>@model.header3</h3><h4 class='header4'>@model.header4</h4><h5 class='header5'>@model.header5</h5><h6 class='header6'>@model.header6</h6><ul class='list'>@for (var i = 0, l = model.list.length; i < l; i++) { <li class='item'>@model.list[i]</li> } </ul></div>", { htmlEscape: false });

window.grips.compile({grips:"{$: '#main' }<div><h1 class='header'>{$= $.header $}</h1><h2 class='header2'>{$= $.header2 $}</h2><h3 class='header3'>{$= $.header3 $}</h3><h4 class='header4'>{$= $.header4 $}</h4><h5 class='header5'>{$= $.header5 $}</h5><h6 class='header6'>{$= $.header6 $}</h6><ul class='list'>{$* $.list }<li class='item'>{$= _.value $}</li>{$}</ul></div>{$}"},true);

// NOTE: this variation of the previous grips template is only present to get around this performance "bug" in FF, otherwise the previous compile() call would have been sufficient.
// http://jsperf.com/functions-created-globally-or-via-new-function

(function(G){function __sort_fn__(a,b){ return a-b; }var partial = G.definePartial, clone = G.cloneObj, unerr = new Error("Unknown error"), RLH = G.RangeLiteralHash;partial(function($,$$){$$ = clone($$) || {};var i, ret = "", ret2, _;ret += "<div><h1 class='header'>";ret += $.header;ret += "</h1><h2 class='header2'>";ret += $.header2;ret += "</h2><h3 class='header3'>";ret += $.header3;ret += "</h3><h4 class='header4'>";ret += $.header4;ret += "</h4><h5 class='header5'>";ret += $.header5;ret += "</h5><h6 class='header6'>";ret += $.header6;ret += "</h6><ul class='list'>";ret2 = (function(){function __iter__($,$$,value,key,index){var i, ret = "", ret2, _;if (value == null) return ret;$$ = clone($$);_ = {value: value,key: key,index: index,even: (index % 2) === 0,odd: (index % 2) === 1,first: (index === 0),last: (index === len - 1)};ret += "<li class='item'>";ret += _.value;ret += "</li>";return ret;}var i, j = 0, len, ret = "", it, tmp;it = $.list;if (it == null) {return "";}if (Array.isArray(it)) {len = it.length;for (i=0; i<len; i++) {ret2 = __iter__($,$$,it[i],""+i,i);ret += ret2;}} else if (typeof it === "object") {tmp = Object.keys(it);len = tmp.length;if (it instanceof RLH) {tmp.sort(__sort_fn__);}for (i=0; i<len; i++) {ret2 = __iter__($,$$,it[tmp[i]],tmp[i],i);ret += ret2;}} else {return unerr;}return ret;})();ret += ret2;ret += "</ul></div>";return ret;},"grips2#main");})(window.grips);

// use the partials directly from the cache (as most others do!)
window.tpl.grips = window.grips.collections["grips"].partials["#main"];
window.tpl.grips2 = window.grips.collections["grips2"].partials["#main"];

</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Mustache 0.5.0 DEV (compiled)
tpl.mustache(tpl.vars);
ready
Kendo UI
tpl.kendo(tpl.vars);
ready
Kendo UI (no "with" block)
tpl.kendo2(tpl.vars);
ready
Handlebars
tpl.handlebars(tpl.vars)
ready
Underscore
tpl.underscore(tpl.vars);
ready
Resig Micro Templates
tpl.resig(tpl.vars)
ready
Resig Micro Templates (No "with" block)
tpl.resig2(tpl.vars)
ready
jqote2 (10/21/2010)
$.jqote(tpl.jqote, tpl.vars);
ready
dot 0.2.0
tpl.dot(tpl.vars);
ready
Hogan 1.0.3
tpl.hogan.render(tpl.vars)
ready
Haml (7/16/11) (DOT2)
//WARNING: Compilation of the template fails in IE7!
tpl.doU(tpl.vars);
ready
Pure
tpl.pure(tpl.vars);
ready
Linked-in Dust
dust.render('dusttmp', tpl.vars, function() {});
ready
Blueimp 1.0.2
window.tpl.blueimp(tpl.vars);
ready
eco
tpl.eco(tpl.vars);
ready
ejs
tpl.ejs.render(tpl.vars);
ready
Jade
tpl.jadeCmpld(tpl.vars);
ready
KiTE
tpl.kite(tpl.vars);
ready
jsRender (jQuery Templates)
$.render.jsr(tpl.vars);
ready
Mote
tpl.mote(tpl.vars);
ready
Template
// Template has an internal cache!
tpl.template.data.compiled.call(tpl.vars, tpl.vars);
//tpl.template.render(tpl.vars);
ready
Underscore - (no "with" block)
tpl.underscoreNoWith(tpl.vars);
ready
Vash
tpl.vash1( tpl.vars ); 
ready
Vash without html escaping
tpl.vash2( tpl.vars );
ready
grips (direct partial, compiled)
// NOTE: this variation of the grips test is currently subject to a performance "bug" in FF.
// http://jsperf.com/functions-created-globally-or-via-new-function

tpl.grips( tpl.vars );
ready
grips (direct partial, pre-compiled)
// NOTE: this variation of the previous grips test is only present to get around this performance "bug" in FF, otherwise the "compiled" test for grips would have been sufficient.
// http://jsperf.com/functions-created-globally-or-via-new-function

tpl.grips2( tpl.vars );
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.