Comparing version 1.3.4 to 2.0.0
{ | ||
"name": "nunjucks", | ||
"version": "1.3.1", | ||
"main": "browser/nunjucks.min.js", | ||
@@ -5,0 +4,0 @@ "ignore": [ |
@@ -1,3 +0,2 @@ | ||
// Browser bundle of nunjucks 1.3.3 (slim, only works with precompiled templates) | ||
(function(){var modules={};(function(){"use strict";function extend(cls,name,props){var F=function(){};F.prototype=cls.prototype;var prototype=new F;var fnTest=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;props=props||{};for(var k in props){var src=props[k];var parent=prototype[k];if(typeof parent==="function"&&typeof src==="function"&&fnTest.test(src)){prototype[k]=function(src,parent){return function(){var tmp=this.parent;this.parent=parent;var res=src.apply(this,arguments);this.parent=tmp;return res}}(src,parent)}else{prototype[k]=src}}prototype.typename=name;var new_cls=function(){if(prototype.init){prototype.init.apply(this,arguments)}};new_cls.prototype=prototype;new_cls.prototype.constructor=new_cls;new_cls.extend=function(name,props){if(typeof name==="object"){props=name;name="anonymous"}return extend(new_cls,name,props)};return new_cls}modules["object"]=extend(Object,"Object",{})})();(function(){"use strict";var ArrayProto=Array.prototype;var ObjProto=Object.prototype;var escapeMap={"&":"&",'"':""","'":"'","<":"<",">":">"};var escapeRegex=/[&"'<>]/g;var lookupEscape=function(ch){return escapeMap[ch]};var exports=modules["lib"]={};exports.withPrettyErrors=function(path,withInternals,func){try{return func()}catch(e){if(!e.Update){e=new exports.TemplateError(e)}e.Update(path);if(!withInternals){var old=e;e=new Error(old.message);e.name=old.name}throw e}};exports.TemplateError=function(message,lineno,colno){var err=this;if(message instanceof Error){err=message;message=message.name+": "+message.message}else{if(Error.captureStackTrace){Error.captureStackTrace(err)}}err.name="Template render error";err.message=message;err.lineno=lineno;err.colno=colno;err.firstUpdate=true;err.Update=function(path){var message="("+(path||"unknown path")+")";if(this.firstUpdate){if(this.lineno&&this.colno){message+=" [Line "+this.lineno+", Column "+this.colno+"]"}else if(this.lineno){message+=" [Line "+this.lineno+"]"}}message+="\n ";if(this.firstUpdate){message+=" "}this.message=message+(this.message||"");this.firstUpdate=false;return this};return err};exports.TemplateError.prototype=Error.prototype;exports.escape=function(val){return val.replace(escapeRegex,lookupEscape)};exports.isFunction=function(obj){return ObjProto.toString.call(obj)==="[object Function]"};exports.isArray=Array.isArray||function(obj){return ObjProto.toString.call(obj)==="[object Array]"};exports.isString=function(obj){return ObjProto.toString.call(obj)==="[object String]"};exports.isObject=function(obj){return ObjProto.toString.call(obj)==="[object Object]"};exports.groupBy=function(obj,val){var result={};var iterator=exports.isFunction(val)?val:function(obj){return obj[val]};for(var i=0;i<obj.length;i++){var value=obj[i];var key=iterator(value,i);(result[key]||(result[key]=[])).push(value)}return result};exports.toArray=function(obj){return Array.prototype.slice.call(obj)};exports.without=function(array){var result=[];if(!array){return result}var index=-1,length=array.length,contains=exports.toArray(arguments).slice(1);while(++index<length){if(exports.indexOf(contains,array[index])===-1){result.push(array[index])}}return result};exports.extend=function(obj,obj2){for(var k in obj2){obj[k]=obj2[k]}return obj};exports.repeat=function(char_,n){var str="";for(var i=0;i<n;i++){str+=char_}return str};exports.each=function(obj,func,context){if(obj==null){return}if(ArrayProto.each&&obj.each===ArrayProto.each){obj.forEach(func,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){func.call(context,obj[i],i,obj)}}};exports.map=function(obj,func){var results=[];if(obj==null){return results}if(ArrayProto.map&&obj.map===ArrayProto.map){return obj.map(func)}for(var i=0;i<obj.length;i++){results[results.length]=func(obj[i],i)}if(obj.length===+obj.length){results.length=obj.length}return results};exports.asyncIter=function(arr,iter,cb){var i=-1;function next(){i++;if(i<arr.length){iter(arr[i],i,next,cb)}else{cb()}}next()};exports.asyncFor=function(obj,iter,cb){var keys=exports.keys(obj);var len=keys.length;var i=-1;function next(){i++;var k=keys[i];if(i<len){iter(k,obj[k],i,len,next)}else{cb()}}next()};exports.indexOf=Array.prototype.indexOf?function(arr,searchElement,fromIndex){return Array.prototype.indexOf.call(arr,searchElement,fromIndex)}:function(arr,searchElement,fromIndex){var length=this.length>>>0;fromIndex=+fromIndex||0;if(Math.abs(fromIndex)===Infinity){fromIndex=0}if(fromIndex<0){fromIndex+=length;if(fromIndex<0){fromIndex=0}}for(;fromIndex<length;fromIndex++){if(arr[fromIndex]===searchElement){return fromIndex}}return-1};if(!Array.prototype.map){Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}}exports.keys=function(obj){if(Object.prototype.keys){return obj.keys()}else{var keys=[];for(var k in obj){if(obj.hasOwnProperty(k)){keys.push(k)}}return keys}}})();(function(){"use strict";var lib=modules["lib"];var Obj=modules["object"];var Frame=Obj.extend({init:function(parent){this.variables={};this.parent=parent},set:function(name,val,resolveUp){var parts=name.split(".");var obj=this.variables;var frame=this;if(resolveUp){if(frame=this.resolve(parts[0])){frame.set(name,val);return}frame=this}for(var i=0;i<parts.length-1;i++){var id=parts[i];if(!obj[id]){obj[id]={}}obj=obj[id]}obj[parts[parts.length-1]]=val},get:function(name){var val=this.variables[name];if(val!==undefined&&val!==null){return val}return null},lookup:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return val}return p&&p.lookup(name)},resolve:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return this}return p&&p.resolve(name)},push:function(){return new Frame(this)},pop:function(){return this.parent}});function makeMacro(argNames,kwargNames,func){return function(){var argCount=numArgs(arguments);var args;var kwargs=getKeywordArgs(arguments);if(argCount>argNames.length){args=Array.prototype.slice.call(arguments,0,argNames.length);var vals=Array.prototype.slice.call(arguments,args.length,argCount);for(var i=0;i<vals.length;i++){if(i<kwargNames.length){kwargs[kwargNames[i]]=vals[i]}}args.push(kwargs)}else if(argCount<argNames.length){args=Array.prototype.slice.call(arguments,0,argCount);for(var i=argCount;i<argNames.length;i++){var arg=argNames[i];args.push(kwargs[arg]);delete kwargs[arg]}args.push(kwargs)}else{args=arguments}return func.apply(this,args)}}function makeKeywordArgs(obj){obj.__keywords=true;return obj}function getKeywordArgs(args){var len=args.length;if(len){var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return lastArg}}return{}}function numArgs(args){var len=args.length;if(len===0){return 0}var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return len-1}else{return len}}function SafeString(val){if(typeof val!=="string"){return val}this.val=val}SafeString.prototype=Object.create(String.prototype);SafeString.prototype.valueOf=function(){return this.val};SafeString.prototype.toString=function(){return this.val};function copySafeness(dest,target){if(dest instanceof SafeString){return new SafeString(target)}return target.toString()}function markSafe(val){var type=typeof val;if(type==="string"){return new SafeString(val)}else if(type!=="function"){return val}else{return function(){var ret=val.apply(this,arguments);if(typeof ret==="string"){return new SafeString(ret)}return ret}}}function suppressValue(val,autoescape){val=val!==undefined&&val!==null?val:"";if(autoescape&&typeof val==="string"){val=lib.escape(val)}return val}function memberLookup(obj,val){obj=obj||{};if(typeof obj[val]==="function"){return function(){return obj[val].apply(obj,arguments)}}return obj[val]}function callWrap(obj,name,args){if(!obj){throw new Error("Unable to call `"+name+"`, which is undefined or falsey")}else if(typeof obj!=="function"){throw new Error("Unable to call `"+name+"`, which is not a function")}return obj.apply(this,args)}function contextOrFrameLookup(context,frame,name){var val=frame.lookup(name);return val!==undefined&&val!==null?val:context.lookup(name)}function handleError(error,lineno,colno){if(error.lineno){return error}else{return new lib.TemplateError(error,lineno,colno)}}function asyncEach(arr,dimen,iter,cb){if(lib.isArray(arr)){var len=arr.length;lib.asyncIter(arr,function(item,i,next){switch(dimen){case 1:iter(item,i,len,next);break;case 2:iter(item[0],item[1],i,len,next);break;case 3:iter(item[0],item[1],item[2],i,len,next);break;default:item.push(i,next);iter.apply(this,item)}},cb)}else{lib.asyncFor(arr,function(key,val,i,len,next){iter(key,val,i,len,next)},cb)}}function asyncAll(arr,dimen,func,cb){var finished=0;var len;var outputArr;function done(i,output){finished++;outputArr[i]=output;if(finished===len){cb(null,outputArr.join(""))}}if(lib.isArray(arr)){len=arr.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<arr.length;i++){var item=arr[i];switch(dimen){case 1:func(item,i,len,done);break;case 2:func(item[0],item[1],i,len,done);break;case 3:func(item[0],item[1],item[2],i,len,done);break;default:item.push(i,done);func.apply(this,item)}}}}else{var keys=lib.keys(arr);len=keys.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<keys.length;i++){var k=keys[i];func(k,arr[k],i,len,done)}}}}modules["runtime"]={Frame:Frame,makeMacro:makeMacro,makeKeywordArgs:makeKeywordArgs,numArgs:numArgs,suppressValue:suppressValue,memberLookup:memberLookup,contextOrFrameLookup:contextOrFrameLookup,callWrap:callWrap,handleError:handleError,isArray:lib.isArray,keys:lib.keys,SafeString:SafeString,copySafeness:copySafeness,markSafe:markSafe,asyncEach:asyncEach,asyncAll:asyncAll}})();(function(){"use strict";var path=modules["path"];var Obj=modules["object"];var lib=modules["lib"];var Loader=Obj.extend({on:function(name,func){this.listeners=this.listeners||{};this.listeners[name]=this.listeners[name]||[];this.listeners[name].push(func)},emit:function(name){var args=Array.prototype.slice.call(arguments,1);if(this.listeners&&this.listeners[name]){lib.each(this.listeners[name],function(listener){listener.apply(null,args)})}},resolve:function(from,to){return path.resolve(path.dirname(from),to)},isRelative:function(filename){return filename.indexOf("./")===0||filename.indexOf("../")===0}});modules["loader"]=Loader})();(function(){"use strict";var Loader=modules["loader"];var WebLoader=Loader.extend({init:function(baseURL,neverUpdate){this.precompiled=window.nunjucksPrecompiled||{};this.baseURL=baseURL||"";this.neverUpdate=neverUpdate},getSource:function(name){if(this.precompiled[name]){return{src:{type:"code",obj:this.precompiled[name]},path:name}}else{var src=this.fetch(this.baseURL+"/"+name);if(!src){return null}return{src:src,path:name,noCache:!this.neverUpdate}}},fetch:function(url,callback){var ajax;var loading=true;var src;if(window.XMLHttpRequest){ajax=new XMLHttpRequest}else if(window.ActiveXObject){ajax=new ActiveXObject("Microsoft.XMLHTTP")}ajax.onreadystatechange=function(){if(ajax.readyState===4&&(ajax.status===0||ajax.status===200)&&loading){loading=false;src=ajax.responseText}};url+=(url.indexOf("?")===-1?"?":"&")+"s="+(new Date).getTime();ajax.open("GET",url,false);ajax.send();return src}});modules["web-loaders"]={WebLoader:WebLoader}})();(function(){if(typeof window==="undefined"||window!==this){modules["loaders"]=modules["node-loaders"]}else{modules["loaders"]=modules["web-loaders"]}})();(function(){"use strict";var lib=modules["lib"];var r=modules["runtime"];var filters={abs:function(n){return Math.abs(n)},batch:function(arr,linecount,fill_with){var res=[];var tmp=[];for(var i=0;i<arr.length;i++){if(i%linecount===0&&tmp.length){res.push(tmp);tmp=[]}tmp.push(arr[i])}if(tmp.length){if(fill_with){for(var i=tmp.length;i<linecount;i++){tmp.push(fill_with)}}res.push(tmp)}return res},capitalize:function(str){var ret=str.toLowerCase();return r.copySafeness(str,ret.charAt(0).toUpperCase()+ret.slice(1))},center:function(str,width){width=width||80;if(str.length>=width){return str}var spaces=width-str.length;var pre=lib.repeat(" ",spaces/2-spaces%2);var post=lib.repeat(" ",spaces/2);return r.copySafeness(str,pre+str+post)},"default":function(val,def){return val?val:def},dictsort:function(val,case_sensitive,by){if(!lib.isObject(val)){throw new lib.TemplateError("dictsort filter: val must be an object")}var array=[];for(var k in val){array.push([k,val[k]])}var si;if(by===undefined||by==="key"){si=0}else if(by==="value"){si=1}else{throw new lib.TemplateError("dictsort filter: You can only sort by either key or value")}array.sort(function(t1,t2){var a=t1[si];var b=t2[si];if(!case_sensitive){if(lib.isString(a)){a=a.toUpperCase()}if(lib.isString(b)){b=b.toUpperCase()}}return a>b?1:a===b?0:-1});return array},escape:function(str){if(typeof str==="string"||str instanceof r.SafeString){return lib.escape(str)}return str},safe:function(str){return r.markSafe(str)},first:function(arr){return arr[0]},groupby:function(arr,attr){return lib.groupBy(arr,attr)},indent:function(str,width,indentfirst){width=width||4;var res="";var lines=str.split("\n");var sp=lib.repeat(" ",width);for(var i=0;i<lines.length;i++){if(i===0&&!indentfirst){res+=lines[i]+"\n"}else{res+=sp+lines[i]+"\n"}}return r.copySafeness(str,res)},join:function(arr,del,attr){del=del||"";if(attr){arr=lib.map(arr,function(v){return v[attr]})}return arr.join(del)},last:function(arr){return arr[arr.length-1]},length:function(arr){return arr!==undefined?arr.length:0},list:function(val){if(lib.isString(val)){return val.split("")}else if(lib.isObject(val)){var keys=[];if(Object.keys){keys=Object.keys(val)}else{for(var k in val){keys.push(k)}}return lib.map(keys,function(k){return{key:k,value:val[k]}})}else if(lib.isArray(val)){return val}else{throw new lib.TemplateError("list filter: type not iterable")}},lower:function(str){return str.toLowerCase()},random:function(arr){return arr[Math.floor(Math.random()*arr.length)]},rejectattr:function(arr,attr){return arr.filter(function(item){return!item[attr]})},selectattr:function(arr,attr){return arr.filter(function(item){return!!item[attr]})},replace:function(str,old,new_,maxCount){if(old instanceof RegExp){return str.replace(old,new_)}var res=str;var last=res;var count=1;res=res.replace(old,new_);while(last!==res){if(count>=maxCount){break}last=res;res=res.replace(old,new_);count++}return r.copySafeness(str,res)},reverse:function(val){var arr;if(lib.isString(val)){arr=filters.list(val)}else{arr=lib.map(val,function(v){return v})}arr.reverse();if(lib.isString(val)){return r.copySafeness(val,arr.join(""))}return arr},round:function(val,precision,method){precision=precision||0;var factor=Math.pow(10,precision);var rounder;if(method==="ceil"){rounder=Math.ceil}else if(method==="floor"){rounder=Math.floor}else{rounder=Math.round}return rounder(val*factor)/factor},slice:function(arr,slices,fillWith){var sliceLength=Math.floor(arr.length/slices);var extra=arr.length%slices;var offset=0;var res=[];for(var i=0;i<slices;i++){var start=offset+i*sliceLength;if(i<extra){offset++}var end=offset+(i+1)*sliceLength;var slice=arr.slice(start,end);if(fillWith&&i>=extra){slice.push(fillWith)}res.push(slice)}return res},sort:function(arr,reverse,caseSens,attr){arr=lib.map(arr,function(v){return v});arr.sort(function(a,b){var x,y;if(attr){x=a[attr];y=b[attr]}else{x=a;y=b}if(!caseSens&&lib.isString(x)&&lib.isString(y)){x=x.toLowerCase();y=y.toLowerCase()}if(x<y){return reverse?1:-1}else if(x>y){return reverse?-1:1}else{return 0}});return arr},string:function(obj){return r.copySafeness(obj,obj)},title:function(str){var words=str.split(" ");for(var i=0;i<words.length;i++){words[i]=filters.capitalize(words[i])}return r.copySafeness(str,words.join(" "))},trim:function(str){return r.copySafeness(str,str.replace(/^\s*|\s*$/g,""))},truncate:function(input,length,killwords,end){var orig=input;length=length||255;if(input.length<=length)return input;if(killwords){input=input.substring(0,length)}else{var idx=input.lastIndexOf(" ",length);if(idx===-1){idx=length}input=input.substring(0,idx)}input+=end!==undefined&&end!==null?end:"...";return r.copySafeness(orig,input)},upper:function(str){return str.toUpperCase()},urlencode:function(obj){var enc=encodeURIComponent;if(lib.isString(obj)){return enc(obj)}else{var parts;if(lib.isArray(obj)){parts=obj.map(function(item){return enc(item[0])+"="+enc(item[1])})}else{parts=[];for(var k in obj){if(obj.hasOwnProperty(k)){parts.push(enc(k)+"="+enc(obj[k]))}}}return parts.join("&")}},urlize:function(str,length,nofollow){if(isNaN(length))length=Infinity;var noFollowAttr=nofollow===true?' rel="nofollow"':"";var puncRE=/^(?:\(|<|<)?(.*?)(?:\.|,|\)|\n|>)?$/;var emailRE=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;var httpHttpsRE=/^https?:\/\/.*$/;var wwwRE=/^www\./;var tldRE=/\.(?:org|net|com)(?:\:|\/|$)/;var words=str.split(/\s+/).filter(function(word){return word&&word.length}).map(function(word){var matches=word.match(puncRE);var possibleUrl=matches&&matches[1]||word;if(httpHttpsRE.test(possibleUrl))return'<a href="'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(wwwRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(emailRE.test(possibleUrl))return'<a href="mailto:'+possibleUrl+'">'+possibleUrl+"</a>";if(tldRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";return word});return words.join(" ")},wordcount:function(str){var words=str?str.match(/\w+/g):null;return words?words.length:null},"float":function(val,def){var res=parseFloat(val);return isNaN(res)?def:res},"int":function(val,def){var res=parseInt(val,10);return isNaN(res)?def:res}};filters.d=filters["default"];filters.e=filters.escape;modules["filters"]=filters})();(function(){"use strict";function cycler(items){var index=-1;return{current:null,reset:function(){index=-1;this.current=null},next:function(){index++;if(index>=items.length){index=0}this.current=items[index];return this.current}}}function joiner(sep){sep=sep||",";var first=true;return function(){var val=first?"":sep;first=false;return val}}var globals={range:function(start,stop,step){if(!stop){stop=start;start=0;step=1}else if(!step){step=1}var arr=[];for(var i=start;i<stop;i+=step){arr.push(i)}return arr},cycler:function(){return cycler(Array.prototype.slice.call(arguments))},joiner:function(sep){return joiner(sep)}};modules["globals"]=globals})();(function(){"use strict";var path=modules["path"];var lib=modules["lib"];var Obj=modules["object"];var lexer=modules["lexer"];var compiler=modules["compiler"];var builtin_filters=modules["filters"];var builtin_loaders=modules["loaders"];var runtime=modules["runtime"];var globals=modules["globals"];var Frame=runtime.Frame;var Environment=Obj.extend({init:function(loaders,opts){var opts=this.opts=opts||{};this.opts.dev=!!opts.dev;this.opts.autoescape=!!opts.autoescape;this.opts.trimBlocks=!!opts.trimBlocks;this.opts.lstripBlocks=!!opts.lstripBlocks;if(!loaders){if(builtin_loaders.FileSystemLoader){this.loaders=[new builtin_loaders.FileSystemLoader("views")]}else{this.loaders=[new builtin_loaders.WebLoader("/views")]}}else{this.loaders=lib.isArray(loaders)?loaders:[loaders]}this.initCache();this.filters={};this.asyncFilters=[];this.extensions={};this.extensionsList=[];for(var name in builtin_filters){this.addFilter(name,builtin_filters[name])}},initCache:function(){lib.each(this.loaders,function(loader){loader.cache={};if(typeof loader.on==="function"){loader.on("update",function(template){loader.cache[template]=null})}})},addExtension:function(name,extension){extension._name=name;this.extensions[name]=extension;this.extensionsList.push(extension)},getExtension:function(name){return this.extensions[name]},addGlobal:function(name,value){globals[name]=value},addFilter:function(name,func,async){var wrapped=func;if(async){this.asyncFilters.push(name)}this.filters[name]=wrapped},getFilter:function(name){if(!this.filters[name]){throw new Error("filter not found: "+name)}return this.filters[name]},resolveTemplate:function(loader,parentName,filename){var isRelative=loader.isRelative&&parentName?loader.isRelative(filename):false;return isRelative&&loader.resolve?loader.resolve(parentName,filename):filename},getTemplate:function(name,eagerCompile,parentName,cb){var that=this;var tmpl=null;if(name&&name.raw){name=name.raw}if(lib.isFunction(parentName)){cb=parentName;parentName=null;eagerCompile=eagerCompile||false}if(lib.isFunction(eagerCompile)){cb=eagerCompile;eagerCompile=false}if(typeof name!=="string"){throw new Error("template names must be a string: "+name)}for(var i=0;i<this.loaders.length;i++){var _name=this.resolveTemplate(this.loaders[i],parentName,name);tmpl=this.loaders[i].cache[_name];if(tmpl)break}if(tmpl){if(eagerCompile){tmpl.compile()}if(cb){cb(null,tmpl)}else{return tmpl}}else{var syncResult;lib.asyncIter(this.loaders,function(loader,i,next,done){function handle(src){if(src){src.loader=loader;done(src)}else{next()}}name=that.resolveTemplate(loader,parentName,name);if(loader.async){loader.getSource(name,function(err,src){if(err){throw err}handle(src)})}else{handle(loader.getSource(name))}},function(info){if(!info){var err=new Error("template not found: "+name);if(cb){cb(err)}else{throw err}}else{var tmpl=new Template(info.src,this,info.path,eagerCompile);if(!info.noCache){info.loader.cache[name]=tmpl}if(cb){cb(null,tmpl)}else{syncResult=tmpl}}}.bind(this));return syncResult}},express:function(app){var env=this;function NunjucksView(name,opts){this.name=name;this.path=name;this.defaultEngine=opts.defaultEngine;this.ext=path.extname(name);if(!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");if(!this.ext)this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine}NunjucksView.prototype.render=function(opts,cb){env.render(this.name,opts,cb)};app.set("view",NunjucksView)},render:function(name,ctx,cb){if(lib.isFunction(ctx)){cb=ctx;ctx=null}var syncResult=null;this.getTemplate(name,function(err,tmpl){if(err&&cb){cb(err)}else if(err){throw err}else{tmpl.render(ctx,cb||function(err,res){if(err){throw err}syncResult=res})}});return syncResult},renderString:function(src,ctx,opts,cb){if(lib.isFunction(opts)){cb=opts;opts={}}opts=opts||{};var tmpl=new Template(src,this,opts.path);return tmpl.render(ctx,cb)}});var Context=Obj.extend({init:function(ctx,blocks){this.ctx=ctx;this.blocks={};this.exported=[];for(var name in blocks){this.addBlock(name,blocks[name])}},lookup:function(name){if(name in globals&&!(name in this.ctx)){return globals[name]}else{return this.ctx[name]}},setVariable:function(name,val){this.ctx[name]=val},getVariables:function(){return this.ctx},addBlock:function(name,block){this.blocks[name]=this.blocks[name]||[];this.blocks[name].push(block)},getBlock:function(name){if(!this.blocks[name]){throw new Error('unknown block "'+name+'"')}return this.blocks[name][0]},getSuper:function(env,name,block,frame,runtime,cb){var idx=lib.indexOf(this.blocks[name]||[],block);var blk=this.blocks[name][idx+1];var context=this;if(idx===-1||!blk){throw new Error('no super block available for "'+name+'"')}blk(env,context,frame,runtime,cb)},addExport:function(name){this.exported.push(name)},getExported:function(){var exported={};for(var i=0;i<this.exported.length;i++){var name=this.exported[i];exported[name]=this.ctx[name]}return exported}});var Template=Obj.extend({init:function(src,env,path,eagerCompile){this.env=env||new Environment;if(lib.isObject(src)){switch(src.type){case"code":this.tmplProps=src.obj;break;case"string":this.tmplStr=src.obj;break}}else if(lib.isString(src)){this.tmplStr=src}else{throw new Error("src must be a string or an object describing "+"the source")}this.path=path;if(eagerCompile){lib.withPrettyErrors(this.path,this.env.dev,this._compile.bind(this))}else{this.compiled=false}},render:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}else if(typeof frame==="function"){cb=frame;frame=null}return lib.withPrettyErrors(this.path,this.env.dev,function(){try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);var syncResult=null;this.rootRenderFunc(this.env,context,frame||new Frame,runtime,cb||function(err,res){if(err){throw err}syncResult=res});return syncResult}.bind(this))},getExported:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}if(typeof frame==="function"){cb=frame;frame=null}try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);this.rootRenderFunc(this.env,context,frame||new Frame,runtime,function(){cb(null,context.getExported())})},compile:function(){if(!this.compiled){this._compile()}},_compile:function(){var props;if(this.tmplProps){props=this.tmplProps}else{var source=compiler.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts);var func=new Function(source);props=func()}this.blocks=this._getBlocks(props);this.rootRenderFunc=props.root;this.compiled=true},_getBlocks:function(props){var blocks={};for(var k in props){if(k.slice(0,2)==="b_"){blocks[k.slice(2)]=props[k]}}return blocks}});modules["environment"]={Environment:Environment,Template:Template}})();var nunjucks;var lib=modules["lib"];var env=modules["environment"];var compiler=modules["compiler"];var parser=modules["parser"];var lexer=modules["lexer"];var runtime=modules["runtime"];var Loader=modules["loader"];var loaders=modules["loaders"];var precompile=modules["precompile"];nunjucks={};nunjucks.Environment=env.Environment;nunjucks.Template=env.Template;nunjucks.Loader=Loader;nunjucks.FileSystemLoader=loaders.FileSystemLoader;nunjucks.WebLoader=loaders.WebLoader;nunjucks.compiler=compiler;nunjucks.parser=parser;nunjucks.lexer=lexer;nunjucks.runtime=runtime;var e;nunjucks.configure=function(templatesPath,opts){opts=opts||{};if(lib.isObject(templatesPath)){opts=templatesPath;templatesPath=null}var noWatch="watch"in opts?!opts.watch:false;var loader=loaders.FileSystemLoader||loaders.WebLoader;e=new env.Environment(new loader(templatesPath,noWatch),opts);if(opts&&opts.express){e.express(opts.express)}return e};nunjucks.compile=function(src,env,path,eagerCompile){if(!e){nunjucks.configure()}return new nunjucks.Template(src,env,path,eagerCompile)};nunjucks.render=function(name,ctx,cb){if(!e){nunjucks.configure()}return e.render(name,ctx,cb)};nunjucks.renderString=function(src,ctx,cb){if(!e){nunjucks.configure()}return e.renderString(src,ctx,cb)};if(precompile){nunjucks.precompile=precompile.precompile;nunjucks.precompileString=precompile.precompileString}nunjucks.require=function(name){return modules[name]};if(typeof define==="function"&&define.amd){define(function(){return nunjucks})}else{window.nunjucks=nunjucks;if(typeof module!=="undefined")module.exports=nunjucks}})(); | ||
/*! Browser bundle of nunjucks 2.0.0 (slim, only works with precompiled templates) */ | ||
var nunjucks=function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return t[n].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";var n=r(1),i=r(2),o=r(11),s=r(3),u=r(3);t.exports={},t.exports.Environment=i.Environment,t.exports.Template=i.Template,t.exports.Loader=o,t.exports.FileSystemLoader=s.FileSystemLoader,t.exports.PrecompiledLoader=s.PrecompiledLoader,t.exports.WebLoader=s.WebLoader,t.exports.compiler=r(3),t.exports.parser=r(3),t.exports.lexer=r(3),t.exports.runtime=r(8),t.exports.lib=n,t.exports.installJinjaCompat=r(12);var a;t.exports.configure=function(t,e){e=e||{},n.isObject(t)&&(e=t,t=null);var r;return s.FileSystemLoader?r=new s.FileSystemLoader(t,{watch:e.watch,noCache:e.noCache}):s.WebLoader&&(r=new s.WebLoader(t,{useCache:e.web&&e.web.useCache,async:e.web&&e.web.async})),a=new i.Environment(r,e),e&&e.express&&a.express(e.express),a},t.exports.compile=function(e,r,n,i){return a||t.exports.configure(),new t.exports.Template(e,r,n,i)},t.exports.render=function(e,r,n){return a||t.exports.configure(),a.render(e,r,n)},t.exports.renderString=function(e,r,n){return a||t.exports.configure(),a.renderString(e,r,n)},u&&(t.exports.precompile=u.precompile,t.exports.precompileString=u.precompileString)},function(t,e){"use strict";var r=Array.prototype,n=Object.prototype,i={"&":"&",'"':""","'":"'","<":"<",">":">"},o=/[&"'<>]/g,s=function(t){return i[t]},e=t.exports={};e.prettifyError=function(t,r,n){if(n.Update||(n=new e.TemplateError(n)),n.Update(t),!r){var i=n;n=new Error(i.message),n.name=i.name}return n},e.TemplateError=function(t,e,r){var n=this;return t instanceof Error?(n=t,t=t.name+": "+t.message):Error.captureStackTrace&&Error.captureStackTrace(n),n.name="Template render error",n.message=t,n.lineno=e,n.colno=r,n.firstUpdate=!0,n.Update=function(t){var e="("+(t||"unknown path")+")";return this.firstUpdate&&(this.lineno&&this.colno?e+=" [Line "+this.lineno+", Column "+this.colno+"]":this.lineno&&(e+=" [Line "+this.lineno+"]")),e+="\n ",this.firstUpdate&&(e+=" "),this.message=e+(this.message||""),this.firstUpdate=!1,this},n},e.TemplateError.prototype=Error.prototype,e.escape=function(t){return t.replace(o,s)},e.isFunction=function(t){return"[object Function]"===n.toString.call(t)},e.isArray=Array.isArray||function(t){return"[object Array]"===n.toString.call(t)},e.isString=function(t){return"[object String]"===n.toString.call(t)},e.isObject=function(t){return"[object Object]"===n.toString.call(t)},e.groupBy=function(t,r){for(var n={},i=e.isFunction(r)?r:function(t){return t[r]},o=0;o<t.length;o++){var s=t[o],u=i(s,o);(n[u]||(n[u]=[])).push(s)}return n},e.toArray=function(t){return Array.prototype.slice.call(t)},e.without=function(t){var r=[];if(!t)return r;for(var n=-1,i=t.length,o=e.toArray(arguments).slice(1);++n<i;)-1===e.indexOf(o,t[n])&&r.push(t[n]);return r},e.extend=function(t,e){for(var r in e)t[r]=e[r];return t},e.repeat=function(t,e){for(var r="",n=0;e>n;n++)r+=t;return r},e.each=function(t,e,n){if(null!=t)if(r.each&&t.each===r.each)t.forEach(e,n);else if(t.length===+t.length)for(var i=0,o=t.length;o>i;i++)e.call(n,t[i],i,t)},e.map=function(t,e){var n=[];if(null==t)return n;if(r.map&&t.map===r.map)return t.map(e);for(var i=0;i<t.length;i++)n[n.length]=e(t[i],i);return t.length===+t.length&&(n.length=t.length),n},e.asyncIter=function(t,e,r){function n(){i++,i<t.length?e(t[i],i,n,r):r()}var i=-1;n()},e.asyncFor=function(t,r,n){function i(){u++;var e=o[u];s>u?r(e,t[e],u,s,i):n()}var o=e.keys(t),s=o.length,u=-1;i()},e.indexOf=Array.prototype.indexOf?function(t,e,r){return Array.prototype.indexOf.call(t,e,r)}:function(t,e,r){var n=this.length>>>0;for(r=+r||0,Math.abs(r)===1/0&&(r=0),0>r&&(r+=n,0>r&&(r=0));n>r;r++)if(t[r]===e)return r;return-1},Array.prototype.map||(Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}),e.keys=function(t){if(Object.prototype.keys)return t.keys();var e=[];for(var r in t)t.hasOwnProperty(r)&&e.push(r);return e}},function(t,e,r){"use strict";function n(t,e,r){s(function(){t(e,r)})}var i,o=r(3),s=r(4),u=r(1),a=r(6),c=r(3),l=r(7),f=r(3),p=r(8),h=r(9),v=p.Frame;f.PrecompiledLoader=r(10);var d=a.extend({init:function(t,e){e=this.opts=e||{},this.opts.dev=!!e.dev,this.opts.autoescape=null!=e.autoescape?e.autoescape:!0,this.opts.throwOnUndefined=!!e.throwOnUndefined,this.opts.trimBlocks=!!e.trimBlocks,this.opts.lstripBlocks=!!e.lstripBlocks,this.loaders=[],t?this.loaders=u.isArray(t)?t:[t]:f.FileSystemLoader?this.loaders=[new f.FileSystemLoader("views")]:f.WebLoader&&(this.loaders=[new f.WebLoader("/views")]),window.nunjucksPrecompiled&&this.loaders.unshift(new f.PrecompiledLoader(window.nunjucksPrecompiled)),this.initCache(),this.filters={},this.asyncFilters=[],this.extensions={},this.extensionsList=[];for(var r in l)this.addFilter(r,l[r])},initCache:function(){u.each(this.loaders,function(t){t.cache={},"function"==typeof t.on&&t.on("update",function(e){t.cache[e]=null})})},addExtension:function(t,e){e._name=t,this.extensions[t]=e,this.extensionsList.push(e)},getExtension:function(t){return this.extensions[t]},addGlobal:function(t,e){h[t]=e},getGlobal:function(t){if(!h[t])throw new Error("global not found: "+t);return h[t]},addFilter:function(t,e,r){var n=e;r&&this.asyncFilters.push(t),this.filters[t]=n},getFilter:function(t){if(!this.filters[t])throw new Error("filter not found: "+t);return this.filters[t]},resolveTemplate:function(t,e,r){var n=t.isRelative&&e?t.isRelative(r):!1;return n&&t.resolve?t.resolve(e,r):r},getTemplate:function(t,e,r,n){var o=this,s=null;if(t&&t.raw&&(t=t.raw),u.isFunction(r)&&(n=r,r=null,e=e||!1),u.isFunction(e)&&(n=e,e=!1),"string"!=typeof t)throw new Error("template names must be a string: "+t);for(var a=0;a<this.loaders.length;a++){var c=this.resolveTemplate(this.loaders[a],r,t);if(s=this.loaders[a].cache[c])break}if(!s){var l,f=this,p=function(r){if(r){var o=new i(r.src,f,r.path,e);r.noCache||(r.loader.cache[t]=o),n?n(null,o):l=o}else{var s=new Error("template not found: "+t);if(!n)throw s;n(s)}};return u.asyncIter(this.loaders,function(e,n,i,s){function u(t){t?(t.loader=e,s(t)):i()}t=o.resolveTemplate(e,r,t),e.async?e.getSource(t,function(t,e){if(t)throw t;u(e)}):u(e.getSource(t))},p),l}return e&&s.compile(),n?void n(null,s):s},express:function(t){function e(t,e){if(this.name=t,this.path=t,this.defaultEngine=e.defaultEngine,this.ext=o.extname(t),!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");this.ext||(this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine)}var r=this;e.prototype.render=function(t,e){r.render(this.name,t,e)},t.set("view",e)},render:function(t,e,r){u.isFunction(e)&&(r=e,e=null);var i=null;return this.getTemplate(t,function(t,o){if(t&&r)n(r,t);else{if(t)throw t;i=o.render(e,r)}}),i},renderString:function(t,e,r,n){u.isFunction(r)&&(n=r,r={}),r=r||{};var o=new i(t,this,r.path);return o.render(e,n)}}),g=a.extend({init:function(t,e){this.ctx={};for(var r in t)t.hasOwnProperty(r)&&(this.ctx[r]=t[r]);this.blocks={},this.exported=[];for(var n in e)this.addBlock(n,e[n])},lookup:function(t){return t in h&&!(t in this.ctx)?h[t]:this.ctx[t]},setVariable:function(t,e){this.ctx[t]=e},getVariables:function(){return this.ctx},addBlock:function(t,e){this.blocks[t]=this.blocks[t]||[],this.blocks[t].push(e)},getBlock:function(t){if(!this.blocks[t])throw new Error('unknown block "'+t+'"');return this.blocks[t][0]},getSuper:function(t,e,r,n,i,o){var s=u.indexOf(this.blocks[e]||[],r),a=this.blocks[e][s+1],c=this;if(-1===s||!a)throw new Error('no super block available for "'+e+'"');a(t,c,n,i,o)},addExport:function(t){this.exported.push(t)},getExported:function(){for(var t={},e=0;e<this.exported.length;e++){var r=this.exported[e];t[r]=this.ctx[r]}return t}});i=a.extend({init:function(t,e,r,n){if(this.env=e||new d,u.isObject(t))switch(t.type){case"code":this.tmplProps=t.obj;break;case"string":this.tmplStr=t.obj}else{if(!u.isString(t))throw new Error("src must be a string or an object describing the source");this.tmplStr=t}if(this.path=r,n){var i=this;try{i._compile()}catch(o){throw u.prettifyError(this.path,this.env.dev,o)}}else this.compiled=!1},render:function(t,e,r){"function"==typeof t?(r=t,t={}):"function"==typeof e&&(r=e,e=null);var i=!0;e&&(i=!1);var o=this;try{o.compile()}catch(s){var a=u.prettifyError(this.path,this.env.dev,s);if(r)return n(r,a);throw a}var c=new g(t||{},o.blocks),l=e?e.push():new v;l.topLevel=!0;var f=null;return o.rootRenderFunc(o.env,c,l||new v,p,function(t,e){if(t&&(t=u.prettifyError(o.path,o.env.dev,t)),r)i?n(r,t,e):r(t,e);else{if(t)throw t;f=e}}),f},getExported:function(t,e,r){"function"==typeof t&&(r=t,t={}),"function"==typeof e&&(r=e,e=null);try{this.compile()}catch(n){if(r)return r(n);throw n}var i=e?e.push():new v;i.topLevel=!0;var o=new g(t||{},this.blocks);this.rootRenderFunc(this.env,o,i,p,function(){r(null,o.getExported())})},compile:function(){this.compiled||this._compile()},_compile:function(){var t;if(this.tmplProps)t=this.tmplProps;else{var e=c.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts),r=new Function(e);t=r()}this.blocks=this._getBlocks(t),this.rootRenderFunc=t.root,this.compiled=!0},_getBlocks:function(t){var e={};for(var r in t)"b_"===r.slice(0,2)&&(e[r.slice(2)]=t[r]);return e}}),t.exports={Environment:d,Template:i}},function(t,e){},function(t,e,r){"use strict";function n(){if(a.length)throw a.shift()}function i(t){var e;e=u.length?u.pop():new o,e.task=t,s(e)}function o(){this.task=null}var s=r(5),u=[],a=[],c=s.makeRequestCallFromTimer(n);t.exports=i,o.prototype.call=function(){try{this.task.call()}catch(t){i.onerror?i.onerror(t):(a.push(t),c())}finally{this.task=null,u[u.length]=this}}},function(t,e){(function(e){"use strict";function r(t){u.length||(s(),a=!0),u[u.length]=t}function n(){for(;c<u.length;){var t=c;if(c+=1,u[t].call(),c>l){for(var e=0,r=u.length-c;r>e;e++)u[e]=u[e+c];u.length-=c,c=0}}u.length=0,c=0,a=!1}function i(t){var e=1,r=new f(t),n=document.createTextNode("");return r.observe(n,{characterData:!0}),function(){e=-e,n.data=e}}function o(t){return function(){function e(){clearTimeout(r),clearInterval(n),t()}var r=setTimeout(e,0),n=setInterval(e,50)}}t.exports=r;var s,u=[],a=!1,c=0,l=1024,f=e.MutationObserver||e.WebKitMutationObserver;s="function"==typeof f?i(n):o(n),r.requestFlush=s,r.makeRequestCallFromTimer=o}).call(e,function(){return this}())},function(t,e){"use strict";function r(t,e,n){var i=function(){};i.prototype=t.prototype;var o=new i,s=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;n=n||{};for(var u in n){var a=n[u],c=o[u];"function"==typeof c&&"function"==typeof a&&s.test(a)?o[u]=function(t,e){return function(){var r=this.parent;this.parent=e;var n=t.apply(this,arguments);return this.parent=r,n}}(a,c):o[u]=a}o.typename=e;var l=function(){o.init&&o.init.apply(this,arguments)};return l.prototype=o,l.prototype.constructor=l,l.extend=function(t,e){return"object"==typeof t&&(e=t,t="anonymous"),r(l,t,e)},l}t.exports=r(Object,"Object",{})},function(t,e,r){"use strict";function n(t,e){return null===t||void 0===t||t===!1?e:t}var i=r(1),o=r(8),s=!1,u={abs:function(t){return Math.abs(t)},batch:function(t,e,r){var n,i=[],o=[];for(n=0;n<t.length;n++)n%e===0&&o.length&&(i.push(o),o=[]),o.push(t[n]);if(o.length){if(r)for(n=o.length;e>n;n++)o.push(r);i.push(o)}return i},capitalize:function(t){t=n(t,"");var e=t.toLowerCase();return o.copySafeness(t,e.charAt(0).toUpperCase()+e.slice(1))},center:function(t,e){if(t=n(t,""),e=e||80,t.length>=e)return t;var r=e-t.length,s=i.repeat(" ",r/2-r%2),u=i.repeat(" ",r/2);return o.copySafeness(t,s+t+u)},"default":function(t,e,r){return r===!0||r===!1||s||(s=!0,console.log('[nunjucks] Warning: the "default" filter was used without specifying the type of comparison. 2.0 changed the default behavior from boolean (val ? val : def) to strictly undefined, so you should make sure that doesn\'t break anything. Be explicit about this to make this warning go away, or wait until 2.1. See http://mozilla.github.io/nunjucks/templating.html#defaultvalue-default-boolean')),r?t?t:e:void 0!==t?t:e},dictsort:function(t,e,r){if(!i.isObject(t))throw new i.TemplateError("dictsort filter: val must be an object");var n=[];for(var o in t)n.push([o,t[o]]);var s;if(void 0===r||"key"===r)s=0;else{if("value"!==r)throw new i.TemplateError("dictsort filter: You can only sort by either key or value");s=1}return n.sort(function(t,r){var n=t[s],o=r[s];return e||(i.isString(n)&&(n=n.toUpperCase()),i.isString(o)&&(o=o.toUpperCase())),n>o?1:n===o?0:-1}),n},dump:function(t){return JSON.stringify(t)},escape:function(t){return"string"==typeof t||t instanceof o.SafeString?i.escape(t):t},safe:function(t){return o.markSafe(t)},first:function(t){return t[0]},groupby:function(t,e){return i.groupBy(t,e)},indent:function(t,e,r){if(t=n(t,""),""===t)return"";e=e||4;for(var s="",u=t.split("\n"),a=i.repeat(" ",e),c=0;c<u.length;c++)s+=0!==c||r?a+u[c]+"\n":u[c]+"\n";return o.copySafeness(t,s)},join:function(t,e,r){return e=e||"",r&&(t=i.map(t,function(t){return t[r]})),t.join(e)},last:function(t){return t[t.length-1]},length:function(t){var e=n(t,"");return void 0!==e?e.length:0},list:function(t){if(i.isString(t))return t.split("");if(i.isObject(t)){var e=[];if(Object.keys)e=Object.keys(t);else for(var r in t)e.push(r);return i.map(e,function(e){return{key:e,value:t[e]}})}if(i.isArray(t))return t;throw new i.TemplateError("list filter: type not iterable")},lower:function(t){return t=n(t,""),t.toLowerCase()},random:function(t){return t[Math.floor(Math.random()*t.length)]},rejectattr:function(t,e){return t.filter(function(t){return!t[e]})},selectattr:function(t,e){return t.filter(function(t){return!!t[e]})},replace:function(t,e,r,n){var i=t;if(e instanceof RegExp)return t.replace(e,r);"undefined"==typeof n&&(n=-1);var s="";if("number"==typeof e)e+="";else if("string"!=typeof e)return t;if("number"==typeof t&&(t+=""),"string"!=typeof t&&!(t instanceof o.SafeString))return t;if(""===e)return s=r+t.split("").join(r)+r,o.copySafeness(t,s);var u=t.indexOf(e);if(0===n||-1===u)return t;for(var a=0,c=0;u>-1&&(-1===n||n>c);)s+=t.substring(a,u)+r,a=u+e.length,c++,u=t.indexOf(e,a);return a<t.length&&(s+=t.substring(a)),o.copySafeness(i,s)},reverse:function(t){var e;return e=i.isString(t)?u.list(t):i.map(t,function(t){return t}),e.reverse(),i.isString(t)?o.copySafeness(t,e.join("")):e},round:function(t,e,r){e=e||0;var n,i=Math.pow(10,e);return n="ceil"===r?Math.ceil:"floor"===r?Math.floor:Math.round,n(t*i)/i},slice:function(t,e,r){for(var n=Math.floor(t.length/e),i=t.length%e,o=0,s=[],u=0;e>u;u++){var a=o+u*n;i>u&&o++;var c=o+(u+1)*n,l=t.slice(a,c);r&&u>=i&&l.push(r),s.push(l)}return s},sort:function(t,e,r,n){return t=i.map(t,function(t){return t}),t.sort(function(t,o){var s,u;return n?(s=t[n],u=o[n]):(s=t,u=o),!r&&i.isString(s)&&i.isString(u)&&(s=s.toLowerCase(),u=u.toLowerCase()),u>s?e?1:-1:s>u?e?-1:1:0}),t},string:function(t){return o.copySafeness(t,t)},title:function(t){t=n(t,"");for(var e=t.split(" "),r=0;r<e.length;r++)e[r]=u.capitalize(e[r]);return o.copySafeness(t,e.join(" "))},trim:function(t){return o.copySafeness(t,t.replace(/^\s*|\s*$/g,""))},truncate:function(t,e,r,i){var s=t;if(t=n(t,""),e=e||255,t.length<=e)return t;if(r)t=t.substring(0,e);else{var u=t.lastIndexOf(" ",e);-1===u&&(u=e),t=t.substring(0,u)}return t+=void 0!==i&&null!==i?i:"...",o.copySafeness(s,t)},upper:function(t){return t=n(t,""),t.toUpperCase()},urlencode:function(t){var e=encodeURIComponent;if(i.isString(t))return e(t);var r;if(i.isArray(t))r=t.map(function(t){return e(t[0])+"="+e(t[1])});else{r=[];for(var n in t)t.hasOwnProperty(n)&&r.push(e(n)+"="+e(t[n]))}return r.join("&")},urlize:function(t,e,r){isNaN(e)&&(e=1/0);var n=r===!0?' rel="nofollow"':"",i=/^(?:\(|<|<)?(.*?)(?:\.|,|\)|\n|>)?$/,o=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i,s=/^https?:\/\/.*$/,u=/^www\./,a=/\.(?:org|net|com)(?:\:|\/|$)/,c=t.split(/\s+/).filter(function(t){return t&&t.length}).map(function(t){var r=t.match(i),c=r&&r[1]||t;return s.test(c)?'<a href="'+c+'"'+n+">"+c.substr(0,e)+"</a>":u.test(c)?'<a href="http://'+c+'"'+n+">"+c.substr(0,e)+"</a>":o.test(c)?'<a href="mailto:'+c+'">'+c+"</a>":a.test(c)?'<a href="http://'+c+'"'+n+">"+c.substr(0,e)+"</a>":t});return c.join(" ")},wordcount:function(t){t=n(t,"");var e=t?t.match(/\w+/g):null;return e?e.length:null},"float":function(t,e){var r=parseFloat(t);return isNaN(r)?e:r},"int":function(t,e){var r=parseInt(t,10);return isNaN(r)?e:r}};u.d=u["default"],u.e=u.escape,t.exports=u},function(t,e,r){"use strict";function n(t,e,r){return function(){var n,i,u=s(arguments),a=o(arguments);if(u>t.length){n=Array.prototype.slice.call(arguments,0,t.length);var c=Array.prototype.slice.call(arguments,n.length,u);for(i=0;i<c.length;i++)i<e.length&&(a[e[i]]=c[i]);n.push(a)}else if(u<t.length){for(n=Array.prototype.slice.call(arguments,0,u),i=u;i<t.length;i++){var l=t[i];n.push(a[l]),delete a[l]}n.push(a)}else n=arguments;return r.apply(this,n)}}function i(t){return t.__keywords=!0,t}function o(t){var e=t.length;if(e){var r=t[e-1];if(r&&r.hasOwnProperty("__keywords"))return r}return{}}function s(t){var e=t.length;if(0===e)return 0;var r=t[e-1];return r&&r.hasOwnProperty("__keywords")?e-1:e}function u(t){return"string"!=typeof t?t:(this.val=t,void(this.length=t.length))}function a(t,e){return t instanceof u?new u(e):e.toString()}function c(t){var e=typeof t;return"string"===e?new u(t):"function"!==e?t:function(){var e=t.apply(this,arguments);return"string"==typeof e?new u(e):e}}function l(t,e){return t=void 0!==t&&null!==t?t:"",e&&"string"==typeof t&&(t=m.escape(t)),t}function f(t,e,r){if(null===t||void 0===t)throw new m.TemplateError("attempted to output null or undefined value",e+1,r+1);return t}function p(t,e){return t=t||{},"function"==typeof t[e]?function(){return t[e].apply(t,arguments)}:t[e]}function h(t,e,r,n){if(!t)throw new Error("Unable to call `"+e+"`, which is undefined or falsey");if("function"!=typeof t)throw new Error("Unable to call `"+e+"`, which is not a function");return t.apply(r,n)}function v(t,e,r){var n=e.lookup(r);return void 0!==n&&null!==n?n:t.lookup(r)}function d(t,e,r){return t.lineno?t:new m.TemplateError(t,e,r)}function g(t,e,r,n){if(m.isArray(t)){var i=t.length;m.asyncIter(t,function(t,n,o){switch(e){case 1:r(t,n,i,o);break;case 2:r(t[0],t[1],n,i,o);break;case 3:r(t[0],t[1],t[2],n,i,o);break;default:t.push(n,o),r.apply(this,t)}},n)}else m.asyncFor(t,function(t,e,n,i,o){r(t,e,n,i,o)},n)}function y(t,e,r,n){function i(t,e){a++,u[t]=e,a===o&&n(null,u.join(""))}var o,s,u,a=0;if(m.isArray(t))if(o=t.length,u=new Array(o),0===o)n(null,"");else for(s=0;s<t.length;s++){var c=t[s];switch(e){case 1:r(c,s,o,i);break;case 2:r(c[0],c[1],s,o,i);break;case 3:r(c[0],c[1],c[2],s,o,i);break;default:c.push(s,i),r.apply(this,c)}}else{var l=m.keys(t);if(o=l.length,u=new Array(o),0===o)n(null,"");else for(s=0;s<l.length;s++){var f=l[s];r(f,t[f],s,o,i)}}}var m=r(1),w=r(6),b=w.extend({init:function(t){this.variables={},this.parent=t,this.topLevel=!1},set:function(t,e,r){var n=t.split("."),i=this.variables,o=this;if(r){if(o=this.resolve(n[0]))return void o.set(t,e);o=this}for(var s=0;s<n.length-1;s++){var u=n[s];i[u]||(i[u]={}),i=i[u]}i[n[n.length-1]]=e},get:function(t){var e=this.variables[t];return void 0!==e&&null!==e?e:null},lookup:function(t){var e=this.parent,r=this.variables[t];return void 0!==r&&null!==r?r:e&&e.lookup(t)},resolve:function(t){var e=this.parent,r=this.variables[t];return void 0!==r&&null!==r?this:e&&e.resolve(t)},push:function(){return new b(this)},pop:function(){return this.parent}});u.prototype=Object.create(String.prototype,{length:{writable:!0,configurable:!0,value:0}}),u.prototype.valueOf=function(){return this.val},u.prototype.toString=function(){return this.val},t.exports={Frame:b,makeMacro:n,makeKeywordArgs:i,numArgs:s,suppressValue:l,ensureDefined:f,memberLookup:p,contextOrFrameLookup:v,callWrap:h,handleError:d,isArray:m.isArray,keys:m.keys,SafeString:u,copySafeness:a,markSafe:c,asyncEach:g,asyncAll:y}},function(t,e){"use strict";function r(t){var e=-1;return{current:null,reset:function(){e=-1,this.current=null},next:function(){return e++,e>=t.length&&(e=0),this.current=t[e],this.current}}}function n(t){t=t||",";var e=!0;return function(){var r=e?"":t;return e=!1,r}}var i={range:function(t,e,r){e?r||(r=1):(e=t,t=0,r=1);for(var n=[],i=t;e>i;i+=r)n.push(i);return n},cycler:function(){return r(Array.prototype.slice.call(arguments))},joiner:function(t){return n(t)}};t.exports=i},function(t,e,r){"use strict";var n=r(11),i=n.extend({init:function(t){this.precompiled=t||{}},getSource:function(t){return this.precompiled[t]?{src:{type:"code",obj:this.precompiled[t]},path:t}:null}});t.exports=i},function(t,e,r){"use strict";var n=r(3),i=r(6),o=r(1),s=i.extend({on:function(t,e){this.listeners=this.listeners||{},this.listeners[t]=this.listeners[t]||[],this.listeners[t].push(e)},emit:function(t){var e=Array.prototype.slice.call(arguments,1);this.listeners&&this.listeners[t]&&o.each(this.listeners[t],function(t){t.apply(null,e)})},resolve:function(t,e){return n.resolve(n.dirname(t),e)},isRelative:function(t){return 0===t.indexOf("./")||0===t.indexOf("../")}});t.exports=s},function(t,e){function r(){"use strict";var t=this.runtime,e=this.lib,r=t.contextOrFrameLookup;t.contextOrFrameLookup=function(t,e,n){var i=r.apply(this,arguments);if(void 0===i)switch(n){case"True":return!0;case"False":return!1;case"None":return null}return i};var n=t.memberLookup,i={pop:function(t){if(void 0===t)return this.pop();if(t>=this.length||0>t)throw new Error("KeyError");return this.splice(t,1)},remove:function(t){for(var e=0;e<this.length;e++)if(this[e]===t)return this.splice(e,1);throw new Error("ValueError")},count:function(t){for(var e=0,r=0;r<this.length;r++)this[r]===t&&e++;return e},index:function(t){var e;if(-1===(e=this.indexOf(t)))throw new Error("ValueError");return e},find:function(t){return this.indexOf(t)},insert:function(t,e){return this.splice(t,0,e)}},o={items:function(){var t=[];for(var e in this)t.push([e,this[e]]);return t},values:function(){var t=[];for(var e in this)t.push(this[e]);return t},keys:function(){var t=[];for(var e in this)t.push(e);return t},get:function(t,e){var r=this[t];return void 0===r&&(r=e),r},has_key:function(t){return this.hasOwnProperty(t)},pop:function(t,e){var r=this[t];if(void 0===r&&void 0!==e)r=e;else{if(void 0===r)throw new Error("KeyError");delete this[t]}return r},popitem:function(){for(var t in this){var e=this[t];return delete this[t],[t,e]}throw new Error("KeyError")},setdefault:function(t,e){return t in this?this[t]:(void 0===e&&(e=null),this[t]=e)},update:function(t){for(var e in t)this[e]=t[e];return null}};o.iteritems=o.items,o.itervalues=o.values,o.iterkeys=o.keys,t.memberLookup=function(t,r,s){return t=t||{},e.isArray(t)&&i.hasOwnProperty(r)?function(){return i[r].apply(t,arguments)}:e.isObject(t)&&o.hasOwnProperty(r)?function(){return o[r].apply(t,arguments)}:n.apply(this,arguments)}}t.exports=r}]); |
35
index.js
@@ -0,8 +1,5 @@ | ||
'use strict'; | ||
var lib = require('./src/lib'); | ||
var env = require('./src/environment'); | ||
var compiler = require('./src/compiler'); | ||
var parser = require('./src/parser'); | ||
var lexer = require('./src/lexer'); | ||
var runtime = require('./src/runtime'); | ||
var Loader = require('./src/loader'); | ||
@@ -18,9 +15,13 @@ var loaders = require('./src/loaders'); | ||
module.exports.FileSystemLoader = loaders.FileSystemLoader; | ||
module.exports.PrecompiledLoader = loaders.PrecompiledLoader; | ||
module.exports.WebLoader = loaders.WebLoader; | ||
module.exports.compiler = compiler; | ||
module.exports.parser = parser; | ||
module.exports.lexer = lexer; | ||
module.exports.runtime = runtime; | ||
module.exports.compiler = require('./src/compiler'); | ||
module.exports.parser = require('./src/parser'); | ||
module.exports.lexer = require('./src/lexer'); | ||
module.exports.runtime = require('./src/runtime'); | ||
module.exports.lib = lib; | ||
module.exports.installJinjaCompat = require('./src/jinja-compat.js'); | ||
// A single instance of an environment, since this is so commonly used | ||
@@ -36,6 +37,18 @@ | ||
var noWatch = 'watch' in opts ? !opts.watch : false; | ||
var loader = loaders.FileSystemLoader || loaders.WebLoader; | ||
e = new env.Environment(new loader(templatesPath, noWatch), opts); | ||
var TemplateLoader; | ||
if(loaders.FileSystemLoader) { | ||
TemplateLoader = new loaders.FileSystemLoader(templatesPath, { | ||
watch: opts.watch, | ||
noCache: opts.noCache | ||
}); | ||
} | ||
else if(loaders.WebLoader) { | ||
TemplateLoader = new loaders.WebLoader(templatesPath, { | ||
useCache: opts.web && opts.web.useCache, | ||
async: opts.web && opts.web.async | ||
}); | ||
} | ||
e = new env.Environment(TemplateLoader, opts); | ||
if(opts && opts.express) { | ||
@@ -42,0 +55,0 @@ e.express(opts.express); |
@@ -34,8 +34,8 @@ | ||
8. Make sure docs are up-to-date. You need to at least copy all the nunjucks*.js files in `browser/` to the [nunjucks-docs repo](https://github.com/mozilla/nunjucks-docs) in the `files` directory. This is where the "download" link points to in the docs. In `nunjucks-docs`, build the docs: | ||
8. Make sure docs are up-to-date. You need to copy all the nunjucks*.js files in `browser/` to the docs. This is where the "download" link points to in the docs. Push (force push if necessary) the build out _site folder onto the `gh-pages` branch of the `nunjucks` repo to get it live. | ||
``` | ||
cd path/to/nunjucks-docs && make prod | ||
cp browser/* docs/files | ||
cd docs && make prod | ||
cd _site && git push origin gh-pages (assumes you have setup a git repo in _site pointing to nunjucks) | ||
``` | ||
And push (force push if necessary) the build out _site folder onto the `gh-pages` branch of the `nunjucks` repo to get it live. |
{ | ||
"name": "nunjucks", | ||
"description": "A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)", | ||
"version": "1.3.4", | ||
"author": "James Long <longster@gmail.com>", | ||
"dependencies": { | ||
"optimist": "*", | ||
"chokidar": "~0.12.5" | ||
}, | ||
"browser" : "./browser/nunjucks.js", | ||
"devDependencies": { | ||
"expect.js": "*", | ||
"mocha": "*", | ||
"uglify-js": "*", | ||
"express": "4.x", | ||
"supertest": "*", | ||
"istanbul": "0.3.x" | ||
}, | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"scripts": { | ||
"test": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha -- -b -R tap tests", | ||
"browserfiles": "./bin/bundle browser/nunjucks; SLIM=1 ./bin/bundle browser/nunjucks-slim" | ||
}, | ||
"bin": { | ||
"nunjucks-precompile": "./bin/precompile" | ||
}, | ||
"main": "index", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/mozilla/nunjucks.git" | ||
}, | ||
"keywords": [ | ||
"template", | ||
"templating" | ||
], | ||
"license": [{ | ||
"type": "BSD", | ||
"url": "https://github.com/mozilla/nunjucks/blob/master/LICENSE" | ||
}], | ||
"bugs": { | ||
"url": "https://github.com/mozilla/nunjucks/issues" | ||
} | ||
"name": "nunjucks", | ||
"description": "A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)", | ||
"version": "2.0.0", | ||
"author": "James Long <longster@gmail.com>", | ||
"dependencies": { | ||
"asap": "^2.0.3", | ||
"chokidar": "^1.0.0", | ||
"optimist": "*" | ||
}, | ||
"browser": "./browser/nunjucks.js", | ||
"devDependencies": { | ||
"expect.js": "*", | ||
"express": "4.x", | ||
"istanbul": "0.3.x", | ||
"jshint": "*", | ||
"mocha": "*", | ||
"node-libs-browser": "^0.4.3", | ||
"supertest": "*", | ||
"uglify-js": "*", | ||
"webpack": "^1.8.11" | ||
}, | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"scripts": { | ||
"lint": "jshint .", | ||
"test": "jshint . && istanbul cover ./node_modules/mocha/bin/_mocha -- -b -R tap tests", | ||
"browserfiles": "./bin/bundle" | ||
}, | ||
"bin": { | ||
"nunjucks-precompile": "./bin/precompile" | ||
}, | ||
"main": "index", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/mozilla/nunjucks.git" | ||
}, | ||
"keywords": [ | ||
"template", | ||
"templating" | ||
], | ||
"license": "BSD-2-Clause", | ||
"bugs": { | ||
"url": "https://github.com/mozilla/nunjucks/issues" | ||
} | ||
} |
@@ -18,5 +18,9 @@ # Nunjucks | ||
## Browser Support | ||
Supported in all modern browsers. For IE8 support, use [es5-shim](https://github.com/es-shims/es5-shim). | ||
## Tests | ||
Run the tests with `make test`. | ||
Run the tests with `npm test`. | ||
@@ -23,0 +27,0 @@ Watch `master` branch's tests running at http://mozilla.github.io/nunjucks/files/tests/browser/. |
@@ -7,2 +7,3 @@ 'use strict'; | ||
var nodes = require('./nodes'); | ||
// jshint -W079 | ||
var Object = require('./object'); | ||
@@ -32,3 +33,3 @@ var Frame = require('./runtime').Frame; | ||
var Compiler = Object.extend({ | ||
init: function(templateName) { | ||
init: function(templateName, throwOnUndefined) { | ||
this.templateName = templateName; | ||
@@ -39,4 +40,5 @@ this.codebuf = []; | ||
this.bufferStack = []; | ||
this.isChild = false; | ||
this.scopeClosers = ''; | ||
this.inBlock = false; | ||
this.throwOnUndefined = throwOnUndefined; | ||
}, | ||
@@ -133,8 +135,2 @@ | ||
_bufferAppend: function(func) { | ||
this.emit(this.buffer + ' += runtime.suppressValue('); | ||
func.call(this); | ||
this.emit(', env.opts.autoescape);\n'); | ||
}, | ||
_compileChildren: function(node, frame) { | ||
@@ -186,2 +182,3 @@ var children = node.children; | ||
nodes.Add, | ||
nodes.Concat, | ||
nodes.Sub, | ||
@@ -219,7 +216,5 @@ nodes.Mul, | ||
compileCallExtension: function(node, frame, async) { | ||
var name = node.extName; | ||
var args = node.args; | ||
var contentArgs = node.contentArgs; | ||
var autoescape = typeof node.autoescape === 'boolean' ? node.autoescape : true; | ||
var transformedArgs = []; | ||
@@ -303,3 +298,3 @@ if(!async) { | ||
compileLiteral: function(node, frame) { | ||
compileLiteral: function(node) { | ||
if(typeof node.value === 'string') { | ||
@@ -386,2 +381,5 @@ var val = node.value.replace(/\\/g, '\\\\'); | ||
compileAdd: binOpEmitter(' + '), | ||
// ensure concatenation instead of addition | ||
// by adding empty string in between | ||
compileConcat: binOpEmitter(' + "" + '), | ||
compileSub: binOpEmitter(' - '), | ||
@@ -438,3 +436,3 @@ compileMul: binOpEmitter(' * '), | ||
this._compileExpression(node.val, frame); | ||
this.emit(', env.opts.autoescape)'); | ||
this.emit(')'); | ||
}, | ||
@@ -472,3 +470,3 @@ | ||
// if the lookup fails. | ||
this.emit(', "' + this._getNodeName(node.name).replace(/"/g, '\\"') + '", '); | ||
this.emit(', "' + this._getNodeName(node.name).replace(/"/g, '\\"') + '", context, '); | ||
@@ -543,12 +541,15 @@ this._compileAggregate(node.args, frame, '[', '])'); | ||
// We are running this for every var, but it's very | ||
// uncommon to assign to multiple vars anyway | ||
this.emitLine('frame.set("' + name + '", ' + id + ', true);'); | ||
// We are running this for every var, but it's very | ||
// uncommon to assign to multiple vars anyway | ||
this.emitLine('if(!frame.parent) {'); | ||
this.emitLine('if(frame.topLevel) {'); | ||
this.emitLine('context.setVariable("' + name + '", ' + id + ');'); | ||
this.emitLine('}'); | ||
if(name.charAt(0) !== '_') { | ||
this.emitLine('context.addExport("' + name + '");'); | ||
this.emitLine('if(frame.topLevel) {'); | ||
this.emitLine('context.addExport("' + name + '", ' + id + ');'); | ||
this.emitLine('}'); | ||
} | ||
this.emitLine('}'); | ||
}, this); | ||
@@ -616,2 +617,3 @@ }, | ||
var v; | ||
var i = this.tmpid(); | ||
@@ -664,3 +666,3 @@ var len = this.tmpid(); | ||
var k = this.tmpid(); | ||
var v = this.tmpid(); | ||
v = this.tmpid(); | ||
frame.set(key.value, k); | ||
@@ -688,3 +690,3 @@ frame.set(val.value, v); | ||
// Generate a typical array iteration | ||
var v = this.tmpid(); | ||
v = this.tmpid(); | ||
frame.set(node.name.value, v); | ||
@@ -912,3 +914,3 @@ | ||
this.emitLine(id + '.getExported(' + | ||
(node.withContext ? 'context.getVariables(), frame.push(), ' : '') + | ||
(node.withContext ? 'context.getVariables(), frame, ' : '') + | ||
this.makeCallback(id)); | ||
@@ -936,3 +938,3 @@ this.addScopeLevel(); | ||
this.emitLine(importedId + '.getExported(' + | ||
(node.withContext ? 'context.getVariables(), frame.push(), ' : '') + | ||
(node.withContext ? 'context.getVariables(), frame, ' : '') + | ||
this.makeCallback(importedId)); | ||
@@ -972,11 +974,25 @@ this.addScopeLevel(); | ||
compileBlock: function(node, frame) { | ||
if(!this.isChild) { | ||
var id = this.tmpid(); | ||
compileBlock: function(node) { | ||
var id = this.tmpid(); | ||
this.emitLine('context.getBlock("' + node.name.value + '")' + | ||
'(env, context, frame, runtime, ' + this.makeCallback(id)); | ||
this.emitLine(this.buffer + ' += ' + id + ';'); | ||
this.addScopeLevel(); | ||
// If we are executing outside a block (creating a top-level | ||
// block), we really don't want to execute its code because it | ||
// will execute twice: once when the child template runs and | ||
// again when the parent template runs. Note that blocks | ||
// within blocks will *always* execute immediately *and* | ||
// wherever else they are invoked (like used in a parent | ||
// template). This may have behavioral differences from jinja | ||
// because blocks can have side effects, but it seems like a | ||
// waste of performance to always execute huge top-level | ||
// blocks twice | ||
if(!this.inBlock) { | ||
this.emit('(parentTemplate ? function(e, c, f, r, cb) { cb(""); } : '); | ||
} | ||
this.emit('context.getBlock("' + node.name.value + '")'); | ||
if(!this.inBlock) { | ||
this.emit(')'); | ||
} | ||
this.emitLine('(env, context, frame, runtime, ' + this.makeCallback(id)); | ||
this.emitLine(this.buffer + ' += ' + id + ';'); | ||
this.addScopeLevel(); | ||
}, | ||
@@ -999,8 +1015,2 @@ | ||
compileExtends: function(node, frame) { | ||
if(this.isChild) { | ||
this.fail('compileExtends: cannot extend multiple times', | ||
node.template.lineno, | ||
node.template.colno); | ||
} | ||
var k = this.tmpid(); | ||
@@ -1010,4 +1020,9 @@ | ||
this._compileExpression(node.template, frame); | ||
this.emitLine(', true, '+this._templateName()+', ' + this.makeCallback('parentTemplate')); | ||
this.emitLine(', true, '+this._templateName()+', ' + this.makeCallback('_parentTemplate')); | ||
// extends is a dynamic tag and can occur within a block like | ||
// `if`, so if this happens we need to capture the parent | ||
// template in the top-level scope | ||
this.emitLine('parentTemplate = _parentTemplate'); | ||
this.emitLine('for(var ' + k + ' in parentTemplate.blocks) {'); | ||
@@ -1019,3 +1034,2 @@ this.emitLine('context.addBlock(' + k + | ||
this.addScopeLevel(); | ||
this.isChild = true; | ||
}, | ||
@@ -1033,3 +1047,3 @@ | ||
this.emitLine(id + '.render(' + | ||
'context.getVariables(), frame.push(), ' + this.makeCallback(id2)); | ||
'context.getVariables(), frame, ' + this.makeCallback(id2)); | ||
this.emitLine(this.buffer + ' += ' + id2); | ||
@@ -1057,3 +1071,9 @@ this.addScopeLevel(); | ||
this.emit(this.buffer + ' += runtime.suppressValue('); | ||
if(this.throwOnUndefined) { | ||
this.emit('runtime.ensureDefined('); | ||
} | ||
this.compile(children[i], frame); | ||
if(this.throwOnUndefined) { | ||
this.emit(',' + node.lineno + ',' + node.colno + ')'); | ||
} | ||
this.emit(', env.opts.autoescape);\n'); | ||
@@ -1072,15 +1092,17 @@ } | ||
this.emitFuncBegin('root'); | ||
this.emitLine('var parentTemplate = null;'); | ||
this._compileChildren(node, frame); | ||
if(this.isChild) { | ||
this.emitLine('parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);'); | ||
} | ||
this.emitFuncEnd(this.isChild); | ||
this.emitLine('if(parentTemplate) {'); | ||
this.emitLine('parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);'); | ||
this.emitLine('} else {'); | ||
this.emitLine('cb(null, ' + this.buffer +');'); | ||
this.emitLine('}'); | ||
this.emitFuncEnd(true); | ||
// When compiling the blocks, they should all act as top-level code | ||
this.isChild = false; | ||
this.inBlock = true; | ||
var blocks = node.findAll(nodes.Block); | ||
for(var i=0; i<blocks.length; i++) { | ||
var block = blocks[i]; | ||
var name = block.name.value; | ||
var i, name, block, blocks = node.findAll(nodes.Block); | ||
for (i = 0; i < blocks.length; i++) { | ||
block = blocks[i]; | ||
name = block.name.value; | ||
@@ -1095,5 +1117,5 @@ this.emitFuncBegin('b_' + name); | ||
this.emitLine('return {'); | ||
for(var i=0; i<blocks.length; i++) { | ||
var block = blocks[i]; | ||
var name = 'b_' + block.name.value; | ||
for (i = 0; i < blocks.length; i++) { | ||
block = blocks[i]; | ||
name = 'b_' + block.name.value; | ||
this.emitLine(name + ': ' + name + ','); | ||
@@ -1122,3 +1144,5 @@ } | ||
// var c = new Compiler(); | ||
// var src = '{% asyncEach i in arr %}{{ i }}{% else %}empty{% endeach %}'; | ||
// var src = 'hello {% filter title %}' + | ||
// 'Hello madam how are you' + | ||
// '{% endfilter %}' | ||
// var ast = transformer.transform(parser.parse(src)); | ||
@@ -1132,3 +1156,3 @@ // nodes.printNodes(ast); | ||
compile: function(src, asyncFilters, extensions, name, opts) { | ||
var c = new Compiler(name); | ||
var c = new Compiler(name, opts.throwOnUndefined); | ||
@@ -1144,7 +1168,9 @@ // Run the extension preprocessors against the source. | ||
c.compile(transformer.transform(parser.parse(src, | ||
extensions, | ||
opts), | ||
asyncFilters, | ||
name)); | ||
c.compile(transformer.transform( | ||
parser.parse(src, | ||
extensions, | ||
opts), | ||
asyncFilters, | ||
name | ||
)); | ||
return c.getCode(); | ||
@@ -1151,0 +1177,0 @@ }, |
'use strict'; | ||
var path = require('path'); | ||
var asap = require('asap'); | ||
var lib = require('./lib'); | ||
var Obj = require('./object'); | ||
var lexer = require('./lexer'); | ||
var compiler = require('./compiler'); | ||
@@ -13,3 +13,14 @@ var builtin_filters = require('./filters'); | ||
var Frame = runtime.Frame; | ||
var Template; | ||
// Unconditionally load in this loader, even if no other ones are | ||
// included (possible in the slim browser build) | ||
builtin_loaders.PrecompiledLoader = require('./precompiled-loader'); | ||
// If the user is using the async API, *always* call it | ||
// asynchronously even if the template was synchronous. | ||
function callbackAsap(cb, err, res) { | ||
asap(function() { cb(err, res); }); | ||
} | ||
var Environment = Obj.extend({ | ||
@@ -23,3 +34,3 @@ init: function(loaders, opts) { | ||
// defaults to false | ||
var opts = this.opts = opts || {}; | ||
opts = this.opts = opts || {}; | ||
this.opts.dev = !!opts.dev; | ||
@@ -30,15 +41,19 @@ | ||
// If false, strings can be manually escaped using the `escape` filter. | ||
// defaults to false | ||
this.opts.autoescape = !!opts.autoescape; | ||
// defaults to true | ||
this.opts.autoescape = opts.autoescape != null ? opts.autoescape : true; | ||
// If true, this will make the system throw errors if trying | ||
// to output a null or undefined value | ||
this.opts.throwOnUndefined = !!opts.throwOnUndefined; | ||
this.opts.trimBlocks = !!opts.trimBlocks; | ||
this.opts.lstripBlocks = !!opts.lstripBlocks; | ||
this.loaders = []; | ||
if(!loaders) { | ||
// The filesystem loader is only available client-side | ||
// The filesystem loader is only available server-side | ||
if(builtin_loaders.FileSystemLoader) { | ||
this.loaders = [new builtin_loaders.FileSystemLoader('views')]; | ||
} | ||
else { | ||
else if(builtin_loaders.WebLoader) { | ||
this.loaders = [new builtin_loaders.WebLoader('/views')]; | ||
@@ -51,2 +66,11 @@ } | ||
// It's easy to use precompiled templates: just include them | ||
// before you configure nunjucks and this will automatically | ||
// pick it up and use it | ||
if(process.env.IS_BROWSER && window.nunjucksPrecompiled) { | ||
this.loaders.unshift( | ||
new builtin_loaders.PrecompiledLoader(window.nunjucksPrecompiled) | ||
); | ||
} | ||
this.initCache(); | ||
@@ -90,2 +114,9 @@ this.filters = {}; | ||
getGlobal: function(name) { | ||
if(!globals[name]) { | ||
throw new Error('global not found: ' + name); | ||
} | ||
return globals[name]; | ||
}, | ||
addFilter: function(name, func, async) { | ||
@@ -154,3 +185,31 @@ var wrapped = func; | ||
var syncResult; | ||
var _this = this; | ||
var createTemplate = function(info) { | ||
if(!info) { | ||
var err = new Error('template not found: ' + name); | ||
if(cb) { | ||
cb(err); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
else { | ||
var tmpl = new Template(info.src, _this, | ||
info.path, eagerCompile); | ||
if(!info.noCache) { | ||
info.loader.cache[name] = tmpl; | ||
} | ||
if(cb) { | ||
cb(null, tmpl); | ||
} | ||
else { | ||
syncResult = tmpl; | ||
} | ||
} | ||
}; | ||
lib.asyncIter(this.loaders, function(loader, i, next, done) { | ||
@@ -179,29 +238,4 @@ function handle(src) { | ||
} | ||
}, function(info) { | ||
if(!info) { | ||
var err = new Error('template not found: ' + name); | ||
if(cb) { | ||
cb(err); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
else { | ||
var tmpl = new Template(info.src, this, | ||
info.path, eagerCompile); | ||
}, createTemplate); | ||
if(!info.noCache) { | ||
info.loader.cache[name] = tmpl; | ||
} | ||
if(cb) { | ||
cb(null, tmpl); | ||
} | ||
else { | ||
syncResult = tmpl; | ||
} | ||
} | ||
}.bind(this)); | ||
return syncResult; | ||
@@ -244,3 +278,3 @@ } | ||
if(err && cb) { | ||
cb(err); | ||
callbackAsap(cb, err); | ||
} | ||
@@ -251,6 +285,3 @@ else if(err) { | ||
else { | ||
tmpl.render(ctx, cb || function(err, res) { | ||
if(err) { throw err; } | ||
syncResult = res; | ||
}); | ||
syncResult = tmpl.render(ctx, cb); | ||
} | ||
@@ -276,3 +307,10 @@ }); | ||
init: function(ctx, blocks) { | ||
this.ctx = ctx; | ||
// Make a duplicate of ctx | ||
this.ctx = {}; | ||
for(var k in ctx) { | ||
if(ctx.hasOwnProperty(k)) { | ||
this.ctx[k] = ctx[k]; | ||
} | ||
} | ||
this.blocks = {}; | ||
@@ -344,3 +382,3 @@ this.exported = []; | ||
var Template = Obj.extend({ | ||
Template = Obj.extend({ | ||
init: function (src, env, path, eagerCompile) { | ||
@@ -366,5 +404,9 @@ this.env = env || new Environment(); | ||
if(eagerCompile) { | ||
lib.withPrettyErrors(this.path, | ||
this.env.dev, | ||
this._compile.bind(this)); | ||
var _this = this; | ||
try { | ||
_this._compile(); | ||
} | ||
catch(err) { | ||
throw lib.prettifyError(this.path, this.env.dev, err); | ||
} | ||
} | ||
@@ -376,3 +418,3 @@ else { | ||
render: function(ctx, frame, cb) { | ||
render: function(ctx, parentFrame, cb) { | ||
if (typeof ctx === 'function') { | ||
@@ -382,35 +424,61 @@ cb = ctx; | ||
} | ||
else if (typeof frame === 'function') { | ||
cb = frame; | ||
frame = null; | ||
else if (typeof parentFrame === 'function') { | ||
cb = parentFrame; | ||
parentFrame = null; | ||
} | ||
return lib.withPrettyErrors(this.path, this.env.dev, function() { | ||
var forceAsync = true; | ||
if(parentFrame) { | ||
// If there is a frame, we are being called from internal | ||
// code of another template, and the internal system | ||
// depends on the sync/async nature of the parent template | ||
// to be inherited, so force an async callback | ||
forceAsync = false; | ||
} | ||
// Catch compile errors for async rendering | ||
try { | ||
this.compile(); | ||
} catch (e) { | ||
if (cb) return cb(e); | ||
else throw e; | ||
} | ||
var _this = this; | ||
// Catch compile errors for async rendering | ||
try { | ||
_this.compile(); | ||
} catch (_err) { | ||
var err = lib.prettifyError(this.path, this.env.dev, _err); | ||
if (cb) return callbackAsap(cb, err); | ||
else throw err; | ||
} | ||
var context = new Context(ctx || {}, this.blocks); | ||
var syncResult = null; | ||
var context = new Context(ctx || {}, _this.blocks); | ||
var frame = parentFrame ? parentFrame.push() : new Frame(); | ||
frame.topLevel = true; | ||
var syncResult = null; | ||
this.rootRenderFunc(this.env, | ||
context, | ||
frame || new Frame(), | ||
runtime, | ||
cb || function(err, res) { | ||
if(err) { throw err; } | ||
syncResult = res; | ||
}); | ||
_this.rootRenderFunc( | ||
_this.env, | ||
context, | ||
frame || new Frame(), | ||
runtime, | ||
function(err, res) { | ||
if(err) { | ||
err = lib.prettifyError(_this.path, _this.env.dev, err); | ||
} | ||
return syncResult; | ||
}.bind(this)); | ||
if(cb) { | ||
if(forceAsync) { | ||
callbackAsap(cb, err, res); | ||
} | ||
else { | ||
cb(err, res); | ||
} | ||
} | ||
else { | ||
if(err) { throw err; } | ||
syncResult = res; | ||
} | ||
} | ||
); | ||
return syncResult; | ||
}, | ||
getExported: function(ctx, frame, cb) { | ||
getExported: function(ctx, parentFrame, cb) { | ||
if (typeof ctx === 'function') { | ||
@@ -421,5 +489,5 @@ cb = ctx; | ||
if (typeof frame === 'function') { | ||
cb = frame; | ||
frame = null; | ||
if (typeof parentFrame === 'function') { | ||
cb = parentFrame; | ||
parentFrame = null; | ||
} | ||
@@ -435,2 +503,5 @@ | ||
var frame = parentFrame ? parentFrame.push() : new Frame(); | ||
frame.topLevel = true; | ||
// Run the rootRenderFunc to populate the context with exported vars | ||
@@ -440,3 +511,3 @@ var context = new Context(ctx || {}, this.blocks); | ||
context, | ||
frame || new Frame(), | ||
frame, | ||
runtime, | ||
@@ -467,2 +538,3 @@ function() { | ||
/* jslint evil: true */ | ||
var func = new Function(source); | ||
@@ -490,7 +562,2 @@ props = func(); | ||
// test code | ||
// var src = '{% macro foo() %}{% include "include.html" %}{% endmacro %}{{ foo() }}'; | ||
// var env = new Environment(new builtin_loaders.FileSystemLoader('../tests/templates', true), { dev: true }); | ||
// console.log(env.renderString(src, { name: 'poop' })); | ||
module.exports = { | ||
@@ -497,0 +564,0 @@ Environment: Environment, |
@@ -6,2 +6,11 @@ 'use strict'; | ||
function normalize(value, defaultValue) { | ||
if(value === null || value === undefined || value === false) { | ||
return defaultValue; | ||
} | ||
return value; | ||
} | ||
var hasWarnedDefault = false; | ||
var filters = { | ||
@@ -13,6 +22,7 @@ abs: function(n) { | ||
batch: function(arr, linecount, fill_with) { | ||
var i; | ||
var res = []; | ||
var tmp = []; | ||
for(var i=0; i<arr.length; i++) { | ||
for(i = 0; i < arr.length; i++) { | ||
if(i % linecount === 0 && tmp.length) { | ||
@@ -28,3 +38,3 @@ res.push(tmp); | ||
if(fill_with) { | ||
for(var i=tmp.length; i<linecount; i++) { | ||
for(i = tmp.length; i < linecount; i++) { | ||
tmp.push(fill_with); | ||
@@ -41,2 +51,3 @@ } | ||
capitalize: function(str) { | ||
str = normalize(str, ''); | ||
var ret = str.toLowerCase(); | ||
@@ -47,2 +58,3 @@ return r.copySafeness(str, ret.charAt(0).toUpperCase() + ret.slice(1)); | ||
center: function(str, width) { | ||
str = normalize(str, ''); | ||
width = width || 80; | ||
@@ -60,4 +72,21 @@ | ||
'default': function(val, def) { | ||
return val ? val : def; | ||
'default': function(val, def, bool) { | ||
if(bool !== true && bool !== false && !hasWarnedDefault) { | ||
hasWarnedDefault = true; | ||
console.log( | ||
'[nunjucks] Warning: the "default" filter was used without ' + | ||
'specifying the type of comparison. 2.0 changed the default ' + | ||
'behavior from boolean (val ? val : def) to strictly undefined, ' + | ||
'so you should make sure that doesn\'t break anything. ' + | ||
'Be explicit about this to make this warning go away, or wait until 2.1. ' + | ||
'See http://mozilla.github.io/nunjucks/templating.html#defaultvalue-default-boolean' | ||
); | ||
} | ||
if(bool) { | ||
return val ? val : def; | ||
} | ||
else { | ||
return (val !== undefined) ? val : def; | ||
} | ||
}, | ||
@@ -105,2 +134,6 @@ | ||
dump: function(obj) { | ||
return JSON.stringify(obj); | ||
}, | ||
escape: function(str) { | ||
@@ -127,2 +160,6 @@ if(typeof str === 'string' || | ||
indent: function(str, width, indentfirst) { | ||
str = normalize(str, ''); | ||
if (str === '') return ''; | ||
width = width || 4; | ||
@@ -161,4 +198,6 @@ var res = ''; | ||
length: function(arr) { | ||
return arr !== undefined ? arr.length : 0; | ||
length: function(val) { | ||
var value = normalize(val, ''); | ||
return value !== undefined ? value.length : 0; | ||
}, | ||
@@ -196,2 +235,3 @@ | ||
lower: function(str) { | ||
str = normalize(str, ''); | ||
return str.toLowerCase(); | ||
@@ -217,2 +257,4 @@ }, | ||
replace: function(str, old, new_, maxCount) { | ||
var originalStr = str; | ||
if (old instanceof RegExp) { | ||
@@ -222,18 +264,64 @@ return str.replace(old, new_); | ||
var res = str; | ||
var last = res; | ||
var count = 1; | ||
res = res.replace(old, new_); | ||
if(typeof maxCount === 'undefined'){ | ||
maxCount = -1; | ||
} | ||
while(last !== res) { | ||
if(count >= maxCount) { | ||
break; | ||
} | ||
var res = ''; // Output | ||
last = res; | ||
res = res.replace(old, new_); | ||
// Cast Numbers in the search term to string | ||
if(typeof old === 'number'){ | ||
old = old + ''; | ||
} | ||
else if(typeof old !== 'string') { | ||
// If it is something other than number or string, | ||
// return the original string | ||
return str; | ||
} | ||
// Cast numbers in the replacement to string | ||
if(typeof str === 'number'){ | ||
str = str + ''; | ||
} | ||
// If by now, we don't have a string, throw it back | ||
if(typeof str !== 'string' && !(str instanceof r.SafeString)){ | ||
return str; | ||
} | ||
// ShortCircuits | ||
if(old === ''){ | ||
// Mimic the python behaviour: empty string is replaced | ||
// by replacement e.g. "abc"|replace("", ".") -> .a.b.c. | ||
res = new_ + str.split('').join(new_) + new_; | ||
return r.copySafeness(str, res); | ||
} | ||
var nextIndex = str.indexOf(old); | ||
// if # of replacements to perform is 0, or the string to does | ||
// not contain the old value, return the string | ||
if(maxCount === 0 || nextIndex === -1){ | ||
return str; | ||
} | ||
var pos = 0; | ||
var count = 0; // # of replacements made | ||
while(nextIndex > -1 && (maxCount === -1 || count < maxCount)){ | ||
// Grab the next chunk of src string and add it with the | ||
// replacement, to the result | ||
res += str.substring(pos, nextIndex) + new_; | ||
// Increment our pointer in the src string | ||
pos = nextIndex + old.length; | ||
count++; | ||
// See if there are any more replacements to be made | ||
nextIndex = str.indexOf(old, pos); | ||
} | ||
return r.copySafeness(str, res); | ||
// We've either reached the end, or done the max # of | ||
// replacements, tack on any remaining string | ||
if(pos < str.length) { | ||
res += str.substring(pos); | ||
} | ||
return r.copySafeness(originalStr, res); | ||
}, | ||
@@ -340,2 +428,3 @@ | ||
title: function(str) { | ||
str = normalize(str, ''); | ||
var words = str.split(' '); | ||
@@ -354,2 +443,3 @@ for(var i = 0; i < words.length; i++) { | ||
var orig = input; | ||
input = normalize(input, ''); | ||
length = length || 255; | ||
@@ -376,2 +466,3 @@ | ||
upper: function(str) { | ||
str = normalize(str, ''); | ||
return str.toUpperCase(); | ||
@@ -389,3 +480,3 @@ }, | ||
return enc(item[0]) + '=' + enc(item[1]); | ||
}) | ||
}); | ||
} else { | ||
@@ -423,7 +514,4 @@ parts = []; | ||
var matches = word.match(puncRE); | ||
var possibleUrl = matches && matches[1] || word; | ||
// url that starts with http or https | ||
@@ -453,2 +541,3 @@ if (httpHttpsRE.test(possibleUrl)) | ||
wordcount: function(str) { | ||
str = normalize(str, ''); | ||
var words = (str) ? str.match(/\w+/g) : null; | ||
@@ -455,0 +544,0 @@ return (words) ? words.length : null; |
@@ -65,4 +65,4 @@ 'use strict'; | ||
} | ||
} | ||
}; | ||
module.exports = globals; |
@@ -6,3 +6,3 @@ 'use strict'; | ||
var whitespaceChars = ' \n\t\r\u00A0'; | ||
var delimChars = '()[]{}%*-+/#,:|.<>=!'; | ||
var delimChars = '()[]{}%*-+~/#,:|.<>=!'; | ||
var intChars = '0123456789'; | ||
@@ -34,2 +34,3 @@ | ||
var TOKEN_COLON = 'colon'; | ||
var TOKEN_TILDE = 'tilde'; | ||
var TOKEN_PIPE = 'pipe'; | ||
@@ -174,2 +175,3 @@ var TOKEN_INT = 'int'; | ||
case ':': type = TOKEN_COLON; break; | ||
case '~': type = TOKEN_TILDE; break; | ||
case '|': type = TOKEN_PIPE; break; | ||
@@ -301,4 +303,2 @@ default: type = TOKEN_OPERATOR; | ||
var lineno = this.lineno; | ||
var colno = this.colno; | ||
var str = ''; | ||
@@ -394,2 +394,14 @@ | ||
Tokenizer.prototype._extractRegex = function(regex) { | ||
var matches = this.currentStr().match(regex); | ||
if(!matches) { | ||
return null; | ||
} | ||
// Move forward whatever was matched | ||
this.forwardN(matches[0].length); | ||
return matches; | ||
}; | ||
Tokenizer.prototype.is_finished = function() { | ||
@@ -417,2 +429,8 @@ return this.index >= this.len; | ||
Tokenizer.prototype.backN = function(n) { | ||
for(var i=0; i<n; i++) { | ||
this.back(); | ||
} | ||
}; | ||
Tokenizer.prototype.back = function() { | ||
@@ -437,2 +455,3 @@ this.index--; | ||
// current returns current character | ||
Tokenizer.prototype.current = function() { | ||
@@ -445,2 +464,10 @@ if(!this.is_finished()) { | ||
// currentStr returns what's left of the unparsed string | ||
Tokenizer.prototype.currentStr = function() { | ||
if(!this.is_finished()) { | ||
return this.str.substr(this.index); | ||
} | ||
return ''; | ||
}; | ||
Tokenizer.prototype.previous = function() { | ||
@@ -472,2 +499,3 @@ return this.str.charAt(this.index-1); | ||
TOKEN_COLON: TOKEN_COLON, | ||
TOKEN_TILDE: TOKEN_TILDE, | ||
TOKEN_PIPE: TOKEN_PIPE, | ||
@@ -474,0 +502,0 @@ TOKEN_INT: TOKEN_INT, |
@@ -22,21 +22,19 @@ 'use strict'; | ||
exports.withPrettyErrors = function(path, withInternals, func) { | ||
try { | ||
return func(); | ||
} catch (e) { | ||
if (!e.Update) { | ||
// not one of ours, cast it | ||
e = new exports.TemplateError(e); | ||
} | ||
e.Update(path); | ||
exports.prettifyError = function(path, withInternals, err) { | ||
// jshint -W022 | ||
// http://jslinterrors.com/do-not-assign-to-the-exception-parameter | ||
if (!err.Update) { | ||
// not one of ours, cast it | ||
err = new exports.TemplateError(err); | ||
} | ||
err.Update(path); | ||
// Unless they marked the dev flag, show them a trace from here | ||
if (!withInternals) { | ||
var old = e; | ||
e = new Error(old.message); | ||
e.name = old.name; | ||
} | ||
// Unless they marked the dev flag, show them a trace from here | ||
if (!withInternals) { | ||
var old = err; | ||
err = new Error(old.message); | ||
err.name = old.name; | ||
} | ||
throw e; | ||
} | ||
return err; | ||
}; | ||
@@ -280,2 +278,2 @@ | ||
} | ||
} | ||
}; |
@@ -1,6 +0,3 @@ | ||
if(typeof window === 'undefined' || window !== this) { | ||
module.exports = require('./node-loaders'); | ||
} | ||
else { | ||
module.exports = require('./web-loaders'); | ||
} | ||
// This file will automatically be rewired to web-loader.js when | ||
// building for the browser | ||
module.exports = require('./node-loaders'); |
@@ -8,2 +8,3 @@ 'use strict'; | ||
var chokidar = require('chokidar'); | ||
var PrecompiledLoader = require('./precompiled-loader.js'); | ||
@@ -14,5 +15,14 @@ // Node <0.7.1 compatibility | ||
var FileSystemLoader = Loader.extend({ | ||
init: function(searchPaths, noWatch, noCache) { | ||
init: function(searchPaths, opts) { | ||
if(typeof opts === 'boolean') { | ||
console.log( | ||
'[nunjucks] Warning: you passed a boolean as the second ' + | ||
'argument to FileSystemLoader, but it now takes an options ' + | ||
'object. See http://mozilla.github.io/nunjucks/api.html#filesystemloader' | ||
); | ||
} | ||
opts = opts || {}; | ||
this.pathsToNames = {}; | ||
this.noCache = !!noCache; | ||
this.noCache = !!opts.noCache; | ||
@@ -28,6 +38,7 @@ if(searchPaths) { | ||
if(!noWatch) { | ||
if(opts.watch) { | ||
var _this = this; | ||
// Watch all the templates in the paths and fire an event when | ||
// they change | ||
lib.each(this.searchPaths, function(p) { | ||
lib.each(_this.searchPaths, function(p) { | ||
if(existsSync(p)) { | ||
@@ -38,8 +49,8 @@ var watcher = chokidar.watch(p); | ||
fullname = path.resolve(fullname); | ||
if(event === 'change' && fullname in this.pathsToNames) { | ||
this.emit('update', this.pathsToNames[fullname]); | ||
if(event === 'change' && fullname in _this.pathsToNames) { | ||
_this.emit('update', _this.pathsToNames[fullname]); | ||
} | ||
}.bind(this)); | ||
}); | ||
} | ||
}.bind(this)); | ||
}); | ||
} | ||
@@ -76,5 +87,5 @@ }, | ||
module.exports = { | ||
FileSystemLoader: FileSystemLoader | ||
FileSystemLoader: FileSystemLoader, | ||
PrecompiledLoader: PrecompiledLoader | ||
}; |
'use strict'; | ||
var util = require('util'); | ||
var lib = require('./lib'); | ||
// jshint -W079 | ||
var Object = require('./object'); | ||
@@ -23,3 +23,3 @@ | ||
var fields = this.fields; | ||
for(var i=0, l=fields.length; i<l; i++) { | ||
for(var i = 0, l = fields.length; i < l; i++) { | ||
var field = fields[i]; | ||
@@ -43,6 +43,7 @@ | ||
var i, l; | ||
if(this instanceof NodeList) { | ||
var children = this.children; | ||
for(var i=0, l=children.length; i<l; i++) { | ||
for(i = 0, l = children.length; i < l; i++) { | ||
traverseAndCheck(children[i], type, results); | ||
@@ -54,3 +55,3 @@ } | ||
for(var i=0, l=fields.length; i<l; i++) { | ||
for(i = 0, l = fields.length; i < l; i++) { | ||
traverseAndCheck(this[fields[i]], type, results); | ||
@@ -133,2 +134,3 @@ } | ||
var Add = BinOp.extend('Add'); | ||
var Concat = BinOp.extend('Concat'); | ||
var Sub = BinOp.extend('Sub'); | ||
@@ -147,10 +149,2 @@ var Mul = BinOp.extend('Mul'); | ||
var CustomTag = Node.extend('CustomTag', { | ||
init: function(lineno, colno, name) { | ||
this.lineno = lineno; | ||
this.colno = colno; | ||
this.name = name; | ||
} | ||
}); | ||
var CallExtension = Node.extend('CallExtension', { | ||
@@ -182,3 +176,3 @@ fields: ['extName', 'prop', 'args', 'contentArgs'], | ||
for(var j=0; j<indent; j++) { | ||
util.print(' '); | ||
process.stdout.write(' '); | ||
} | ||
@@ -189,6 +183,6 @@ } | ||
if(i === lines.length-1) { | ||
util.print(lines[i]); | ||
process.stdout.write(lines[i]); | ||
} | ||
else { | ||
util.puts(lines[i]); | ||
process.stdout.write(lines[i] + '\n'); | ||
} | ||
@@ -236,3 +230,3 @@ } | ||
if(props) { | ||
print(util.inspect(props, true, null) + '\n', null, true); | ||
print(JSON.stringify(props, null, 2) + '\n', null, true); | ||
} | ||
@@ -299,2 +293,3 @@ else { | ||
Add: Add, | ||
Concat: Concat, | ||
Sub: Sub, | ||
@@ -301,0 +296,0 @@ Mul: Mul, |
@@ -11,2 +11,3 @@ 'use strict'; | ||
// jshint undef: false | ||
var fnTest = /xyz/.test(function(){ xyz; }) ? /\bparent\b/ : /.*/; | ||
@@ -22,2 +23,3 @@ props = props || {}; | ||
fnTest.test(src)) { | ||
/*jshint -W083 */ | ||
prototype[k] = (function (src, parent) { | ||
@@ -24,0 +26,0 @@ return function() { |
@@ -5,2 +5,3 @@ 'use strict'; | ||
var nodes = require('./nodes'); | ||
// jshint -W079 | ||
var Object = require('./object'); | ||
@@ -96,6 +97,2 @@ var lib = require('./lib'); | ||
skipWhitespace: function () { | ||
return this.skip(lexer.TOKEN_WHITESPACE); | ||
}, | ||
skipSymbol: function(val) { | ||
@@ -106,4 +103,5 @@ return this.skipValue(lexer.TOKEN_SYMBOL, val); | ||
advanceAfterBlockEnd: function(name) { | ||
var tok; | ||
if(!name) { | ||
var tok = this.peekToken(); | ||
tok = this.peekToken(); | ||
@@ -122,3 +120,3 @@ if(!tok) { | ||
var tok = this.nextToken(); | ||
tok = this.nextToken(); | ||
@@ -133,2 +131,4 @@ if(tok && tok.type === lexer.TOKEN_BLOCK_END) { | ||
} | ||
return tok; | ||
}, | ||
@@ -417,3 +417,3 @@ | ||
parseTemplateRef: function(tagName, nodeType) { | ||
parseTemplateRef: function(tagName, NodeType) { | ||
var tag = this.peekToken(); | ||
@@ -424,3 +424,3 @@ if(!this.skipSymbol(tagName)) { | ||
var node = new nodeType(tag.lineno, tag.colno); | ||
var node = new NodeType(tag.lineno, tag.colno); | ||
node.template = this.parseExpression(); | ||
@@ -542,2 +542,3 @@ | ||
case 'from': return this.parseFrom(); | ||
case 'filter': return this.parseFilterStatement(); | ||
default: | ||
@@ -559,50 +560,38 @@ if (this.extensions.length) { | ||
parseRaw: function() { | ||
this.advanceAfterBlockEnd(); | ||
var blockRegex = /([\s\S]*){%\s*(.*?)\s*(?=%})%}/; | ||
var rawLevel = 1; | ||
var str = ''; | ||
var begun = this.peekToken(); | ||
var matches = null; | ||
while(1) { | ||
// Passing true gives us all the whitespace tokens as | ||
// well, which are usually ignored. | ||
var tok = this.nextToken(true); | ||
// Skip opening raw token | ||
// Keep this token to track line and column numbers | ||
var begun = this.advanceAfterBlockEnd(); | ||
if(!tok) { | ||
this.fail('expected endraw, got end of file'); | ||
} | ||
// Exit when there's nothing to match | ||
// or when we've found the matching "endraw" block | ||
while((matches = this.tokens._extractRegex(blockRegex)) && rawLevel > 0) { | ||
var all = matches[0]; | ||
var pre = matches[1]; | ||
var blockName = matches[2]; | ||
if(tok.type === lexer.TOKEN_BLOCK_START) { | ||
// We need to look for the `endraw` block statement, | ||
// which involves a lookahead so carefully keep track | ||
// of whitespace | ||
var ws = null; | ||
var name = this.nextToken(true); | ||
// Adjust rawlevel | ||
if(blockName === 'raw') { | ||
if(name.type === lexer.TOKEN_WHITESPACE) { | ||
ws = name; | ||
name = this.nextToken(); | ||
} | ||
rawLevel += 1; | ||
} else if(blockName === 'endraw') { | ||
rawLevel -= 1; | ||
} | ||
if(name.type === lexer.TOKEN_SYMBOL && | ||
name.value === 'endraw') { | ||
this.advanceAfterBlockEnd(name.value); | ||
break; | ||
} | ||
else { | ||
str += tok.value; | ||
if(ws) { | ||
str += ws.value; | ||
} | ||
str += name.value; | ||
} | ||
// Add to str | ||
if(rawLevel === 0) { | ||
// We want to exclude the last "endraw" | ||
str += pre; | ||
// Move tokenizer to beginning of endraw block | ||
this.tokens.backN(all.length - pre.length); | ||
} else { | ||
str += all; | ||
} | ||
else if(tok.type === lexer.TOKEN_STRING) { | ||
str += '"' + tok.value + '"'; | ||
} | ||
else { | ||
str += tok.value; | ||
} | ||
} | ||
var output = new nodes.Output( | ||
return new nodes.Output( | ||
begun.lineno, | ||
@@ -612,8 +601,6 @@ begun.colno, | ||
); | ||
return output; | ||
}, | ||
parsePostfix: function(node) { | ||
var tok = this.peekToken(); | ||
var lookup, tok = this.peekToken(); | ||
@@ -630,3 +617,3 @@ while(tok) { | ||
// Reference | ||
var lookup = this.parseAggregate(); | ||
lookup = this.parseAggregate(); | ||
if(lookup.children.length > 1) { | ||
@@ -654,3 +641,3 @@ this.fail('invalid index'); | ||
// reference | ||
var lookup = new nodes.Literal(val.lineno, | ||
lookup = new nodes.Literal(val.lineno, | ||
val.colno, | ||
@@ -763,3 +750,3 @@ val.value); | ||
var compareOps = ['==', '!=', '<', '>', '<=', '>=']; | ||
var expr = this.parseAdd(); | ||
var expr = this.parseConcat(); | ||
var ops = []; | ||
@@ -776,3 +763,3 @@ | ||
tok.colno, | ||
this.parseAdd(), | ||
this.parseConcat(), | ||
tok.value)); | ||
@@ -797,2 +784,15 @@ } | ||
// finds the '~' for string concatenation | ||
parseConcat: function(){ | ||
var node = this.parseAdd(); | ||
while(this.skipValue(lexer.TOKEN_TILDE, '~')) { | ||
var node2 = this.parseAdd(); | ||
node = new nodes.Concat(node.lineno, | ||
node.colno, | ||
node, | ||
node2); | ||
} | ||
return node; | ||
}, | ||
parseAdd: function() { | ||
@@ -968,29 +968,37 @@ var node = this.parseSub(); | ||
parseFilterName: function() { | ||
var tok = this.expect(lexer.TOKEN_SYMBOL); | ||
var name = tok.value; | ||
while(this.skipValue(lexer.TOKEN_OPERATOR, '.')) { | ||
name += '.' + this.expect(lexer.TOKEN_SYMBOL).value; | ||
} | ||
return new nodes.Symbol(tok.lineno, tok.colno, name); | ||
}, | ||
parseFilterArgs: function(node) { | ||
if(this.peekToken().type === lexer.TOKEN_LEFT_PAREN) { | ||
// Get a FunCall node and add the parameters to the | ||
// filter | ||
var call = this.parsePostfix(node); | ||
return call.args.children; | ||
} | ||
return []; | ||
}, | ||
parseFilter: function(node) { | ||
while(this.skip(lexer.TOKEN_PIPE)) { | ||
var tok = this.expect(lexer.TOKEN_SYMBOL); | ||
var name = tok.value; | ||
var name = this.parseFilterName(); | ||
while(this.skipValue(lexer.TOKEN_OPERATOR, '.')) { | ||
name += '.' + this.expect(lexer.TOKEN_SYMBOL).value; | ||
} | ||
node = new nodes.Filter( | ||
tok.lineno, | ||
tok.colno, | ||
new nodes.Symbol(tok.lineno, | ||
tok.colno, | ||
name), | ||
name.lineno, | ||
name.colno, | ||
name, | ||
new nodes.NodeList( | ||
tok.lineno, | ||
tok.colno, | ||
[node]) | ||
name.lineno, | ||
name.colno, | ||
[node].concat(this.parseFilterArgs(node)) | ||
) | ||
); | ||
if(this.peekToken().type === lexer.TOKEN_LEFT_PAREN) { | ||
// Get a FunCall node and add the parameters to the | ||
// filter | ||
var call = this.parsePostfix(node); | ||
node.args.children = node.args.children.concat(call.args.children); | ||
} | ||
} | ||
@@ -1001,2 +1009,35 @@ | ||
parseFilterStatement: function() { | ||
var filterTok = this.peekToken(); | ||
if(!this.skipSymbol('filter')) { | ||
this.fail('parseFilterStatement: expected filter'); | ||
} | ||
var name = this.parseFilterName(); | ||
var args = this.parseFilterArgs(name); | ||
this.advanceAfterBlockEnd(filterTok.value); | ||
var body = this.parseUntilBlocks('endfilter'); | ||
this.advanceAfterBlockEnd(); | ||
var node = new nodes.Filter( | ||
name.lineno, | ||
name.colno, | ||
name, | ||
new nodes.NodeList( | ||
name.lineno, | ||
name.colno, | ||
// Body is a NodeList with an Output node as a child, | ||
// need to strip those | ||
body.children[0].children.concat(args) | ||
) | ||
); | ||
return new nodes.Output( | ||
name.lineno, | ||
name.colno, | ||
[node] | ||
); | ||
}, | ||
parseAggregate: function() { | ||
@@ -1080,3 +1121,2 @@ var tok = this.nextToken(); | ||
var kwargs = new nodes.KeywordArgs(tok.lineno, tok.colno); | ||
var kwnames = []; | ||
var checkComma = false; | ||
@@ -1207,3 +1247,5 @@ | ||
// var p = new Parser(lexer.lex('{% if not x %}foo{% endif %}')); | ||
// var p = new Parser(lexer.lex('hello {% filter title %}' + | ||
// 'Hello madam how are you' + | ||
// '{% endfilter %}')); | ||
// var n = p.parseAsRoot(); | ||
@@ -1210,0 +1252,0 @@ // nodes.printNodes(n); |
@@ -8,2 +8,3 @@ 'use strict'; | ||
var Environment = require('./environment').Environment; | ||
var precompileGlobal = require('./precompile-global'); | ||
@@ -33,10 +34,13 @@ function match(filename, patterns) { | ||
// * exclude: which file/folders to exclude (folders are auto-included, files are auto-excluded) | ||
// * wrapper: function(name, template, opts) {...} | ||
// Customize the output format to store the compiled template. | ||
// By default, templates are stored in a global variable used by the runtime. | ||
// A custom loader will be necessary to load your custom wrapper. | ||
opts = opts || {}; | ||
var env = opts.env || new Environment([]); | ||
var asyncFilters = env.asyncFilters; | ||
var extensions = env.extensionsList; | ||
var wrapper = opts.wrapper || precompileGlobal; | ||
var pathStats = fs.existsSync(input) && fs.statSync(input); | ||
var output = ''; | ||
var precompiled = []; | ||
var templates = []; | ||
@@ -70,12 +74,14 @@ | ||
return _precompile(input, | ||
opts.name, | ||
env, | ||
opts.asFunction); | ||
precompiled.push( _precompile( | ||
input, | ||
opts.name, | ||
env | ||
) ); | ||
} | ||
else if(pathStats.isFile()) { | ||
return _precompile(fs.readFileSync(input, 'utf-8'), | ||
opts.name || input, | ||
env, | ||
opts.asFunction); | ||
precompiled.push( _precompile( | ||
fs.readFileSync(input, 'utf-8'), | ||
opts.name || input, | ||
env | ||
) ); | ||
} | ||
@@ -89,6 +95,7 @@ else if(pathStats.isDirectory()) { | ||
try { | ||
output += _precompile(fs.readFileSync(templates[i], 'utf-8'), | ||
name, | ||
env, | ||
opts.asFunction); | ||
precompiled.push( _precompile( | ||
fs.readFileSync(templates[i], 'utf-8'), | ||
name, | ||
env | ||
) ); | ||
} catch(e) { | ||
@@ -105,8 +112,8 @@ if(opts.force) { | ||
} | ||
} | ||
return output; | ||
} | ||
return wrapper(precompiled, opts); | ||
} | ||
function _precompile(str, name, env, asFunction) { | ||
function _precompile(str, name, env) { | ||
env = env || new Environment([]); | ||
@@ -116,25 +123,16 @@ | ||
var extensions = env.extensionsList; | ||
var template; | ||
var out = '(function() {' + | ||
'(window.nunjucksPrecompiled = window.nunjucksPrecompiled || {})' + | ||
'["' + name.replace(/\\/g, '/') + '"] = (function() {'; | ||
out += lib.withPrettyErrors( | ||
name, | ||
false, | ||
function() { | ||
return compiler.compile(str, | ||
try { | ||
template = compiler.compile(str, | ||
asyncFilters, | ||
extensions, | ||
name); | ||
} | ||
); | ||
out += '})();\n'; | ||
if(asFunction) { | ||
out += 'return function(ctx, cb) { return nunjucks.render("' + name + '", ctx, cb); }'; | ||
name, | ||
env.opts); | ||
} | ||
catch(err) { | ||
throw lib.prettifyError(name, false, err); | ||
} | ||
out += '})();\n'; | ||
return out; | ||
return { name: name, template: template }; | ||
} | ||
@@ -145,2 +143,2 @@ | ||
precompileString: precompileString | ||
} | ||
}; |
@@ -13,2 +13,3 @@ 'use strict'; | ||
this.parent = parent; | ||
this.topLevel = false; | ||
}, | ||
@@ -83,2 +84,3 @@ | ||
var kwargs = getKeywordArgs(arguments); | ||
var i; | ||
@@ -91,3 +93,3 @@ if(argCount > argNames.length) { | ||
var vals = Array.prototype.slice.call(arguments, args.length, argCount); | ||
for(var i=0; i<vals.length; i++) { | ||
for(i = 0; i < vals.length; i++) { | ||
if(i < kwargNames.length) { | ||
@@ -103,3 +105,3 @@ kwargs[kwargNames[i]] = vals[i]; | ||
for(var i=argCount; i<argNames.length; i++) { | ||
for(i = argCount; i < argNames.length; i++) { | ||
var arg = argNames[i]; | ||
@@ -164,5 +166,8 @@ | ||
this.val = val; | ||
this.length = val.length; | ||
} | ||
SafeString.prototype = Object.create(String.prototype); | ||
SafeString.prototype = Object.create(String.prototype, { | ||
length: { writable: true, configurable: true, value: 0 } | ||
}); | ||
SafeString.prototype.valueOf = function() { | ||
@@ -214,2 +219,13 @@ return this.val; | ||
function ensureDefined(val, lineno, colno) { | ||
if(val === null || val === undefined) { | ||
throw new lib.TemplateError( | ||
'attempted to output null or undefined value', | ||
lineno + 1, | ||
colno + 1 | ||
); | ||
} | ||
return val; | ||
} | ||
function memberLookup(obj, val) { | ||
@@ -227,3 +243,3 @@ obj = obj || {}; | ||
function callWrap(obj, name, args) { | ||
function callWrap(obj, name, context, args) { | ||
if(!obj) { | ||
@@ -236,3 +252,4 @@ throw new Error('Unable to call `' + name + '`, which is undefined or falsey'); | ||
return obj.apply(this, args); | ||
// jshint validthis: true | ||
return obj.apply(context, args); | ||
} | ||
@@ -280,3 +297,3 @@ | ||
var finished = 0; | ||
var len; | ||
var len, i; | ||
var outputArr; | ||
@@ -301,3 +318,3 @@ | ||
else { | ||
for(var i=0; i<arr.length; i++) { | ||
for(i = 0; i < arr.length; i++) { | ||
var item = arr[i]; | ||
@@ -311,2 +328,3 @@ | ||
item.push(i, done); | ||
// jshint validthis: true | ||
func.apply(this, item); | ||
@@ -326,3 +344,3 @@ } | ||
else { | ||
for(var i=0; i<keys.length; i++) { | ||
for(i = 0; i < keys.length; i++) { | ||
var k = keys[i]; | ||
@@ -341,2 +359,3 @@ func(k, arr[k], i, len, done); | ||
suppressValue: suppressValue, | ||
ensureDefined: ensureDefined, | ||
memberLookup: memberLookup, | ||
@@ -343,0 +362,0 @@ contextOrFrameLookup: contextOrFrameLookup, |
@@ -140,2 +140,5 @@ 'use strict'; | ||
} | ||
else if(node instanceof nodes.Set) { | ||
return _liftFilters(node, asyncFilters, 'value'); | ||
} | ||
else if(node instanceof nodes.For) { | ||
@@ -191,3 +194,4 @@ return _liftFilters(node, asyncFilters, 'arr'); | ||
node instanceof nodes.AsyncAll || | ||
node instanceof nodes.CallExtensionAsync) { | ||
node instanceof nodes.CallExtensionAsync || | ||
node instanceof nodes.Include) { | ||
async = true; | ||
@@ -227,3 +231,3 @@ // Stop iterating by returning the node | ||
function transform(ast, asyncFilters, name) { | ||
function transform(ast, asyncFilters) { | ||
return cps(ast, asyncFilters || []); | ||
@@ -230,0 +234,0 @@ } |
'use strict'; | ||
var Loader = require('./loader'); | ||
var PrecompiledLoader = require('./precompiled-loader.js'); | ||
var WebLoader = Loader.extend({ | ||
init: function(baseURL, neverUpdate) { | ||
// It's easy to use precompiled templates: just include them | ||
// before you configure nunjucks and this will automatically | ||
// pick it up and use it | ||
this.precompiled = window.nunjucksPrecompiled || {}; | ||
init: function(baseURL, opts) { | ||
this.baseURL = baseURL || '.'; | ||
this.baseURL = baseURL || ''; | ||
this.neverUpdate = neverUpdate; | ||
// By default, the cache is turned off because there's no way | ||
// to "watch" templates over HTTP, so they are re-downloaded | ||
// and compiled each time. (Remember, PRECOMPILE YOUR | ||
// TEMPLATES in production!) | ||
this.useCache = opts.useCache; | ||
// We default `async` to false so that the simple synchronous | ||
// API can be used when you aren't doing anything async in | ||
// your templates (which is most of the time). This performs a | ||
// sync ajax request, but that's ok because it should *only* | ||
// happen in development. PRECOMPILE YOUR TEMPLATES. | ||
this.async = opts.async; | ||
}, | ||
getSource: function(name) { | ||
if(this.precompiled[name]) { | ||
return { | ||
src: { type: 'code', | ||
obj: this.precompiled[name] }, | ||
path: name | ||
}; | ||
} | ||
else { | ||
var src = this.fetch(this.baseURL + '/' + name); | ||
if(!src) { | ||
return null; | ||
resolve: function(from, to) { // jshint ignore:line | ||
throw new Error('relative templates not support in the browser yet'); | ||
}, | ||
getSource: function(name, cb) { | ||
var useCache = this.useCache; | ||
var result; | ||
this.fetch(this.baseURL + '/' + name, function(err, src) { | ||
if(err) { | ||
if(!cb) { | ||
throw err; | ||
} | ||
cb(err); | ||
} | ||
else { | ||
result = { src: src, | ||
path: name, | ||
noCache: !useCache }; | ||
if(cb) { | ||
cb(null, result); | ||
} | ||
} | ||
}); | ||
return { src: src, | ||
path: name, | ||
noCache: !this.neverUpdate }; | ||
} | ||
// if this WebLoader isn't running asynchronously, the | ||
// fetch above would actually run sync and we'll have a | ||
// result here | ||
return result; | ||
}, | ||
fetch: function(url, callback) { | ||
fetch: function(url, cb) { | ||
// Only in the browser please | ||
var ajax; | ||
var loading = true; | ||
var src; | ||
@@ -46,2 +63,3 @@ if(window.XMLHttpRequest) { // Mozilla, Safari, ... | ||
else if(window.ActiveXObject) { // IE 8 and older | ||
/* global ActiveXObject */ | ||
ajax = new ActiveXObject('Microsoft.XMLHTTP'); | ||
@@ -51,5 +69,10 @@ } | ||
ajax.onreadystatechange = function() { | ||
if(ajax.readyState === 4 && (ajax.status === 0 || ajax.status === 200) && loading) { | ||
if(ajax.readyState === 4 && loading) { | ||
loading = false; | ||
src = ajax.responseText; | ||
if(ajax.status === 0 || ajax.status === 200) { | ||
cb(null, ajax.responseText); | ||
} | ||
else { | ||
cb(ajax.responseText); | ||
} | ||
} | ||
@@ -61,8 +84,4 @@ }; | ||
// Synchronous because this API shouldn't be used in | ||
// production (pre-load compiled templates instead) | ||
ajax.open('GET', url, false); | ||
ajax.open('GET', url, this.async); | ||
ajax.send(); | ||
return src; | ||
} | ||
@@ -72,3 +91,4 @@ }); | ||
module.exports = { | ||
WebLoader: WebLoader | ||
WebLoader: WebLoader, | ||
PrecompiledLoader: PrecompiledLoader | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
531192
40
0
12650
36
1
3
9
4
+ Addedasap@^2.0.3
+ Addedanymatch@1.3.2(transitive)
+ Addedarr-diff@2.0.04.0.0(transitive)
+ Addedarr-flatten@1.1.0(transitive)
+ Addedarr-union@3.1.0(transitive)
+ Addedarray-unique@0.2.10.3.2(transitive)
+ Addedasap@2.0.6(transitive)
+ Addedassign-symbols@1.0.0(transitive)
+ Addedasync-each@1.0.6(transitive)
+ Addedatob@2.1.2(transitive)
+ Addedbase@0.11.2(transitive)
+ Addedbinary-extensions@1.13.1(transitive)
+ Addedbindings@1.5.0(transitive)
+ Addedbraces@1.8.52.3.2(transitive)
+ Addedcache-base@1.0.1(transitive)
+ Addedchokidar@1.7.0(transitive)
+ Addedclass-utils@0.3.6(transitive)
+ Addedcollection-visit@1.0.0(transitive)
+ Addedcomponent-emitter@1.3.1(transitive)
+ Addedcopy-descriptor@0.1.1(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addeddecode-uri-component@0.2.2(transitive)
+ Addeddefine-property@0.2.51.0.02.0.2(transitive)
+ Addedexpand-brackets@0.1.52.1.4(transitive)
+ Addedexpand-range@1.8.2(transitive)
+ Addedextend-shallow@2.0.13.0.2(transitive)
+ Addedextglob@0.3.22.0.4(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addedfilename-regex@2.0.1(transitive)
+ Addedfill-range@2.2.44.0.0(transitive)
+ Addedfor-in@1.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedfragment-cache@0.2.1(transitive)
+ Addedfsevents@1.2.13(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-value@2.0.6(transitive)
+ Addedglob-base@0.3.0(transitive)
+ Addedglob-parent@2.0.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhas-value@0.3.11.0.0(transitive)
+ Addedhas-values@0.1.41.0.0(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedis-accessor-descriptor@1.0.1(transitive)
+ Addedis-binary-path@1.0.1(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-data-descriptor@1.0.1(transitive)
+ Addedis-descriptor@0.1.71.0.3(transitive)
+ Addedis-dotfile@1.0.3(transitive)
+ Addedis-equal-shallow@0.1.3(transitive)
+ Addedis-extendable@0.1.11.0.1(transitive)
+ Addedis-extglob@1.0.0(transitive)
+ Addedis-glob@2.0.1(transitive)
+ Addedis-number@2.1.03.0.04.0.0(transitive)
+ Addedis-plain-object@2.0.4(transitive)
+ Addedis-posix-bracket@0.1.1(transitive)
+ Addedis-primitive@2.0.0(transitive)
+ Addedis-windows@1.0.2(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisobject@2.1.03.0.1(transitive)
+ Addedkind-of@3.2.24.0.06.0.3(transitive)
+ Addedmap-cache@0.2.2(transitive)
+ Addedmap-visit@1.0.0(transitive)
+ Addedmath-random@1.0.4(transitive)
+ Addedmicromatch@2.3.113.1.10(transitive)
+ Addedmixin-deep@1.3.2(transitive)
+ Addedms@2.0.0(transitive)
+ Addednanomatch@1.2.13(transitive)
+ Addednormalize-path@2.1.1(transitive)
+ Addedobject-copy@0.1.0(transitive)
+ Addedobject-visit@1.0.1(transitive)
+ Addedobject.omit@2.0.1(transitive)
+ Addedobject.pick@1.3.0(transitive)
+ Addedparse-glob@3.0.4(transitive)
+ Addedpascalcase@0.1.1(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedposix-character-classes@0.1.1(transitive)
+ Addedpreserve@0.2.0(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedrandomatic@3.1.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedreaddirp@2.2.1(transitive)
+ Addedregex-cache@0.4.4(transitive)
+ Addedregex-not@1.0.2(transitive)
+ Addedremove-trailing-separator@1.1.0(transitive)
+ Addedrepeat-element@1.1.4(transitive)
+ Addedrepeat-string@1.6.1(transitive)
+ Addedresolve-url@0.2.1(transitive)
+ Addedret@0.1.15(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedsafe-regex@1.1.0(transitive)
+ Addedset-value@2.0.1(transitive)
+ Addedsnapdragon@0.8.2(transitive)
+ Addedsnapdragon-node@2.1.1(transitive)
+ Addedsnapdragon-util@3.0.1(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addedsource-map-resolve@0.5.3(transitive)
+ Addedsource-map-url@0.4.1(transitive)
+ Addedsplit-string@3.1.0(transitive)
+ Addedstatic-extend@0.1.2(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedto-object-path@0.3.0(transitive)
+ Addedto-regex@3.0.2(transitive)
+ Addedto-regex-range@2.1.1(transitive)
+ Addedunion-value@1.0.1(transitive)
+ Addedunset-value@1.0.0(transitive)
+ Addedurix@0.1.0(transitive)
+ Addeduse@3.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
- Removedasync-each@0.1.6(transitive)
- Removedchokidar@0.12.6(transitive)
- Removedfsevents@0.3.8(transitive)
- Removedgraceful-fs@2.0.3(transitive)
- Removedisarray@0.0.1(transitive)
- Removedlru-cache@2.7.3(transitive)
- Removedminimatch@0.2.14(transitive)
- Removedreadable-stream@1.0.34(transitive)
- Removedreaddirp@1.3.0(transitive)
- Removedsigmund@1.0.1(transitive)
- Removedstring_decoder@0.10.31(transitive)
Updatedchokidar@^1.0.0