jade-js-source 0.19.0 → 0.27.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/jade_js/jade.js +722 -194
 - data/lib/jade_js/runtime.js +64 -8
 - metadata +3 -3
 
    
        data/lib/jade_js/jade.js
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            (function() {
         
     | 
| 
       1 
2 
     | 
    
         | 
| 
       2 
3 
     | 
    
         
             
            // CommonJS require()
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
         @@ -29,7 +30,7 @@ require.register = function (path, fn){ 
     | 
|
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
            require.relative = function (parent) {
         
     | 
| 
       31 
32 
     | 
    
         
             
                return function(p){
         
     | 
| 
       32 
     | 
    
         
            -
                  if ('.' != p 
     | 
| 
      
 33 
     | 
    
         
            +
                  if ('.' != p.charAt(0)) return require(p);
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
                  var path = parent.split('/')
         
     | 
| 
       35 
36 
     | 
    
         
             
                    , segs = p.split('/');
         
     | 
| 
         @@ -62,10 +63,10 @@ var nodes = require('./nodes') 
     | 
|
| 
       62 
63 
     | 
    
         
             
              , filters = require('./filters')
         
     | 
| 
       63 
64 
     | 
    
         
             
              , doctypes = require('./doctypes')
         
     | 
| 
       64 
65 
     | 
    
         
             
              , selfClosing = require('./self-closing')
         
     | 
| 
       65 
     | 
    
         
            -
              ,  
     | 
| 
      
 66 
     | 
    
         
            +
              , runtime = require('./runtime')
         
     | 
| 
       66 
67 
     | 
    
         
             
              , utils = require('./utils');
         
     | 
| 
       67 
68 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
       69 
70 
     | 
    
         
             
             if (!Object.keys) {
         
     | 
| 
       70 
71 
     | 
    
         
             
               Object.keys = function(obj){
         
     | 
| 
       71 
72 
     | 
    
         
             
                 var arr = [];
         
     | 
| 
         @@ -75,9 +76,9 @@ var nodes = require('./nodes') 
     | 
|
| 
       75 
76 
     | 
    
         
             
                   }
         
     | 
| 
       76 
77 
     | 
    
         
             
                 }
         
     | 
| 
       77 
78 
     | 
    
         
             
                 return arr;
         
     | 
| 
       78 
     | 
    
         
            -
               } 
     | 
| 
      
 79 
     | 
    
         
            +
               }
         
     | 
| 
       79 
80 
     | 
    
         
             
             }
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
       81 
82 
     | 
    
         
             
             if (!String.prototype.trimLeft) {
         
     | 
| 
       82 
83 
     | 
    
         
             
               String.prototype.trimLeft = function(){
         
     | 
| 
       83 
84 
     | 
    
         
             
                 return this.replace(/^\s+/, '');
         
     | 
| 
         @@ -102,6 +103,7 @@ var Compiler = module.exports = function Compiler(node, options) { 
     | 
|
| 
       102 
103 
     | 
    
         
             
              this.pp = options.pretty || false;
         
     | 
| 
       103 
104 
     | 
    
         
             
              this.debug = false !== options.compileDebug;
         
     | 
| 
       104 
105 
     | 
    
         
             
              this.indents = 0;
         
     | 
| 
      
 106 
     | 
    
         
            +
              this.parentIndents = 0;
         
     | 
| 
       105 
107 
     | 
    
         
             
              if (options.doctype) this.setDoctype(options.doctype);
         
     | 
| 
       106 
108 
     | 
    
         
             
            };
         
     | 
| 
       107 
109 
     | 
    
         | 
| 
         @@ -110,16 +112,17 @@ var Compiler = module.exports = function Compiler(node, options) { 
     | 
|
| 
       110 
112 
     | 
    
         
             
             */
         
     | 
| 
       111 
113 
     | 
    
         | 
| 
       112 
114 
     | 
    
         
             
            Compiler.prototype = {
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
       114 
116 
     | 
    
         
             
              /**
         
     | 
| 
       115 
117 
     | 
    
         
             
               * Compile parse tree to JavaScript.
         
     | 
| 
       116 
118 
     | 
    
         
             
               *
         
     | 
| 
       117 
119 
     | 
    
         
             
               * @api public
         
     | 
| 
       118 
120 
     | 
    
         
             
               */
         
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
       120 
122 
     | 
    
         
             
              compile: function(){
         
     | 
| 
       121 
123 
     | 
    
         
             
                this.buf = ['var interp;'];
         
     | 
| 
       122 
     | 
    
         
            -
                this. 
     | 
| 
      
 124 
     | 
    
         
            +
                if (this.pp) this.buf.push("var __indent = [];");
         
     | 
| 
      
 125 
     | 
    
         
            +
                this.lastBufferedIdx = -1;
         
     | 
| 
       123 
126 
     | 
    
         
             
                this.visit(this.node);
         
     | 
| 
       124 
127 
     | 
    
         
             
                return this.buf.join('\n');
         
     | 
| 
       125 
128 
     | 
    
         
             
              },
         
     | 
| 
         @@ -132,15 +135,14 @@ Compiler.prototype = { 
     | 
|
| 
       132 
135 
     | 
    
         
             
               * @param {string} name
         
     | 
| 
       133 
136 
     | 
    
         
             
               * @api public
         
     | 
| 
       134 
137 
     | 
    
         
             
               */
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
       136 
139 
     | 
    
         
             
              setDoctype: function(name){
         
     | 
| 
       137 
     | 
    
         
            -
                 
     | 
| 
       138 
     | 
    
         
            -
                doctype =  
     | 
| 
       139 
     | 
    
         
            -
                this. 
     | 
| 
       140 
     | 
    
         
            -
                this.terse = '5' == name || 'html' == name;
         
     | 
| 
      
 140 
     | 
    
         
            +
                name = (name && name.toLowerCase()) || 'default';
         
     | 
| 
      
 141 
     | 
    
         
            +
                this.doctype = doctypes[name] || '<!DOCTYPE ' + name + '>';
         
     | 
| 
      
 142 
     | 
    
         
            +
                this.terse = this.doctype.toLowerCase() == '<!doctype html>';
         
     | 
| 
       141 
143 
     | 
    
         
             
                this.xml = 0 == this.doctype.indexOf('<?xml');
         
     | 
| 
       142 
144 
     | 
    
         
             
              },
         
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
       144 
146 
     | 
    
         
             
              /**
         
     | 
| 
       145 
147 
     | 
    
         
             
               * Buffer the given `str` optionally escaped.
         
     | 
| 
       146 
148 
     | 
    
         
             
               *
         
     | 
| 
         @@ -148,10 +150,10 @@ Compiler.prototype = { 
     | 
|
| 
       148 
150 
     | 
    
         
             
               * @param {Boolean} esc
         
     | 
| 
       149 
151 
     | 
    
         
             
               * @api public
         
     | 
| 
       150 
152 
     | 
    
         
             
               */
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
       152 
154 
     | 
    
         
             
              buffer: function(str, esc){
         
     | 
| 
       153 
155 
     | 
    
         
             
                if (esc) str = utils.escape(str);
         
     | 
| 
       154 
     | 
    
         
            -
             
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
       155 
157 
     | 
    
         
             
                if (this.lastBufferedIdx == this.buf.length) {
         
     | 
| 
       156 
158 
     | 
    
         
             
                  this.lastBuffered += str;
         
     | 
| 
       157 
159 
     | 
    
         
             
                  this.buf[this.lastBufferedIdx - 1] = "buf.push('" + this.lastBuffered + "');"
         
     | 
| 
         @@ -159,24 +161,41 @@ Compiler.prototype = { 
     | 
|
| 
       159 
161 
     | 
    
         
             
                  this.buf.push("buf.push('" + str + "');");
         
     | 
| 
       160 
162 
     | 
    
         
             
                  this.lastBuffered = str;
         
     | 
| 
       161 
163 
     | 
    
         
             
                  this.lastBufferedIdx = this.buf.length;
         
     | 
| 
       162 
     | 
    
         
            -
                } 
     | 
| 
      
 164 
     | 
    
         
            +
                }
         
     | 
| 
       163 
165 
     | 
    
         
             
              },
         
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
              /**
         
     | 
| 
      
 168 
     | 
    
         
            +
               * Buffer an indent based on the current `indent`
         
     | 
| 
      
 169 
     | 
    
         
            +
               * property and an additional `offset`.
         
     | 
| 
      
 170 
     | 
    
         
            +
               *
         
     | 
| 
      
 171 
     | 
    
         
            +
               * @param {Number} offset
         
     | 
| 
      
 172 
     | 
    
         
            +
               * @param {Boolean} newline
         
     | 
| 
      
 173 
     | 
    
         
            +
               * @api public
         
     | 
| 
      
 174 
     | 
    
         
            +
               */
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
              prettyIndent: function(offset, newline){
         
     | 
| 
      
 177 
     | 
    
         
            +
                offset = offset || 0;
         
     | 
| 
      
 178 
     | 
    
         
            +
                newline = newline ? '\\n' : '';
         
     | 
| 
      
 179 
     | 
    
         
            +
                this.buffer(newline + Array(this.indents + offset).join('  '));
         
     | 
| 
      
 180 
     | 
    
         
            +
                if (this.parentIndents)
         
     | 
| 
      
 181 
     | 
    
         
            +
                  this.buf.push("buf.push.apply(buf, __indent);");
         
     | 
| 
      
 182 
     | 
    
         
            +
              },
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
       165 
184 
     | 
    
         
             
              /**
         
     | 
| 
       166 
185 
     | 
    
         
             
               * Visit `node`.
         
     | 
| 
       167 
186 
     | 
    
         
             
               *
         
     | 
| 
       168 
187 
     | 
    
         
             
               * @param {Node} node
         
     | 
| 
       169 
188 
     | 
    
         
             
               * @api public
         
     | 
| 
       170 
189 
     | 
    
         
             
               */
         
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
       172 
191 
     | 
    
         
             
              visit: function(node){
         
     | 
| 
       173 
192 
     | 
    
         
             
                var debug = this.debug;
         
     | 
| 
       174 
193 
     | 
    
         | 
| 
       175 
194 
     | 
    
         
             
                if (debug) {
         
     | 
| 
       176 
     | 
    
         
            -
                  this.buf.push(' 
     | 
| 
      
 195 
     | 
    
         
            +
                  this.buf.push('__jade.unshift({ lineno: ' + node.line
         
     | 
| 
       177 
196 
     | 
    
         
             
                    + ', filename: ' + (node.filename
         
     | 
| 
       178 
     | 
    
         
            -
                      ?  
     | 
| 
       179 
     | 
    
         
            -
                      : ' 
     | 
| 
      
 197 
     | 
    
         
            +
                      ? JSON.stringify(node.filename)
         
     | 
| 
      
 198 
     | 
    
         
            +
                      : '__jade[0].filename')
         
     | 
| 
       180 
199 
     | 
    
         
             
                    + ' });');
         
     | 
| 
       181 
200 
     | 
    
         
             
                }
         
     | 
| 
       182 
201 
     | 
    
         | 
| 
         @@ -189,16 +208,16 @@ Compiler.prototype = { 
     | 
|
| 
       189 
208 
     | 
    
         | 
| 
       190 
209 
     | 
    
         
             
                this.visitNode(node);
         
     | 
| 
       191 
210 
     | 
    
         | 
| 
       192 
     | 
    
         
            -
                if (debug) this.buf.push(' 
     | 
| 
      
 211 
     | 
    
         
            +
                if (debug) this.buf.push('__jade.shift();');
         
     | 
| 
       193 
212 
     | 
    
         
             
              },
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
       195 
214 
     | 
    
         
             
              /**
         
     | 
| 
       196 
215 
     | 
    
         
             
               * Visit `node`.
         
     | 
| 
       197 
216 
     | 
    
         
             
               *
         
     | 
| 
       198 
217 
     | 
    
         
             
               * @param {Node} node
         
     | 
| 
       199 
218 
     | 
    
         
             
               * @api public
         
     | 
| 
       200 
219 
     | 
    
         
             
               */
         
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
       202 
221 
     | 
    
         
             
              visitNode: function(node){
         
     | 
| 
       203 
222 
     | 
    
         
             
                var name = node.constructor.name
         
     | 
| 
       204 
223 
     | 
    
         
             
                  || node.constructor.toString().match(/function ([^(\s]+)()/)[1];
         
     | 
| 
         @@ -220,7 +239,7 @@ Compiler.prototype = { 
     | 
|
| 
       220 
239 
     | 
    
         
             
                this.buf.push('}');
         
     | 
| 
       221 
240 
     | 
    
         
             
                this.withinCase = _;
         
     | 
| 
       222 
241 
     | 
    
         
             
              },
         
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
       224 
243 
     | 
    
         
             
              /**
         
     | 
| 
       225 
244 
     | 
    
         
             
               * Visit when `node`.
         
     | 
| 
       226 
245 
     | 
    
         
             
               *
         
     | 
| 
         @@ -258,12 +277,34 @@ Compiler.prototype = { 
     | 
|
| 
       258 
277 
     | 
    
         
             
               */
         
     | 
| 
       259 
278 
     | 
    
         | 
| 
       260 
279 
     | 
    
         
             
              visitBlock: function(block){
         
     | 
| 
       261 
     | 
    
         
            -
                var len = block.nodes.length 
     | 
| 
      
 280 
     | 
    
         
            +
                var len = block.nodes.length
         
     | 
| 
      
 281 
     | 
    
         
            +
                  , escape = this.escape
         
     | 
| 
      
 282 
     | 
    
         
            +
                  , pp = this.pp
         
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
      
 284 
     | 
    
         
            +
                // Block keyword has a special meaning in mixins
         
     | 
| 
      
 285 
     | 
    
         
            +
                if (this.parentIndents && block.mode) {
         
     | 
| 
      
 286 
     | 
    
         
            +
                  if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join('  ') + "');")
         
     | 
| 
      
 287 
     | 
    
         
            +
                  this.buf.push('block && block();');
         
     | 
| 
      
 288 
     | 
    
         
            +
                  if (pp) this.buf.push("__indent.pop();")
         
     | 
| 
      
 289 
     | 
    
         
            +
                  return;
         
     | 
| 
      
 290 
     | 
    
         
            +
                }
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
                // Pretty print multi-line text
         
     | 
| 
      
 293 
     | 
    
         
            +
                if (pp && len > 1 && !escape && block.nodes[0].isText && block.nodes[1].isText)
         
     | 
| 
      
 294 
     | 
    
         
            +
                  this.prettyIndent(1, true);
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
       262 
296 
     | 
    
         
             
                for (var i = 0; i < len; ++i) {
         
     | 
| 
      
 297 
     | 
    
         
            +
                  // Pretty print text
         
     | 
| 
      
 298 
     | 
    
         
            +
                  if (pp && i > 0 && !escape && block.nodes[i].isText && block.nodes[i-1].isText)
         
     | 
| 
      
 299 
     | 
    
         
            +
                    this.prettyIndent(1, false);
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
       263 
301 
     | 
    
         
             
                  this.visit(block.nodes[i]);
         
     | 
| 
      
 302 
     | 
    
         
            +
                  // Multiple text nodes are separated by newlines
         
     | 
| 
      
 303 
     | 
    
         
            +
                  if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText)
         
     | 
| 
      
 304 
     | 
    
         
            +
                    this.buffer('\\n');
         
     | 
| 
       264 
305 
     | 
    
         
             
                }
         
     | 
| 
       265 
306 
     | 
    
         
             
              },
         
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
       267 
308 
     | 
    
         
             
              /**
         
     | 
| 
       268 
309 
     | 
    
         
             
               * Visit `doctype`. Sets terse mode to `true` when html 5
         
     | 
| 
       269 
310 
     | 
    
         
             
               * is used, causing self-closing tags to end with ">" vs "/>",
         
     | 
| 
         @@ -272,7 +313,7 @@ Compiler.prototype = { 
     | 
|
| 
       272 
313 
     | 
    
         
             
               * @param {Doctype} doctype
         
     | 
| 
       273 
314 
     | 
    
         
             
               * @api public
         
     | 
| 
       274 
315 
     | 
    
         
             
               */
         
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
       276 
317 
     | 
    
         
             
              visitDoctype: function(doctype){
         
     | 
| 
       277 
318 
     | 
    
         
             
                if (doctype && (doctype.val || !this.doctype)) {
         
     | 
| 
       278 
319 
     | 
    
         
             
                  this.setDoctype(doctype.val || 'default');
         
     | 
| 
         @@ -292,14 +333,62 @@ Compiler.prototype = { 
     | 
|
| 
       292 
333 
     | 
    
         | 
| 
       293 
334 
     | 
    
         
             
              visitMixin: function(mixin){
         
     | 
| 
       294 
335 
     | 
    
         
             
                var name = mixin.name.replace(/-/g, '_') + '_mixin'
         
     | 
| 
       295 
     | 
    
         
            -
                  , args = mixin.args || '' 
     | 
| 
      
 336 
     | 
    
         
            +
                  , args = mixin.args || ''
         
     | 
| 
      
 337 
     | 
    
         
            +
                  , block = mixin.block
         
     | 
| 
      
 338 
     | 
    
         
            +
                  , attrs = mixin.attrs
         
     | 
| 
      
 339 
     | 
    
         
            +
                  , pp = this.pp;
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
                if (mixin.call) {
         
     | 
| 
      
 342 
     | 
    
         
            +
                  if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join('  ') + "');")
         
     | 
| 
      
 343 
     | 
    
         
            +
                  if (block || attrs.length) {
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
                    this.buf.push(name + '.call({');
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
                    if (block) {
         
     | 
| 
      
 348 
     | 
    
         
            +
                      this.buf.push('block: function(){');
         
     | 
| 
      
 349 
     | 
    
         
            +
             
     | 
| 
      
 350 
     | 
    
         
            +
                      // Render block with no indents, dynamically added when rendered
         
     | 
| 
      
 351 
     | 
    
         
            +
                      this.parentIndents++;
         
     | 
| 
      
 352 
     | 
    
         
            +
                      var _indents = this.indents;
         
     | 
| 
      
 353 
     | 
    
         
            +
                      this.indents = 0;
         
     | 
| 
      
 354 
     | 
    
         
            +
                      this.visit(mixin.block);
         
     | 
| 
      
 355 
     | 
    
         
            +
                      this.indents = _indents;
         
     | 
| 
      
 356 
     | 
    
         
            +
                      this.parentIndents--;
         
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
      
 358 
     | 
    
         
            +
                      if (attrs.length) {
         
     | 
| 
      
 359 
     | 
    
         
            +
                        this.buf.push('},');
         
     | 
| 
      
 360 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 361 
     | 
    
         
            +
                        this.buf.push('}');
         
     | 
| 
      
 362 
     | 
    
         
            +
                      }
         
     | 
| 
      
 363 
     | 
    
         
            +
                    }
         
     | 
| 
       296 
364 
     | 
    
         | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
      
 365 
     | 
    
         
            +
                    if (attrs.length) {
         
     | 
| 
      
 366 
     | 
    
         
            +
                      var val = this.attrs(attrs);
         
     | 
| 
      
 367 
     | 
    
         
            +
                      if (val.inherits) {
         
     | 
| 
      
 368 
     | 
    
         
            +
                        this.buf.push('attributes: merge({' + val.buf
         
     | 
| 
      
 369 
     | 
    
         
            +
                            + '}, attributes), escaped: merge(' + val.escaped + ', escaped, true)');
         
     | 
| 
      
 370 
     | 
    
         
            +
                      } else {
         
     | 
| 
      
 371 
     | 
    
         
            +
                        this.buf.push('attributes: {' + val.buf + '}, escaped: ' + val.escaped);
         
     | 
| 
      
 372 
     | 
    
         
            +
                      }
         
     | 
| 
      
 373 
     | 
    
         
            +
                    }
         
     | 
| 
      
 374 
     | 
    
         
            +
             
     | 
| 
      
 375 
     | 
    
         
            +
                    if (args) {
         
     | 
| 
      
 376 
     | 
    
         
            +
                      this.buf.push('}, ' + args + ');');
         
     | 
| 
      
 377 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 378 
     | 
    
         
            +
                      this.buf.push('});');
         
     | 
| 
      
 379 
     | 
    
         
            +
                    }
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 382 
     | 
    
         
            +
                    this.buf.push(name + '(' + args + ');');
         
     | 
| 
      
 383 
     | 
    
         
            +
                  }
         
     | 
| 
      
 384 
     | 
    
         
            +
                  if (pp) this.buf.push("__indent.pop();")
         
     | 
| 
       301 
385 
     | 
    
         
             
                } else {
         
     | 
| 
       302 
     | 
    
         
            -
                  this.buf.push(name + '(' + args + ') 
     | 
| 
      
 386 
     | 
    
         
            +
                  this.buf.push('var ' + name + ' = function(' + args + '){');
         
     | 
| 
      
 387 
     | 
    
         
            +
                  this.buf.push('var block = this.block, attributes = this.attributes || {}, escaped = this.escaped || {};');
         
     | 
| 
      
 388 
     | 
    
         
            +
                  this.parentIndents++;
         
     | 
| 
      
 389 
     | 
    
         
            +
                  this.visit(block);
         
     | 
| 
      
 390 
     | 
    
         
            +
                  this.parentIndents--;
         
     | 
| 
      
 391 
     | 
    
         
            +
                  this.buf.push('};');
         
     | 
| 
       303 
392 
     | 
    
         
             
                }
         
     | 
| 
       304 
393 
     | 
    
         
             
              },
         
     | 
| 
       305 
394 
     | 
    
         | 
| 
         @@ -310,10 +399,13 @@ Compiler.prototype = { 
     | 
|
| 
       310 
399 
     | 
    
         
             
               * @param {Tag} tag
         
     | 
| 
       311 
400 
     | 
    
         
             
               * @api public
         
     | 
| 
       312 
401 
     | 
    
         
             
               */
         
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
      
 402 
     | 
    
         
            +
             
     | 
| 
       314 
403 
     | 
    
         
             
              visitTag: function(tag){
         
     | 
| 
       315 
404 
     | 
    
         
             
                this.indents++;
         
     | 
| 
       316 
     | 
    
         
            -
                var name = tag.name 
     | 
| 
      
 405 
     | 
    
         
            +
                var name = tag.name
         
     | 
| 
      
 406 
     | 
    
         
            +
                  , pp = this.pp;
         
     | 
| 
      
 407 
     | 
    
         
            +
             
     | 
| 
      
 408 
     | 
    
         
            +
                if (tag.buffer) name = "' + (" + name + ") + '";
         
     | 
| 
       317 
409 
     | 
    
         | 
| 
       318 
410 
     | 
    
         
             
                if (!this.hasCompiledTag) {
         
     | 
| 
       319 
411 
     | 
    
         
             
                  if (!this.hasCompiledDoctype && 'html' == name) {
         
     | 
| 
         @@ -323,11 +415,10 @@ Compiler.prototype = { 
     | 
|
| 
       323 
415 
     | 
    
         
             
                }
         
     | 
| 
       324 
416 
     | 
    
         | 
| 
       325 
417 
     | 
    
         
             
                // pretty print
         
     | 
| 
       326 
     | 
    
         
            -
                if ( 
     | 
| 
       327 
     | 
    
         
            -
                  this. 
     | 
| 
       328 
     | 
    
         
            -
                }
         
     | 
| 
      
 418 
     | 
    
         
            +
                if (pp && !tag.isInline())
         
     | 
| 
      
 419 
     | 
    
         
            +
                  this.prettyIndent(0, true);
         
     | 
| 
       329 
420 
     | 
    
         | 
| 
       330 
     | 
    
         
            -
                if (~selfClosing.indexOf(name) && !this.xml) {
         
     | 
| 
      
 421 
     | 
    
         
            +
                if ((~selfClosing.indexOf(name) || tag.selfClosing) && !this.xml) {
         
     | 
| 
       331 
422 
     | 
    
         
             
                  this.buffer('<' + name);
         
     | 
| 
       332 
423 
     | 
    
         
             
                  this.visitAttributes(tag.attrs);
         
     | 
| 
       333 
424 
     | 
    
         
             
                  this.terse
         
     | 
| 
         @@ -343,27 +434,25 @@ Compiler.prototype = { 
     | 
|
| 
       343 
434 
     | 
    
         
             
                    this.buffer('<' + name + '>');
         
     | 
| 
       344 
435 
     | 
    
         
             
                  }
         
     | 
| 
       345 
436 
     | 
    
         
             
                  if (tag.code) this.visitCode(tag.code);
         
     | 
| 
       346 
     | 
    
         
            -
                  if (tag.text) this.buffer(utils.text(tag.text.nodes[0].trimLeft()));
         
     | 
| 
       347 
437 
     | 
    
         
             
                  this.escape = 'pre' == tag.name;
         
     | 
| 
       348 
438 
     | 
    
         
             
                  this.visit(tag.block);
         
     | 
| 
       349 
439 
     | 
    
         | 
| 
       350 
440 
     | 
    
         
             
                  // pretty print
         
     | 
| 
       351 
     | 
    
         
            -
                  if ( 
     | 
| 
       352 
     | 
    
         
            -
                    this. 
     | 
| 
       353 
     | 
    
         
            -
                  }
         
     | 
| 
      
 441 
     | 
    
         
            +
                  if (pp && !tag.isInline() && 'pre' != tag.name && !tag.canInline())
         
     | 
| 
      
 442 
     | 
    
         
            +
                    this.prettyIndent(0, true);
         
     | 
| 
       354 
443 
     | 
    
         | 
| 
       355 
444 
     | 
    
         
             
                  this.buffer('</' + name + '>');
         
     | 
| 
       356 
445 
     | 
    
         
             
                }
         
     | 
| 
       357 
446 
     | 
    
         
             
                this.indents--;
         
     | 
| 
       358 
447 
     | 
    
         
             
              },
         
     | 
| 
       359 
     | 
    
         
            -
             
     | 
| 
      
 448 
     | 
    
         
            +
             
     | 
| 
       360 
449 
     | 
    
         
             
              /**
         
     | 
| 
       361 
450 
     | 
    
         
             
               * Visit `filter`, throwing when the filter does not exist.
         
     | 
| 
       362 
451 
     | 
    
         
             
               *
         
     | 
| 
       363 
452 
     | 
    
         
             
               * @param {Filter} filter
         
     | 
| 
       364 
453 
     | 
    
         
             
               * @api public
         
     | 
| 
       365 
454 
     | 
    
         
             
               */
         
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
       367 
456 
     | 
    
         
             
              visitFilter: function(filter){
         
     | 
| 
       368 
457 
     | 
    
         
             
                var fn = filters[filter.name];
         
     | 
| 
       369 
458 
     | 
    
         | 
| 
         @@ -375,48 +464,50 @@ Compiler.prototype = { 
     | 
|
| 
       375 
464 
     | 
    
         
             
                    throw new Error('unknown filter ":' + filter.name + '"');
         
     | 
| 
       376 
465 
     | 
    
         
             
                  }
         
     | 
| 
       377 
466 
     | 
    
         
             
                }
         
     | 
| 
      
 467 
     | 
    
         
            +
             
     | 
| 
       378 
468 
     | 
    
         
             
                if (filter.isASTFilter) {
         
     | 
| 
       379 
469 
     | 
    
         
             
                  this.buf.push(fn(filter.block, this, filter.attrs));
         
     | 
| 
       380 
470 
     | 
    
         
             
                } else {
         
     | 
| 
       381 
     | 
    
         
            -
                  var text = filter.block.nodes.join('');
         
     | 
| 
      
 471 
     | 
    
         
            +
                  var text = filter.block.nodes.map(function(node){ return node.val }).join('\n');
         
     | 
| 
      
 472 
     | 
    
         
            +
                  filter.attrs = filter.attrs || {};
         
     | 
| 
      
 473 
     | 
    
         
            +
                  filter.attrs.filename = this.options.filename;
         
     | 
| 
       382 
474 
     | 
    
         
             
                  this.buffer(utils.text(fn(text, filter.attrs)));
         
     | 
| 
       383 
475 
     | 
    
         
             
                }
         
     | 
| 
       384 
476 
     | 
    
         
             
              },
         
     | 
| 
       385 
     | 
    
         
            -
             
     | 
| 
      
 477 
     | 
    
         
            +
             
     | 
| 
       386 
478 
     | 
    
         
             
              /**
         
     | 
| 
       387 
479 
     | 
    
         
             
               * Visit `text` node.
         
     | 
| 
       388 
480 
     | 
    
         
             
               *
         
     | 
| 
       389 
481 
     | 
    
         
             
               * @param {Text} text
         
     | 
| 
       390 
482 
     | 
    
         
             
               * @api public
         
     | 
| 
       391 
483 
     | 
    
         
             
               */
         
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
      
 484 
     | 
    
         
            +
             
     | 
| 
       393 
485 
     | 
    
         
             
              visitText: function(text){
         
     | 
| 
       394 
     | 
    
         
            -
                text = utils.text(text. 
     | 
| 
      
 486 
     | 
    
         
            +
                text = utils.text(text.val.replace(/\\/g, '\\\\'));
         
     | 
| 
       395 
487 
     | 
    
         
             
                if (this.escape) text = escape(text);
         
     | 
| 
       396 
488 
     | 
    
         
             
                this.buffer(text);
         
     | 
| 
       397 
     | 
    
         
            -
                this.buffer('\\n');
         
     | 
| 
       398 
489 
     | 
    
         
             
              },
         
     | 
| 
       399 
     | 
    
         
            -
             
     | 
| 
      
 490 
     | 
    
         
            +
             
     | 
| 
       400 
491 
     | 
    
         
             
              /**
         
     | 
| 
       401 
492 
     | 
    
         
             
               * Visit a `comment`, only buffering when the buffer flag is set.
         
     | 
| 
       402 
493 
     | 
    
         
             
               *
         
     | 
| 
       403 
494 
     | 
    
         
             
               * @param {Comment} comment
         
     | 
| 
       404 
495 
     | 
    
         
             
               * @api public
         
     | 
| 
       405 
496 
     | 
    
         
             
               */
         
     | 
| 
       406 
     | 
    
         
            -
             
     | 
| 
      
 497 
     | 
    
         
            +
             
     | 
| 
       407 
498 
     | 
    
         
             
              visitComment: function(comment){
         
     | 
| 
       408 
499 
     | 
    
         
             
                if (!comment.buffer) return;
         
     | 
| 
       409 
     | 
    
         
            -
                if (this.pp) this. 
     | 
| 
      
 500 
     | 
    
         
            +
                if (this.pp) this.prettyIndent(1, true);
         
     | 
| 
       410 
501 
     | 
    
         
             
                this.buffer('<!--' + utils.escape(comment.val) + '-->');
         
     | 
| 
       411 
502 
     | 
    
         
             
              },
         
     | 
| 
       412 
     | 
    
         
            -
             
     | 
| 
      
 503 
     | 
    
         
            +
             
     | 
| 
       413 
504 
     | 
    
         
             
              /**
         
     | 
| 
       414 
505 
     | 
    
         
             
               * Visit a `BlockComment`.
         
     | 
| 
       415 
506 
     | 
    
         
             
               *
         
     | 
| 
       416 
507 
     | 
    
         
             
               * @param {Comment} comment
         
     | 
| 
       417 
508 
     | 
    
         
             
               * @api public
         
     | 
| 
       418 
509 
     | 
    
         
             
               */
         
     | 
| 
       419 
     | 
    
         
            -
             
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
       420 
511 
     | 
    
         
             
              visitBlockComment: function(comment){
         
     | 
| 
       421 
512 
     | 
    
         
             
                if (!comment.buffer) return;
         
     | 
| 
       422 
513 
     | 
    
         
             
                if (0 == comment.val.trim().indexOf('if')) {
         
     | 
| 
         @@ -429,7 +520,7 @@ Compiler.prototype = { 
     | 
|
| 
       429 
520 
     | 
    
         
             
                  this.buffer('-->');
         
     | 
| 
       430 
521 
     | 
    
         
             
                }
         
     | 
| 
       431 
522 
     | 
    
         
             
              },
         
     | 
| 
       432 
     | 
    
         
            -
             
     | 
| 
      
 523 
     | 
    
         
            +
             
     | 
| 
       433 
524 
     | 
    
         
             
              /**
         
     | 
| 
       434 
525 
     | 
    
         
             
               * Visit `code`, respecting buffer / escape flags.
         
     | 
| 
       435 
526 
     | 
    
         
             
               * If the code is followed by a block, wrap it in
         
     | 
| 
         @@ -438,7 +529,7 @@ Compiler.prototype = { 
     | 
|
| 
       438 
529 
     | 
    
         
             
               * @param {Code} code
         
     | 
| 
       439 
530 
     | 
    
         
             
               * @api public
         
     | 
| 
       440 
531 
     | 
    
         
             
               */
         
     | 
| 
       441 
     | 
    
         
            -
             
     | 
| 
      
 532 
     | 
    
         
            +
             
     | 
| 
       442 
533 
     | 
    
         
             
              visitCode: function(code){
         
     | 
| 
       443 
534 
     | 
    
         
             
                // Wrap code blocks with {}.
         
     | 
| 
       444 
535 
     | 
    
         
             
                // we only wrap unbuffered code blocks ATM
         
     | 
| 
         @@ -462,26 +553,39 @@ Compiler.prototype = { 
     | 
|
| 
       462 
553 
     | 
    
         
             
                  if (!code.buffer) this.buf.push('}');
         
     | 
| 
       463 
554 
     | 
    
         
             
                }
         
     | 
| 
       464 
555 
     | 
    
         
             
              },
         
     | 
| 
       465 
     | 
    
         
            -
             
     | 
| 
      
 556 
     | 
    
         
            +
             
     | 
| 
       466 
557 
     | 
    
         
             
              /**
         
     | 
| 
       467 
558 
     | 
    
         
             
               * Visit `each` block.
         
     | 
| 
       468 
559 
     | 
    
         
             
               *
         
     | 
| 
       469 
560 
     | 
    
         
             
               * @param {Each} each
         
     | 
| 
       470 
561 
     | 
    
         
             
               * @api public
         
     | 
| 
       471 
562 
     | 
    
         
             
               */
         
     | 
| 
       472 
     | 
    
         
            -
             
     | 
| 
      
 563 
     | 
    
         
            +
             
     | 
| 
       473 
564 
     | 
    
         
             
              visitEach: function(each){
         
     | 
| 
       474 
565 
     | 
    
         
             
                this.buf.push(''
         
     | 
| 
       475 
566 
     | 
    
         
             
                  + '// iterate ' + each.obj + '\n'
         
     | 
| 
       476 
     | 
    
         
            -
                  + '(function(){\n'
         
     | 
| 
       477 
     | 
    
         
            -
                  + '  if (\'number\' == typeof ' + each.obj + '.length) {\n'
         
     | 
| 
      
 567 
     | 
    
         
            +
                  + ';(function(){\n'
         
     | 
| 
      
 568 
     | 
    
         
            +
                  + '  if (\'number\' == typeof ' + each.obj + '.length) {\n');
         
     | 
| 
      
 569 
     | 
    
         
            +
             
     | 
| 
      
 570 
     | 
    
         
            +
                if (each.alternative) {
         
     | 
| 
      
 571 
     | 
    
         
            +
                  this.buf.push('  if (' + each.obj + '.length) {');
         
     | 
| 
      
 572 
     | 
    
         
            +
                }
         
     | 
| 
      
 573 
     | 
    
         
            +
             
     | 
| 
      
 574 
     | 
    
         
            +
                this.buf.push(''
         
     | 
| 
       478 
575 
     | 
    
         
             
                  + '    for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n'
         
     | 
| 
       479 
576 
     | 
    
         
             
                  + '      var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
         
     | 
| 
       480 
577 
     | 
    
         | 
| 
       481 
578 
     | 
    
         
             
                this.visit(each.block);
         
     | 
| 
       482 
579 
     | 
    
         | 
| 
      
 580 
     | 
    
         
            +
                this.buf.push('    }\n');
         
     | 
| 
      
 581 
     | 
    
         
            +
             
     | 
| 
      
 582 
     | 
    
         
            +
                if (each.alternative) {
         
     | 
| 
      
 583 
     | 
    
         
            +
                  this.buf.push('  } else {');
         
     | 
| 
      
 584 
     | 
    
         
            +
                  this.visit(each.alternative);
         
     | 
| 
      
 585 
     | 
    
         
            +
                  this.buf.push('  }');
         
     | 
| 
      
 586 
     | 
    
         
            +
                }
         
     | 
| 
      
 587 
     | 
    
         
            +
             
     | 
| 
       483 
588 
     | 
    
         
             
                this.buf.push(''
         
     | 
| 
       484 
     | 
    
         
            -
                  + '    }\n'
         
     | 
| 
       485 
589 
     | 
    
         
             
                  + '  } else {\n'
         
     | 
| 
       486 
590 
     | 
    
         
             
                  + '    for (var ' + each.key + ' in ' + each.obj + ') {\n'
         
     | 
| 
       487 
591 
     | 
    
         
             
                   + '      if (' + each.obj + '.hasOwnProperty(' + each.key + ')){'
         
     | 
| 
         @@ -493,21 +597,43 @@ Compiler.prototype = { 
     | 
|
| 
       493 
597 
     | 
    
         | 
| 
       494 
598 
     | 
    
         
             
                this.buf.push('   }\n  }\n}).call(this);\n');
         
     | 
| 
       495 
599 
     | 
    
         
             
              },
         
     | 
| 
       496 
     | 
    
         
            -
             
     | 
| 
      
 600 
     | 
    
         
            +
             
     | 
| 
       497 
601 
     | 
    
         
             
              /**
         
     | 
| 
       498 
602 
     | 
    
         
             
               * Visit `attrs`.
         
     | 
| 
       499 
603 
     | 
    
         
             
               *
         
     | 
| 
       500 
604 
     | 
    
         
             
               * @param {Array} attrs
         
     | 
| 
       501 
605 
     | 
    
         
             
               * @api public
         
     | 
| 
       502 
606 
     | 
    
         
             
               */
         
     | 
| 
       503 
     | 
    
         
            -
             
     | 
| 
      
 607 
     | 
    
         
            +
             
     | 
| 
       504 
608 
     | 
    
         
             
              visitAttributes: function(attrs){
         
     | 
| 
      
 609 
     | 
    
         
            +
                var val = this.attrs(attrs);
         
     | 
| 
      
 610 
     | 
    
         
            +
                if (val.inherits) {
         
     | 
| 
      
 611 
     | 
    
         
            +
                  this.buf.push("buf.push(attrs(merge({ " + val.buf +
         
     | 
| 
      
 612 
     | 
    
         
            +
                      " }, attributes), merge(" + val.escaped + ", escaped, true)));");
         
     | 
| 
      
 613 
     | 
    
         
            +
                } else if (val.constant) {
         
     | 
| 
      
 614 
     | 
    
         
            +
                  eval('var buf={' + val.buf + '};');
         
     | 
| 
      
 615 
     | 
    
         
            +
                  this.buffer(runtime.attrs(buf, JSON.parse(val.escaped)), true);
         
     | 
| 
      
 616 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 617 
     | 
    
         
            +
                  this.buf.push("buf.push(attrs({ " + val.buf + " }, " + val.escaped + "));");
         
     | 
| 
      
 618 
     | 
    
         
            +
                }
         
     | 
| 
      
 619 
     | 
    
         
            +
              },
         
     | 
| 
      
 620 
     | 
    
         
            +
             
     | 
| 
      
 621 
     | 
    
         
            +
              /**
         
     | 
| 
      
 622 
     | 
    
         
            +
               * Compile attributes.
         
     | 
| 
      
 623 
     | 
    
         
            +
               */
         
     | 
| 
      
 624 
     | 
    
         
            +
             
     | 
| 
      
 625 
     | 
    
         
            +
              attrs: function(attrs){
         
     | 
| 
       505 
626 
     | 
    
         
             
                var buf = []
         
     | 
| 
       506 
     | 
    
         
            -
                  , classes = [] 
     | 
| 
      
 627 
     | 
    
         
            +
                  , classes = []
         
     | 
| 
      
 628 
     | 
    
         
            +
                  , escaped = {}
         
     | 
| 
      
 629 
     | 
    
         
            +
                  , constant = attrs.every(function(attr){ return isConstant(attr.val) })
         
     | 
| 
      
 630 
     | 
    
         
            +
                  , inherits = false;
         
     | 
| 
       507 
631 
     | 
    
         | 
| 
       508 
632 
     | 
    
         
             
                if (this.terse) buf.push('terse: true');
         
     | 
| 
       509 
633 
     | 
    
         | 
| 
       510 
634 
     | 
    
         
             
                attrs.forEach(function(attr){
         
     | 
| 
      
 635 
     | 
    
         
            +
                  if (attr.name == 'attributes') return inherits = true;
         
     | 
| 
      
 636 
     | 
    
         
            +
                  escaped[attr.name] = attr.escaped;
         
     | 
| 
       511 
637 
     | 
    
         
             
                  if (attr.name == 'class') {
         
     | 
| 
       512 
638 
     | 
    
         
             
                    classes.push('(' + attr.val + ')');
         
     | 
| 
       513 
639 
     | 
    
         
             
                  } else {
         
     | 
| 
         @@ -521,12 +647,40 @@ Compiler.prototype = { 
     | 
|
| 
       521 
647 
     | 
    
         
             
                  buf.push("class: " + classes);
         
     | 
| 
       522 
648 
     | 
    
         
             
                }
         
     | 
| 
       523 
649 
     | 
    
         | 
| 
       524 
     | 
    
         
            -
                 
     | 
| 
       525 
     | 
    
         
            -
             
     | 
| 
       526 
     | 
    
         
            -
             
     | 
| 
      
 650 
     | 
    
         
            +
                return {
         
     | 
| 
      
 651 
     | 
    
         
            +
                  buf: buf.join(', ').replace('class:', '"class":'),
         
     | 
| 
      
 652 
     | 
    
         
            +
                  escaped: JSON.stringify(escaped),
         
     | 
| 
      
 653 
     | 
    
         
            +
                  inherits: inherits,
         
     | 
| 
      
 654 
     | 
    
         
            +
                  constant: constant
         
     | 
| 
      
 655 
     | 
    
         
            +
                };
         
     | 
| 
       527 
656 
     | 
    
         
             
              }
         
     | 
| 
       528 
657 
     | 
    
         
             
            };
         
     | 
| 
       529 
658 
     | 
    
         | 
| 
      
 659 
     | 
    
         
            +
            /**
         
     | 
| 
      
 660 
     | 
    
         
            +
             * Check if expression can be evaluated to a constant
         
     | 
| 
      
 661 
     | 
    
         
            +
             *
         
     | 
| 
      
 662 
     | 
    
         
            +
             * @param {String} expression
         
     | 
| 
      
 663 
     | 
    
         
            +
             * @return {Boolean}
         
     | 
| 
      
 664 
     | 
    
         
            +
             * @api private
         
     | 
| 
      
 665 
     | 
    
         
            +
             */
         
     | 
| 
      
 666 
     | 
    
         
            +
             
     | 
| 
      
 667 
     | 
    
         
            +
            function isConstant(val){
         
     | 
| 
      
 668 
     | 
    
         
            +
              // Check strings/literals
         
     | 
| 
      
 669 
     | 
    
         
            +
              if (/^ *("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|true|false|null|undefined) *$/i.test(val))
         
     | 
| 
      
 670 
     | 
    
         
            +
                return true;
         
     | 
| 
      
 671 
     | 
    
         
            +
             
     | 
| 
      
 672 
     | 
    
         
            +
              // Check numbers
         
     | 
| 
      
 673 
     | 
    
         
            +
              if (!isNaN(Number(val)))
         
     | 
| 
      
 674 
     | 
    
         
            +
                return true;
         
     | 
| 
      
 675 
     | 
    
         
            +
             
     | 
| 
      
 676 
     | 
    
         
            +
              // Check arrays
         
     | 
| 
      
 677 
     | 
    
         
            +
              var matches;
         
     | 
| 
      
 678 
     | 
    
         
            +
              if (matches = /^ *\[(.*)\] *$/.exec(val))
         
     | 
| 
      
 679 
     | 
    
         
            +
                return matches[1].split(',').every(isConstant);
         
     | 
| 
      
 680 
     | 
    
         
            +
             
     | 
| 
      
 681 
     | 
    
         
            +
              return false;
         
     | 
| 
      
 682 
     | 
    
         
            +
            }
         
     | 
| 
      
 683 
     | 
    
         
            +
             
     | 
| 
       530 
684 
     | 
    
         
             
            /**
         
     | 
| 
       531 
685 
     | 
    
         
             
             * Escape the given string of `html`.
         
     | 
| 
       532 
686 
     | 
    
         
             
             *
         
     | 
| 
         @@ -555,8 +709,8 @@ require.register("doctypes.js", function(module, exports, require){ 
     | 
|
| 
       555 
709 
     | 
    
         | 
| 
       556 
710 
     | 
    
         
             
            module.exports = {
         
     | 
| 
       557 
711 
     | 
    
         
             
                '5': '<!DOCTYPE html>'
         
     | 
| 
      
 712 
     | 
    
         
            +
              , 'default': '<!DOCTYPE html>'
         
     | 
| 
       558 
713 
     | 
    
         
             
              , 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
         
     | 
| 
       559 
     | 
    
         
            -
              , 'default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
         
     | 
| 
       560 
714 
     | 
    
         
             
              , 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
         
     | 
| 
       561 
715 
     | 
    
         
             
              , 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
         
     | 
| 
       562 
716 
     | 
    
         
             
              , 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
         
     | 
| 
         @@ -640,7 +794,12 @@ module.exports = { 
     | 
|
| 
       640 
794 
     | 
    
         
             
                    try {
         
     | 
| 
       641 
795 
     | 
    
         
             
                      md = require('markdown-js');
         
     | 
| 
       642 
796 
     | 
    
         
             
                    } catch (err) {
         
     | 
| 
       643 
     | 
    
         
            -
                       
     | 
| 
      
 797 
     | 
    
         
            +
                      try {
         
     | 
| 
      
 798 
     | 
    
         
            +
                        md = require('marked');
         
     | 
| 
      
 799 
     | 
    
         
            +
                      } catch (err) {
         
     | 
| 
      
 800 
     | 
    
         
            +
                        throw new
         
     | 
| 
      
 801 
     | 
    
         
            +
                          Error('Cannot find markdown library, install markdown, discount, or marked.');
         
     | 
| 
      
 802 
     | 
    
         
            +
                      }
         
     | 
| 
       644 
803 
     | 
    
         
             
                    }
         
     | 
| 
       645 
804 
     | 
    
         
             
                  }
         
     | 
| 
       646 
805 
     | 
    
         
             
                }
         
     | 
| 
         @@ -655,7 +814,7 @@ module.exports = { 
     | 
|
| 
       655 
814 
     | 
    
         | 
| 
       656 
815 
     | 
    
         
             
              coffeescript: function(str){
         
     | 
| 
       657 
816 
     | 
    
         
             
                str = str.replace(/\\n/g, '\n');
         
     | 
| 
       658 
     | 
    
         
            -
                var js = require('coffee-script').compile(str).replace(/\n/g, '\\n');
         
     | 
| 
      
 817 
     | 
    
         
            +
                var js = require('coffee-script').compile(str).replace(/\\/g, '\\\\').replace(/\n/g, '\\n');
         
     | 
| 
       659 
818 
     | 
    
         
             
                return '<script type="text/javascript">\\n' + js + '</script>';
         
     | 
| 
       660 
819 
     | 
    
         
             
              }
         
     | 
| 
       661 
820 
     | 
    
         
             
            };
         
     | 
| 
         @@ -694,7 +853,6 @@ module.exports = [ 
     | 
|
| 
       694 
853 
     | 
    
         
             
            }); // module: inline-tags.js
         
     | 
| 
       695 
854 
     | 
    
         | 
| 
       696 
855 
     | 
    
         
             
            require.register("jade.js", function(module, exports, require){
         
     | 
| 
       697 
     | 
    
         
            -
             
     | 
| 
       698 
856 
     | 
    
         
             
            /*!
         
     | 
| 
       699 
857 
     | 
    
         
             
             * Jade
         
     | 
| 
       700 
858 
     | 
    
         
             
             * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
         
     | 
| 
         @@ -714,7 +872,7 @@ var Parser = require('./parser') 
     | 
|
| 
       714 
872 
     | 
    
         
             
             * Library version.
         
     | 
| 
       715 
873 
     | 
    
         
             
             */
         
     | 
| 
       716 
874 
     | 
    
         | 
| 
       717 
     | 
    
         
            -
            exports.version = '0. 
     | 
| 
      
 875 
     | 
    
         
            +
            exports.version = '0.27.6';
         
     | 
| 
       718 
876 
     | 
    
         | 
| 
       719 
877 
     | 
    
         
             
            /**
         
     | 
| 
       720 
878 
     | 
    
         
             
             * Expose self closing tags.
         
     | 
| 
         @@ -811,11 +969,25 @@ function parse(str, options){ 
     | 
|
| 
       811 
969 
     | 
    
         
             
              }
         
     | 
| 
       812 
970 
     | 
    
         
             
            }
         
     | 
| 
       813 
971 
     | 
    
         | 
| 
      
 972 
     | 
    
         
            +
            /**
         
     | 
| 
      
 973 
     | 
    
         
            +
             * Strip any UTF-8 BOM off of the start of `str`, if it exists.
         
     | 
| 
      
 974 
     | 
    
         
            +
             *
         
     | 
| 
      
 975 
     | 
    
         
            +
             * @param {String} str
         
     | 
| 
      
 976 
     | 
    
         
            +
             * @return {String}
         
     | 
| 
      
 977 
     | 
    
         
            +
             * @api private
         
     | 
| 
      
 978 
     | 
    
         
            +
             */
         
     | 
| 
      
 979 
     | 
    
         
            +
             
     | 
| 
      
 980 
     | 
    
         
            +
            function stripBOM(str){
         
     | 
| 
      
 981 
     | 
    
         
            +
              return 0xFEFF == str.charCodeAt(0)
         
     | 
| 
      
 982 
     | 
    
         
            +
                ? str.substring(1)
         
     | 
| 
      
 983 
     | 
    
         
            +
                : str;
         
     | 
| 
      
 984 
     | 
    
         
            +
            }
         
     | 
| 
      
 985 
     | 
    
         
            +
             
     | 
| 
       814 
986 
     | 
    
         
             
            /**
         
     | 
| 
       815 
987 
     | 
    
         
             
             * Compile a `Function` representation of the given jade `str`.
         
     | 
| 
       816 
988 
     | 
    
         
             
             *
         
     | 
| 
       817 
989 
     | 
    
         
             
             * Options:
         
     | 
| 
       818 
     | 
    
         
            -
             * 
     | 
| 
      
 990 
     | 
    
         
            +
             *
         
     | 
| 
       819 
991 
     | 
    
         
             
             *   - `compileDebug` when `false` debugging code is stripped from the compiled template
         
     | 
| 
       820 
992 
     | 
    
         
             
             *   - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()`
         
     | 
| 
       821 
993 
     | 
    
         
             
             *      for use with the Jade client-side runtime.js
         
     | 
| 
         @@ -834,29 +1006,31 @@ exports.compile = function(str, options){ 
     | 
|
| 
       834 
1006 
     | 
    
         
             
                  : 'undefined'
         
     | 
| 
       835 
1007 
     | 
    
         
             
                , fn;
         
     | 
| 
       836 
1008 
     | 
    
         | 
| 
      
 1009 
     | 
    
         
            +
              str = stripBOM(String(str));
         
     | 
| 
      
 1010 
     | 
    
         
            +
             
     | 
| 
       837 
1011 
     | 
    
         
             
              if (options.compileDebug !== false) {
         
     | 
| 
       838 
1012 
     | 
    
         
             
                fn = [
         
     | 
| 
       839 
     | 
    
         
            -
                    'var  
     | 
| 
      
 1013 
     | 
    
         
            +
                    'var __jade = [{ lineno: 1, filename: ' + filename + ' }];'
         
     | 
| 
       840 
1014 
     | 
    
         
             
                  , 'try {'
         
     | 
| 
       841 
     | 
    
         
            -
                  , parse( 
     | 
| 
      
 1015 
     | 
    
         
            +
                  , parse(str, options)
         
     | 
| 
       842 
1016 
     | 
    
         
             
                  , '} catch (err) {'
         
     | 
| 
       843 
     | 
    
         
            -
                  , '  rethrow(err,  
     | 
| 
      
 1017 
     | 
    
         
            +
                  , '  rethrow(err, __jade[0].filename, __jade[0].lineno);'
         
     | 
| 
       844 
1018 
     | 
    
         
             
                  , '}'
         
     | 
| 
       845 
1019 
     | 
    
         
             
                ].join('\n');
         
     | 
| 
       846 
1020 
     | 
    
         
             
              } else {
         
     | 
| 
       847 
     | 
    
         
            -
                fn = parse( 
     | 
| 
      
 1021 
     | 
    
         
            +
                fn = parse(str, options);
         
     | 
| 
       848 
1022 
     | 
    
         
             
              }
         
     | 
| 
       849 
1023 
     | 
    
         | 
| 
       850 
1024 
     | 
    
         
             
              if (client) {
         
     | 
| 
       851 
     | 
    
         
            -
                fn = ' 
     | 
| 
      
 1025 
     | 
    
         
            +
                fn = 'attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;\n' + fn;
         
     | 
| 
       852 
1026 
     | 
    
         
             
              }
         
     | 
| 
       853 
1027 
     | 
    
         | 
| 
       854 
     | 
    
         
            -
              fn = new Function('locals, attrs, escape, rethrow', fn);
         
     | 
| 
      
 1028 
     | 
    
         
            +
              fn = new Function('locals, attrs, escape, rethrow, merge', fn);
         
     | 
| 
       855 
1029 
     | 
    
         | 
| 
       856 
1030 
     | 
    
         
             
              if (client) return fn;
         
     | 
| 
       857 
1031 
     | 
    
         | 
| 
       858 
1032 
     | 
    
         
             
              return function(locals){
         
     | 
| 
       859 
     | 
    
         
            -
                return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow);
         
     | 
| 
      
 1033 
     | 
    
         
            +
                return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow, runtime.merge);
         
     | 
| 
       860 
1034 
     | 
    
         
             
              };
         
     | 
| 
       861 
1035 
     | 
    
         
             
            };
         
     | 
| 
       862 
1036 
     | 
    
         | 
| 
         @@ -929,16 +1103,18 @@ exports.renderFile = function(path, options, fn){ 
     | 
|
| 
       929 
1103 
     | 
    
         
             
             */
         
     | 
| 
       930 
1104 
     | 
    
         | 
| 
       931 
1105 
     | 
    
         
             
            exports.__express = exports.renderFile;
         
     | 
| 
      
 1106 
     | 
    
         
            +
             
     | 
| 
       932 
1107 
     | 
    
         
             
            }); // module: jade.js
         
     | 
| 
       933 
1108 
     | 
    
         | 
| 
       934 
1109 
     | 
    
         
             
            require.register("lexer.js", function(module, exports, require){
         
     | 
| 
       935 
     | 
    
         
            -
             
     | 
| 
       936 
1110 
     | 
    
         
             
            /*!
         
     | 
| 
       937 
1111 
     | 
    
         
             
             * Jade - Lexer
         
     | 
| 
       938 
1112 
     | 
    
         
             
             * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
         
     | 
| 
       939 
1113 
     | 
    
         
             
             * MIT Licensed
         
     | 
| 
       940 
1114 
     | 
    
         
             
             */
         
     | 
| 
       941 
1115 
     | 
    
         | 
| 
      
 1116 
     | 
    
         
            +
            var utils = require('./utils');
         
     | 
| 
      
 1117 
     | 
    
         
            +
             
     | 
| 
       942 
1118 
     | 
    
         
             
            /**
         
     | 
| 
       943 
1119 
     | 
    
         
             
             * Initialize `Lexer` with the given `str`.
         
     | 
| 
       944 
1120 
     | 
    
         
             
             *
         
     | 
| 
         @@ -1055,9 +1231,9 @@ Lexer.prototype = { 
     | 
|
| 
       1055 
1231 
     | 
    
         
             
                  , nend = 0
         
     | 
| 
       1056 
1232 
     | 
    
         
             
                  , pos = 0;
         
     | 
| 
       1057 
1233 
     | 
    
         
             
                for (var i = 0, len = str.length; i < len; ++i) {
         
     | 
| 
       1058 
     | 
    
         
            -
                  if (start == str 
     | 
| 
      
 1234 
     | 
    
         
            +
                  if (start == str.charAt(i)) {
         
     | 
| 
       1059 
1235 
     | 
    
         
             
                    ++nstart;
         
     | 
| 
       1060 
     | 
    
         
            -
                  } else if (end == str 
     | 
| 
      
 1236 
     | 
    
         
            +
                  } else if (end == str.charAt(i)) {
         
     | 
| 
       1061 
1237 
     | 
    
         
             
                    if (++nend == nstart) {
         
     | 
| 
       1062 
1238 
     | 
    
         
             
                      pos = i;
         
     | 
| 
       1063 
1239 
     | 
    
         
             
                      break;
         
     | 
| 
         @@ -1099,6 +1275,19 @@ Lexer.prototype = { 
     | 
|
| 
       1099 
1275 
     | 
    
         
             
                }
         
     | 
| 
       1100 
1276 
     | 
    
         
             
              },
         
     | 
| 
       1101 
1277 
     | 
    
         | 
| 
      
 1278 
     | 
    
         
            +
              /**
         
     | 
| 
      
 1279 
     | 
    
         
            +
               * Blank line.
         
     | 
| 
      
 1280 
     | 
    
         
            +
               */
         
     | 
| 
      
 1281 
     | 
    
         
            +
              
         
     | 
| 
      
 1282 
     | 
    
         
            +
              blank: function() {
         
     | 
| 
      
 1283 
     | 
    
         
            +
                var captures;
         
     | 
| 
      
 1284 
     | 
    
         
            +
                if (captures = /^\n *\n/.exec(this.input)) {
         
     | 
| 
      
 1285 
     | 
    
         
            +
                  this.consume(captures[0].length - 1);
         
     | 
| 
      
 1286 
     | 
    
         
            +
                  if (this.pipeless) return this.tok('text', '');
         
     | 
| 
      
 1287 
     | 
    
         
            +
                  return this.next();
         
     | 
| 
      
 1288 
     | 
    
         
            +
                }
         
     | 
| 
      
 1289 
     | 
    
         
            +
              },
         
     | 
| 
      
 1290 
     | 
    
         
            +
             
     | 
| 
       1102 
1291 
     | 
    
         
             
              /**
         
     | 
| 
       1103 
1292 
     | 
    
         
             
               * Comment.
         
     | 
| 
       1104 
1293 
     | 
    
         
             
               */
         
     | 
| 
         @@ -1112,14 +1301,26 @@ Lexer.prototype = { 
     | 
|
| 
       1112 
1301 
     | 
    
         
             
                  return tok;
         
     | 
| 
       1113 
1302 
     | 
    
         
             
                }
         
     | 
| 
       1114 
1303 
     | 
    
         
             
              },
         
     | 
| 
       1115 
     | 
    
         
            -
             
     | 
| 
      
 1304 
     | 
    
         
            +
             
     | 
| 
      
 1305 
     | 
    
         
            +
              /**
         
     | 
| 
      
 1306 
     | 
    
         
            +
               * Interpolated tag.
         
     | 
| 
      
 1307 
     | 
    
         
            +
               */
         
     | 
| 
      
 1308 
     | 
    
         
            +
             
     | 
| 
      
 1309 
     | 
    
         
            +
              interpolation: function() {
         
     | 
| 
      
 1310 
     | 
    
         
            +
                var captures;
         
     | 
| 
      
 1311 
     | 
    
         
            +
                if (captures = /^#\{(.*?)\}/.exec(this.input)) {
         
     | 
| 
      
 1312 
     | 
    
         
            +
                  this.consume(captures[0].length);
         
     | 
| 
      
 1313 
     | 
    
         
            +
                  return this.tok('interpolation', captures[1]);
         
     | 
| 
      
 1314 
     | 
    
         
            +
                }
         
     | 
| 
      
 1315 
     | 
    
         
            +
              },
         
     | 
| 
      
 1316 
     | 
    
         
            +
             
     | 
| 
       1116 
1317 
     | 
    
         
             
              /**
         
     | 
| 
       1117 
1318 
     | 
    
         
             
               * Tag.
         
     | 
| 
       1118 
1319 
     | 
    
         
             
               */
         
     | 
| 
       1119 
1320 
     | 
    
         | 
| 
       1120 
1321 
     | 
    
         
             
              tag: function() {
         
     | 
| 
       1121 
1322 
     | 
    
         
             
                var captures;
         
     | 
| 
       1122 
     | 
    
         
            -
                if (captures = /^(\w[-:\w]*)/.exec(this.input)) {
         
     | 
| 
      
 1323 
     | 
    
         
            +
                if (captures = /^(\w[-:\w]*)(\/?)/.exec(this.input)) {
         
     | 
| 
       1123 
1324 
     | 
    
         
             
                  this.consume(captures[0].length);
         
     | 
| 
       1124 
1325 
     | 
    
         
             
                  var tok, name = captures[1];
         
     | 
| 
       1125 
1326 
     | 
    
         
             
                  if (':' == name[name.length - 1]) {
         
     | 
| 
         @@ -1130,6 +1331,7 @@ Lexer.prototype = { 
     | 
|
| 
       1130 
1331 
     | 
    
         
             
                  } else {
         
     | 
| 
       1131 
1332 
     | 
    
         
             
                    tok = this.tok('tag', name);
         
     | 
| 
       1132 
1333 
     | 
    
         
             
                  }
         
     | 
| 
      
 1334 
     | 
    
         
            +
                  tok.selfClosing = !! captures[2];
         
     | 
| 
       1133 
1335 
     | 
    
         
             
                  return tok;
         
     | 
| 
       1134 
1336 
     | 
    
         
             
                }
         
     | 
| 
       1135 
1337 
     | 
    
         
             
              },
         
     | 
| 
         @@ -1171,15 +1373,15 @@ Lexer.prototype = { 
     | 
|
| 
       1171 
1373 
     | 
    
         
             
               */
         
     | 
| 
       1172 
1374 
     | 
    
         | 
| 
       1173 
1375 
     | 
    
         
             
              text: function() {
         
     | 
| 
       1174 
     | 
    
         
            -
                return this.scan(/^(?:\| ?)?([^\n]+)/, 'text');
         
     | 
| 
      
 1376 
     | 
    
         
            +
                return this.scan(/^(?:\| ?| ?)?([^\n]+)/, 'text');
         
     | 
| 
       1175 
1377 
     | 
    
         
             
              },
         
     | 
| 
       1176 
1378 
     | 
    
         | 
| 
       1177 
1379 
     | 
    
         
             
              /**
         
     | 
| 
       1178 
1380 
     | 
    
         
             
               * Extends.
         
     | 
| 
       1179 
1381 
     | 
    
         
             
               */
         
     | 
| 
       1180 
1382 
     | 
    
         | 
| 
       1181 
     | 
    
         
            -
              extends: function() {
         
     | 
| 
       1182 
     | 
    
         
            -
                return this.scan(/^extends +([^\n]+)/, 'extends');
         
     | 
| 
      
 1383 
     | 
    
         
            +
              "extends": function() {
         
     | 
| 
      
 1384 
     | 
    
         
            +
                return this.scan(/^extends? +([^\n]+)/, 'extends');
         
     | 
| 
       1183 
1385 
     | 
    
         
             
              },
         
     | 
| 
       1184 
1386 
     | 
    
         | 
| 
       1185 
1387 
     | 
    
         
             
              /**
         
     | 
| 
         @@ -1220,16 +1422,25 @@ Lexer.prototype = { 
     | 
|
| 
       1220 
1422 
     | 
    
         | 
| 
       1221 
1423 
     | 
    
         
             
              block: function() {
         
     | 
| 
       1222 
1424 
     | 
    
         
             
                var captures;
         
     | 
| 
       1223 
     | 
    
         
            -
                if (captures = /^block  
     | 
| 
      
 1425 
     | 
    
         
            +
                if (captures = /^block\b *(?:(prepend|append) +)?([^\n]*)/.exec(this.input)) {
         
     | 
| 
       1224 
1426 
     | 
    
         
             
                  this.consume(captures[0].length);
         
     | 
| 
       1225 
1427 
     | 
    
         
             
                  var mode = captures[1] || 'replace'
         
     | 
| 
       1226 
1428 
     | 
    
         
             
                    , name = captures[2]
         
     | 
| 
       1227 
1429 
     | 
    
         
             
                    , tok = this.tok('block', name);
         
     | 
| 
      
 1430 
     | 
    
         
            +
             
     | 
| 
       1228 
1431 
     | 
    
         
             
                  tok.mode = mode;
         
     | 
| 
       1229 
1432 
     | 
    
         
             
                  return tok;
         
     | 
| 
       1230 
1433 
     | 
    
         
             
                }
         
     | 
| 
       1231 
1434 
     | 
    
         
             
              },
         
     | 
| 
       1232 
1435 
     | 
    
         | 
| 
      
 1436 
     | 
    
         
            +
              /**
         
     | 
| 
      
 1437 
     | 
    
         
            +
               * Yield.
         
     | 
| 
      
 1438 
     | 
    
         
            +
               */
         
     | 
| 
      
 1439 
     | 
    
         
            +
              
         
     | 
| 
      
 1440 
     | 
    
         
            +
              yield: function() {
         
     | 
| 
      
 1441 
     | 
    
         
            +
                return this.scan(/^yield */, 'yield');
         
     | 
| 
      
 1442 
     | 
    
         
            +
              },
         
     | 
| 
      
 1443 
     | 
    
         
            +
             
     | 
| 
       1233 
1444 
     | 
    
         
             
              /**
         
     | 
| 
       1234 
1445 
     | 
    
         
             
               * Include.
         
     | 
| 
       1235 
1446 
     | 
    
         
             
               */
         
     | 
| 
         @@ -1242,7 +1453,7 @@ Lexer.prototype = { 
     | 
|
| 
       1242 
1453 
     | 
    
         
             
               * Case.
         
     | 
| 
       1243 
1454 
     | 
    
         
             
               */
         
     | 
| 
       1244 
1455 
     | 
    
         | 
| 
       1245 
     | 
    
         
            -
              case: function() {
         
     | 
| 
      
 1456 
     | 
    
         
            +
              "case": function() {
         
     | 
| 
       1246 
1457 
     | 
    
         
             
                return this.scan(/^case +([^\n]+)/, 'case');
         
     | 
| 
       1247 
1458 
     | 
    
         
             
              },
         
     | 
| 
       1248 
1459 
     | 
    
         | 
| 
         @@ -1258,7 +1469,7 @@ Lexer.prototype = { 
     | 
|
| 
       1258 
1469 
     | 
    
         
             
               * Default.
         
     | 
| 
       1259 
1470 
     | 
    
         
             
               */
         
     | 
| 
       1260 
1471 
     | 
    
         | 
| 
       1261 
     | 
    
         
            -
              default: function() {
         
     | 
| 
      
 1472 
     | 
    
         
            +
              "default": function() {
         
     | 
| 
       1262 
1473 
     | 
    
         
             
                return this.scan(/^default */, 'default');
         
     | 
| 
       1263 
1474 
     | 
    
         
             
              },
         
     | 
| 
       1264 
1475 
     | 
    
         | 
| 
         @@ -1276,13 +1487,35 @@ Lexer.prototype = { 
     | 
|
| 
       1276 
1487 
     | 
    
         
             
                }
         
     | 
| 
       1277 
1488 
     | 
    
         
             
              },
         
     | 
| 
       1278 
1489 
     | 
    
         | 
| 
      
 1490 
     | 
    
         
            +
              /**
         
     | 
| 
      
 1491 
     | 
    
         
            +
               * Call mixin.
         
     | 
| 
      
 1492 
     | 
    
         
            +
               */
         
     | 
| 
      
 1493 
     | 
    
         
            +
              
         
     | 
| 
      
 1494 
     | 
    
         
            +
              call: function(){
         
     | 
| 
      
 1495 
     | 
    
         
            +
                var captures;
         
     | 
| 
      
 1496 
     | 
    
         
            +
                if (captures = /^\+([-\w]+)/.exec(this.input)) {
         
     | 
| 
      
 1497 
     | 
    
         
            +
                  this.consume(captures[0].length);
         
     | 
| 
      
 1498 
     | 
    
         
            +
                  var tok = this.tok('call', captures[1]);
         
     | 
| 
      
 1499 
     | 
    
         
            +
                  
         
     | 
| 
      
 1500 
     | 
    
         
            +
                  // Check for args (not attributes)
         
     | 
| 
      
 1501 
     | 
    
         
            +
                  if (captures = /^ *\((.*?)\)/.exec(this.input)) {
         
     | 
| 
      
 1502 
     | 
    
         
            +
                    if (!/^ *[-\w]+ *=/.test(captures[1])) {
         
     | 
| 
      
 1503 
     | 
    
         
            +
                      this.consume(captures[0].length);
         
     | 
| 
      
 1504 
     | 
    
         
            +
                      tok.args = captures[1];
         
     | 
| 
      
 1505 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1506 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1507 
     | 
    
         
            +
                  
         
     | 
| 
      
 1508 
     | 
    
         
            +
                  return tok;
         
     | 
| 
      
 1509 
     | 
    
         
            +
                }
         
     | 
| 
      
 1510 
     | 
    
         
            +
              },
         
     | 
| 
      
 1511 
     | 
    
         
            +
             
     | 
| 
       1279 
1512 
     | 
    
         
             
              /**
         
     | 
| 
       1280 
1513 
     | 
    
         
             
               * Mixin.
         
     | 
| 
       1281 
1514 
     | 
    
         
             
               */
         
     | 
| 
       1282 
1515 
     | 
    
         | 
| 
       1283 
1516 
     | 
    
         
             
              mixin: function(){
         
     | 
| 
       1284 
1517 
     | 
    
         
             
                var captures;
         
     | 
| 
       1285 
     | 
    
         
            -
                if (captures = /^mixin +([-\w]+)( 
     | 
| 
      
 1518 
     | 
    
         
            +
                if (captures = /^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)) {
         
     | 
| 
       1286 
1519 
     | 
    
         
             
                  this.consume(captures[0].length);
         
     | 
| 
       1287 
1520 
     | 
    
         
             
                  var tok = this.tok('mixin', captures[1]);
         
     | 
| 
       1288 
1521 
     | 
    
         
             
                  tok.args = captures[2];
         
     | 
| 
         @@ -1316,7 +1549,7 @@ Lexer.prototype = { 
     | 
|
| 
       1316 
1549 
     | 
    
         
             
               * While.
         
     | 
| 
       1317 
1550 
     | 
    
         
             
               */
         
     | 
| 
       1318 
1551 
     | 
    
         | 
| 
       1319 
     | 
    
         
            -
              while: function() {
         
     | 
| 
      
 1552 
     | 
    
         
            +
              "while": function() {
         
     | 
| 
       1320 
1553 
     | 
    
         
             
                var captures;
         
     | 
| 
       1321 
1554 
     | 
    
         
             
                if (captures = /^while +([^\n]+)/.exec(this.input)) {
         
     | 
| 
       1322 
1555 
     | 
    
         
             
                  this.consume(captures[0].length);
         
     | 
| 
         @@ -1350,8 +1583,8 @@ Lexer.prototype = { 
     | 
|
| 
       1350 
1583 
     | 
    
         
             
                  var flags = captures[1];
         
     | 
| 
       1351 
1584 
     | 
    
         
             
                  captures[1] = captures[2];
         
     | 
| 
       1352 
1585 
     | 
    
         
             
                  var tok = this.tok('code', captures[1]);
         
     | 
| 
       1353 
     | 
    
         
            -
                  tok.escape = flags 
     | 
| 
       1354 
     | 
    
         
            -
                  tok.buffer = flags 
     | 
| 
      
 1586 
     | 
    
         
            +
                  tok.escape = flags.charAt(0) === '=';
         
     | 
| 
      
 1587 
     | 
    
         
            +
                  tok.buffer = flags.charAt(0) === '=' || flags.charAt(1) === '=';
         
     | 
| 
       1355 
1588 
     | 
    
         
             
                  return tok;
         
     | 
| 
       1356 
1589 
     | 
    
         
             
                }
         
     | 
| 
       1357 
1590 
     | 
    
         
             
              },
         
     | 
| 
         @@ -1361,30 +1594,35 @@ Lexer.prototype = { 
     | 
|
| 
       1361 
1594 
     | 
    
         
             
               */
         
     | 
| 
       1362 
1595 
     | 
    
         | 
| 
       1363 
1596 
     | 
    
         
             
              attrs: function() {
         
     | 
| 
       1364 
     | 
    
         
            -
                if ('(' == this.input 
     | 
| 
      
 1597 
     | 
    
         
            +
                if ('(' == this.input.charAt(0)) {
         
     | 
| 
       1365 
1598 
     | 
    
         
             
                  var index = this.indexOfDelimiters('(', ')')
         
     | 
| 
       1366 
1599 
     | 
    
         
             
                    , str = this.input.substr(1, index-1)
         
     | 
| 
       1367 
1600 
     | 
    
         
             
                    , tok = this.tok('attrs')
         
     | 
| 
       1368 
1601 
     | 
    
         
             
                    , len = str.length
         
     | 
| 
       1369 
1602 
     | 
    
         
             
                    , colons = this.colons
         
     | 
| 
       1370 
1603 
     | 
    
         
             
                    , states = ['key']
         
     | 
| 
      
 1604 
     | 
    
         
            +
                    , escapedAttr
         
     | 
| 
       1371 
1605 
     | 
    
         
             
                    , key = ''
         
     | 
| 
       1372 
1606 
     | 
    
         
             
                    , val = ''
         
     | 
| 
       1373 
1607 
     | 
    
         
             
                    , quote
         
     | 
| 
       1374 
     | 
    
         
            -
                    , c 
     | 
| 
      
 1608 
     | 
    
         
            +
                    , c
         
     | 
| 
      
 1609 
     | 
    
         
            +
                    , p;
         
     | 
| 
       1375 
1610 
     | 
    
         | 
| 
       1376 
1611 
     | 
    
         
             
                  function state(){
         
     | 
| 
       1377 
1612 
     | 
    
         
             
                    return states[states.length - 1];
         
     | 
| 
       1378 
1613 
     | 
    
         
             
                  }
         
     | 
| 
       1379 
1614 
     | 
    
         | 
| 
       1380 
1615 
     | 
    
         
             
                  function interpolate(attr) {
         
     | 
| 
       1381 
     | 
    
         
            -
                    return attr.replace( 
     | 
| 
       1382 
     | 
    
         
            -
                      return  
     | 
| 
      
 1616 
     | 
    
         
            +
                    return attr.replace(/(\\)?#\{([^}]+)\}/g, function(_, escape, expr){
         
     | 
| 
      
 1617 
     | 
    
         
            +
                      return escape
         
     | 
| 
      
 1618 
     | 
    
         
            +
                         ? _
         
     | 
| 
      
 1619 
     | 
    
         
            +
                         : quote + " + (" + expr + ") + " + quote;
         
     | 
| 
       1383 
1620 
     | 
    
         
             
                    });
         
     | 
| 
       1384 
1621 
     | 
    
         
             
                  }
         
     | 
| 
       1385 
1622 
     | 
    
         | 
| 
       1386 
1623 
     | 
    
         
             
                  this.consume(index + 1);
         
     | 
| 
       1387 
1624 
     | 
    
         
             
                  tok.attrs = {};
         
     | 
| 
      
 1625 
     | 
    
         
            +
                  tok.escaped = {};
         
     | 
| 
       1388 
1626 
     | 
    
         | 
| 
       1389 
1627 
     | 
    
         
             
                  function parse(c) {
         
     | 
| 
       1390 
1628 
     | 
    
         
             
                    var real = c;
         
     | 
| 
         @@ -1405,7 +1643,9 @@ Lexer.prototype = { 
     | 
|
| 
       1405 
1643 
     | 
    
         
             
                            val = val.trim();
         
     | 
| 
       1406 
1644 
     | 
    
         
             
                            key = key.trim();
         
     | 
| 
       1407 
1645 
     | 
    
         
             
                            if ('' == key) return;
         
     | 
| 
       1408 
     | 
    
         
            -
                             
     | 
| 
      
 1646 
     | 
    
         
            +
                            key = key.replace(/^['"]|['"]$/g, '').replace('!', '');
         
     | 
| 
      
 1647 
     | 
    
         
            +
                            tok.escaped[key] = escapedAttr;
         
     | 
| 
      
 1648 
     | 
    
         
            +
                            tok.attrs[key] = '' == val
         
     | 
| 
       1409 
1649 
     | 
    
         
             
                              ? true
         
     | 
| 
       1410 
1650 
     | 
    
         
             
                              : interpolate(val);
         
     | 
| 
       1411 
1651 
     | 
    
         
             
                            key = val = '';
         
     | 
| 
         @@ -1424,6 +1664,7 @@ Lexer.prototype = { 
     | 
|
| 
       1424 
1664 
     | 
    
         
             
                            val += real;
         
     | 
| 
       1425 
1665 
     | 
    
         
             
                            break;
         
     | 
| 
       1426 
1666 
     | 
    
         
             
                          default:
         
     | 
| 
      
 1667 
     | 
    
         
            +
                            escapedAttr = '!' != p;
         
     | 
| 
       1427 
1668 
     | 
    
         
             
                            states.push('val');
         
     | 
| 
       1428 
1669 
     | 
    
         
             
                        }
         
     | 
| 
       1429 
1670 
     | 
    
         
             
                        break;
         
     | 
| 
         @@ -1484,14 +1725,20 @@ Lexer.prototype = { 
     | 
|
| 
       1484 
1725 
     | 
    
         
             
                            val += c;
         
     | 
| 
       1485 
1726 
     | 
    
         
             
                        }
         
     | 
| 
       1486 
1727 
     | 
    
         
             
                    }
         
     | 
| 
      
 1728 
     | 
    
         
            +
                    p = c;
         
     | 
| 
       1487 
1729 
     | 
    
         
             
                  }
         
     | 
| 
       1488 
1730 
     | 
    
         | 
| 
       1489 
1731 
     | 
    
         
             
                  for (var i = 0; i < len; ++i) {
         
     | 
| 
       1490 
     | 
    
         
            -
                    parse(str 
     | 
| 
      
 1732 
     | 
    
         
            +
                    parse(str.charAt(i));
         
     | 
| 
       1491 
1733 
     | 
    
         
             
                  }
         
     | 
| 
       1492 
1734 
     | 
    
         | 
| 
       1493 
1735 
     | 
    
         
             
                  parse(',');
         
     | 
| 
       1494 
1736 
     | 
    
         | 
| 
      
 1737 
     | 
    
         
            +
                  if ('/' == this.input.charAt(0)) {
         
     | 
| 
      
 1738 
     | 
    
         
            +
                    this.consume(1);
         
     | 
| 
      
 1739 
     | 
    
         
            +
                    tok.selfClosing = true;
         
     | 
| 
      
 1740 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1741 
     | 
    
         
            +
             
     | 
| 
       1495 
1742 
     | 
    
         
             
                  return tok;
         
     | 
| 
       1496 
1743 
     | 
    
         
             
                }
         
     | 
| 
       1497 
1744 
     | 
    
         
             
              },
         
     | 
| 
         @@ -1602,21 +1849,25 @@ Lexer.prototype = { 
     | 
|
| 
       1602 
1849 
     | 
    
         | 
| 
       1603 
1850 
     | 
    
         
             
              next: function() {
         
     | 
| 
       1604 
1851 
     | 
    
         
             
                return this.deferred()
         
     | 
| 
      
 1852 
     | 
    
         
            +
                  || this.blank()
         
     | 
| 
       1605 
1853 
     | 
    
         
             
                  || this.eos()
         
     | 
| 
       1606 
1854 
     | 
    
         
             
                  || this.pipelessText()
         
     | 
| 
      
 1855 
     | 
    
         
            +
                  || this.yield()
         
     | 
| 
       1607 
1856 
     | 
    
         
             
                  || this.doctype()
         
     | 
| 
       1608 
     | 
    
         
            -
                  || this. 
     | 
| 
      
 1857 
     | 
    
         
            +
                  || this.interpolation()
         
     | 
| 
      
 1858 
     | 
    
         
            +
                  || this["case"]()
         
     | 
| 
       1609 
1859 
     | 
    
         
             
                  || this.when()
         
     | 
| 
       1610 
     | 
    
         
            -
                  || this 
     | 
| 
       1611 
     | 
    
         
            -
                  || this 
     | 
| 
      
 1860 
     | 
    
         
            +
                  || this["default"]()
         
     | 
| 
      
 1861 
     | 
    
         
            +
                  || this["extends"]()
         
     | 
| 
       1612 
1862 
     | 
    
         
             
                  || this.append()
         
     | 
| 
       1613 
1863 
     | 
    
         
             
                  || this.prepend()
         
     | 
| 
       1614 
1864 
     | 
    
         
             
                  || this.block()
         
     | 
| 
       1615 
1865 
     | 
    
         
             
                  || this.include()
         
     | 
| 
       1616 
1866 
     | 
    
         
             
                  || this.mixin()
         
     | 
| 
      
 1867 
     | 
    
         
            +
                  || this.call()
         
     | 
| 
       1617 
1868 
     | 
    
         
             
                  || this.conditional()
         
     | 
| 
       1618 
1869 
     | 
    
         
             
                  || this.each()
         
     | 
| 
       1619 
     | 
    
         
            -
                  || this 
     | 
| 
      
 1870 
     | 
    
         
            +
                  || this["while"]()
         
     | 
| 
       1620 
1871 
     | 
    
         
             
                  || this.assignment()
         
     | 
| 
       1621 
1872 
     | 
    
         
             
                  || this.tag()
         
     | 
| 
       1622 
1873 
     | 
    
         
             
                  || this.filter()
         
     | 
| 
         @@ -1633,6 +1884,89 @@ Lexer.prototype = { 
     | 
|
| 
       1633 
1884 
     | 
    
         | 
| 
       1634 
1885 
     | 
    
         
             
            }); // module: lexer.js
         
     | 
| 
       1635 
1886 
     | 
    
         | 
| 
      
 1887 
     | 
    
         
            +
            require.register("nodes/attrs.js", function(module, exports, require){
         
     | 
| 
      
 1888 
     | 
    
         
            +
             
     | 
| 
      
 1889 
     | 
    
         
            +
            /*!
         
     | 
| 
      
 1890 
     | 
    
         
            +
             * Jade - nodes - Attrs
         
     | 
| 
      
 1891 
     | 
    
         
            +
             * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
         
     | 
| 
      
 1892 
     | 
    
         
            +
             * MIT Licensed
         
     | 
| 
      
 1893 
     | 
    
         
            +
             */
         
     | 
| 
      
 1894 
     | 
    
         
            +
             
     | 
| 
      
 1895 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1896 
     | 
    
         
            +
             * Module dependencies.
         
     | 
| 
      
 1897 
     | 
    
         
            +
             */
         
     | 
| 
      
 1898 
     | 
    
         
            +
             
     | 
| 
      
 1899 
     | 
    
         
            +
            var Node = require('./node'),
         
     | 
| 
      
 1900 
     | 
    
         
            +
                Block = require('./block');
         
     | 
| 
      
 1901 
     | 
    
         
            +
             
     | 
| 
      
 1902 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1903 
     | 
    
         
            +
             * Initialize a `Attrs` node.
         
     | 
| 
      
 1904 
     | 
    
         
            +
             *
         
     | 
| 
      
 1905 
     | 
    
         
            +
             * @api public
         
     | 
| 
      
 1906 
     | 
    
         
            +
             */
         
     | 
| 
      
 1907 
     | 
    
         
            +
             
     | 
| 
      
 1908 
     | 
    
         
            +
            var Attrs = module.exports = function Attrs() {
         
     | 
| 
      
 1909 
     | 
    
         
            +
              this.attrs = [];
         
     | 
| 
      
 1910 
     | 
    
         
            +
            };
         
     | 
| 
      
 1911 
     | 
    
         
            +
             
     | 
| 
      
 1912 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1913 
     | 
    
         
            +
             * Inherit from `Node`.
         
     | 
| 
      
 1914 
     | 
    
         
            +
             */
         
     | 
| 
      
 1915 
     | 
    
         
            +
             
     | 
| 
      
 1916 
     | 
    
         
            +
            Attrs.prototype = new Node;
         
     | 
| 
      
 1917 
     | 
    
         
            +
            Attrs.prototype.constructor = Attrs;
         
     | 
| 
      
 1918 
     | 
    
         
            +
             
     | 
| 
      
 1919 
     | 
    
         
            +
             
     | 
| 
      
 1920 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1921 
     | 
    
         
            +
             * Set attribute `name` to `val`, keep in mind these become
         
     | 
| 
      
 1922 
     | 
    
         
            +
             * part of a raw js object literal, so to quote a value you must
         
     | 
| 
      
 1923 
     | 
    
         
            +
             * '"quote me"', otherwise or example 'user.name' is literal JavaScript.
         
     | 
| 
      
 1924 
     | 
    
         
            +
             *
         
     | 
| 
      
 1925 
     | 
    
         
            +
             * @param {String} name
         
     | 
| 
      
 1926 
     | 
    
         
            +
             * @param {String} val
         
     | 
| 
      
 1927 
     | 
    
         
            +
             * @param {Boolean} escaped
         
     | 
| 
      
 1928 
     | 
    
         
            +
             * @return {Tag} for chaining
         
     | 
| 
      
 1929 
     | 
    
         
            +
             * @api public
         
     | 
| 
      
 1930 
     | 
    
         
            +
             */
         
     | 
| 
      
 1931 
     | 
    
         
            +
             
     | 
| 
      
 1932 
     | 
    
         
            +
            Attrs.prototype.setAttribute = function(name, val, escaped){
         
     | 
| 
      
 1933 
     | 
    
         
            +
              this.attrs.push({ name: name, val: val, escaped: escaped });
         
     | 
| 
      
 1934 
     | 
    
         
            +
              return this;
         
     | 
| 
      
 1935 
     | 
    
         
            +
            };
         
     | 
| 
      
 1936 
     | 
    
         
            +
             
     | 
| 
      
 1937 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1938 
     | 
    
         
            +
             * Remove attribute `name` when present.
         
     | 
| 
      
 1939 
     | 
    
         
            +
             *
         
     | 
| 
      
 1940 
     | 
    
         
            +
             * @param {String} name
         
     | 
| 
      
 1941 
     | 
    
         
            +
             * @api public
         
     | 
| 
      
 1942 
     | 
    
         
            +
             */
         
     | 
| 
      
 1943 
     | 
    
         
            +
             
     | 
| 
      
 1944 
     | 
    
         
            +
            Attrs.prototype.removeAttribute = function(name){
         
     | 
| 
      
 1945 
     | 
    
         
            +
              for (var i = 0, len = this.attrs.length; i < len; ++i) {
         
     | 
| 
      
 1946 
     | 
    
         
            +
                if (this.attrs[i] && this.attrs[i].name == name) {
         
     | 
| 
      
 1947 
     | 
    
         
            +
                  delete this.attrs[i];
         
     | 
| 
      
 1948 
     | 
    
         
            +
                }
         
     | 
| 
      
 1949 
     | 
    
         
            +
              }
         
     | 
| 
      
 1950 
     | 
    
         
            +
            };
         
     | 
| 
      
 1951 
     | 
    
         
            +
             
     | 
| 
      
 1952 
     | 
    
         
            +
            /**
         
     | 
| 
      
 1953 
     | 
    
         
            +
             * Get attribute value by `name`.
         
     | 
| 
      
 1954 
     | 
    
         
            +
             *
         
     | 
| 
      
 1955 
     | 
    
         
            +
             * @param {String} name
         
     | 
| 
      
 1956 
     | 
    
         
            +
             * @return {String}
         
     | 
| 
      
 1957 
     | 
    
         
            +
             * @api public
         
     | 
| 
      
 1958 
     | 
    
         
            +
             */
         
     | 
| 
      
 1959 
     | 
    
         
            +
             
     | 
| 
      
 1960 
     | 
    
         
            +
            Attrs.prototype.getAttribute = function(name){
         
     | 
| 
      
 1961 
     | 
    
         
            +
              for (var i = 0, len = this.attrs.length; i < len; ++i) {
         
     | 
| 
      
 1962 
     | 
    
         
            +
                if (this.attrs[i] && this.attrs[i].name == name) {
         
     | 
| 
      
 1963 
     | 
    
         
            +
                  return this.attrs[i].val;
         
     | 
| 
      
 1964 
     | 
    
         
            +
                }
         
     | 
| 
      
 1965 
     | 
    
         
            +
              }
         
     | 
| 
      
 1966 
     | 
    
         
            +
            };
         
     | 
| 
      
 1967 
     | 
    
         
            +
             
     | 
| 
      
 1968 
     | 
    
         
            +
            }); // module: nodes/attrs.js
         
     | 
| 
      
 1969 
     | 
    
         
            +
             
     | 
| 
       1636 
1970 
     | 
    
         
             
            require.register("nodes/block-comment.js", function(module, exports, require){
         
     | 
| 
       1637 
1971 
     | 
    
         | 
| 
       1638 
1972 
     | 
    
         
             
            /*!
         
     | 
| 
         @@ -1705,6 +2039,12 @@ Block.prototype = new Node; 
     | 
|
| 
       1705 
2039 
     | 
    
         
             
            Block.prototype.constructor = Block;
         
     | 
| 
       1706 
2040 
     | 
    
         | 
| 
       1707 
2041 
     | 
    
         | 
| 
      
 2042 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2043 
     | 
    
         
            +
             * Block flag.
         
     | 
| 
      
 2044 
     | 
    
         
            +
             */
         
     | 
| 
      
 2045 
     | 
    
         
            +
             
     | 
| 
      
 2046 
     | 
    
         
            +
            Block.prototype.isBlock = true;
         
     | 
| 
      
 2047 
     | 
    
         
            +
             
     | 
| 
       1708 
2048 
     | 
    
         
             
            /**
         
     | 
| 
       1709 
2049 
     | 
    
         
             
             * Replace the nodes in `other` with the nodes
         
     | 
| 
       1710 
2050 
     | 
    
         
             
             * in `this` block.
         
     | 
| 
         @@ -1753,21 +2093,41 @@ Block.prototype.unshift = function(node){ 
     | 
|
| 
       1753 
2093 
     | 
    
         
             
            };
         
     | 
| 
       1754 
2094 
     | 
    
         | 
| 
       1755 
2095 
     | 
    
         
             
            /**
         
     | 
| 
       1756 
     | 
    
         
            -
             * Return the "last" block.
         
     | 
| 
      
 2096 
     | 
    
         
            +
             * Return the "last" block, or the first `yield` node.
         
     | 
| 
       1757 
2097 
     | 
    
         
             
             *
         
     | 
| 
       1758 
2098 
     | 
    
         
             
             * @return {Block}
         
     | 
| 
       1759 
2099 
     | 
    
         
             
             * @api private
         
     | 
| 
       1760 
2100 
     | 
    
         
             
             */
         
     | 
| 
       1761 
2101 
     | 
    
         | 
| 
       1762 
     | 
    
         
            -
            Block.prototype. 
     | 
| 
       1763 
     | 
    
         
            -
              var  
     | 
| 
      
 2102 
     | 
    
         
            +
            Block.prototype.includeBlock = function(){
         
     | 
| 
      
 2103 
     | 
    
         
            +
              var ret = this
         
     | 
| 
       1764 
2104 
     | 
    
         
             
                , node;
         
     | 
| 
      
 2105 
     | 
    
         
            +
             
     | 
| 
       1765 
2106 
     | 
    
         
             
              for (var i = 0, len = this.nodes.length; i < len; ++i) {
         
     | 
| 
       1766 
2107 
     | 
    
         
             
                node = this.nodes[i];
         
     | 
| 
       1767 
     | 
    
         
            -
                if (node. 
     | 
| 
       1768 
     | 
    
         
            -
                else if (node. 
     | 
| 
      
 2108 
     | 
    
         
            +
                if (node.yield) return node;
         
     | 
| 
      
 2109 
     | 
    
         
            +
                else if (node.textOnly) continue;
         
     | 
| 
      
 2110 
     | 
    
         
            +
                else if (node.includeBlock) ret = node.includeBlock();
         
     | 
| 
      
 2111 
     | 
    
         
            +
                else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock();
         
     | 
| 
      
 2112 
     | 
    
         
            +
                if (ret.yield) return ret;
         
     | 
| 
      
 2113 
     | 
    
         
            +
              }
         
     | 
| 
      
 2114 
     | 
    
         
            +
             
     | 
| 
      
 2115 
     | 
    
         
            +
              return ret;
         
     | 
| 
      
 2116 
     | 
    
         
            +
            };
         
     | 
| 
      
 2117 
     | 
    
         
            +
             
     | 
| 
      
 2118 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2119 
     | 
    
         
            +
             * Return a clone of this block.
         
     | 
| 
      
 2120 
     | 
    
         
            +
             *
         
     | 
| 
      
 2121 
     | 
    
         
            +
             * @return {Block}
         
     | 
| 
      
 2122 
     | 
    
         
            +
             * @api private
         
     | 
| 
      
 2123 
     | 
    
         
            +
             */
         
     | 
| 
      
 2124 
     | 
    
         
            +
             
     | 
| 
      
 2125 
     | 
    
         
            +
            Block.prototype.clone = function(){
         
     | 
| 
      
 2126 
     | 
    
         
            +
              var clone = new Block;
         
     | 
| 
      
 2127 
     | 
    
         
            +
              for (var i = 0, len = this.nodes.length; i < len; ++i) {
         
     | 
| 
      
 2128 
     | 
    
         
            +
                clone.push(this.nodes[i].clone());
         
     | 
| 
       1769 
2129 
     | 
    
         
             
              }
         
     | 
| 
       1770 
     | 
    
         
            -
              return  
     | 
| 
      
 2130 
     | 
    
         
            +
              return clone;
         
     | 
| 
       1771 
2131 
     | 
    
         
             
            };
         
     | 
| 
       1772 
2132 
     | 
    
         | 
| 
       1773 
2133 
     | 
    
         | 
| 
         @@ -2003,7 +2363,7 @@ var Filter = module.exports = function Filter(name, block, attrs) { 
     | 
|
| 
       2003 
2363 
     | 
    
         
             
              this.name = name;
         
     | 
| 
       2004 
2364 
     | 
    
         
             
              this.block = block;
         
     | 
| 
       2005 
2365 
     | 
    
         
             
              this.attrs = attrs;
         
     | 
| 
       2006 
     | 
    
         
            -
              this.isASTFilter = block  
     | 
| 
      
 2366 
     | 
    
         
            +
              this.isASTFilter = !block.nodes.every(function(node){ return node.isText });
         
     | 
| 
       2007 
2367 
     | 
    
         
             
            };
         
     | 
| 
       2008 
2368 
     | 
    
         | 
| 
       2009 
2369 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -2062,7 +2422,8 @@ var Node = require('./node'); 
     | 
|
| 
       2062 
2422 
     | 
    
         | 
| 
       2063 
2423 
     | 
    
         
             
            var Literal = module.exports = function Literal(str) {
         
     | 
| 
       2064 
2424 
     | 
    
         
             
              this.str = str
         
     | 
| 
       2065 
     | 
    
         
            -
                .replace( 
     | 
| 
      
 2425 
     | 
    
         
            +
                .replace(/\\/g, "\\\\")
         
     | 
| 
      
 2426 
     | 
    
         
            +
                .replace(/\n|\r\n/g, "\\n")
         
     | 
| 
       2066 
2427 
     | 
    
         
             
                .replace(/'/g, "\\'");
         
     | 
| 
       2067 
2428 
     | 
    
         
             
            };
         
     | 
| 
       2068 
2429 
     | 
    
         | 
| 
         @@ -2088,7 +2449,7 @@ require.register("nodes/mixin.js", function(module, exports, require){ 
     | 
|
| 
       2088 
2449 
     | 
    
         
             
             * Module dependencies.
         
     | 
| 
       2089 
2450 
     | 
    
         
             
             */
         
     | 
| 
       2090 
2451 
     | 
    
         | 
| 
       2091 
     | 
    
         
            -
            var  
     | 
| 
      
 2452 
     | 
    
         
            +
            var Attrs = require('./attrs');
         
     | 
| 
       2092 
2453 
     | 
    
         | 
| 
       2093 
2454 
     | 
    
         
             
            /**
         
     | 
| 
       2094 
2455 
     | 
    
         
             
             * Initialize a new `Mixin` with `name` and `block`.
         
     | 
| 
         @@ -2099,17 +2460,19 @@ var Node = require('./node'); 
     | 
|
| 
       2099 
2460 
     | 
    
         
             
             * @api public
         
     | 
| 
       2100 
2461 
     | 
    
         
             
             */
         
     | 
| 
       2101 
2462 
     | 
    
         | 
| 
       2102 
     | 
    
         
            -
            var Mixin = module.exports = function Mixin(name, args, block){
         
     | 
| 
      
 2463 
     | 
    
         
            +
            var Mixin = module.exports = function Mixin(name, args, block, call){
         
     | 
| 
       2103 
2464 
     | 
    
         
             
              this.name = name;
         
     | 
| 
       2104 
2465 
     | 
    
         
             
              this.args = args;
         
     | 
| 
       2105 
2466 
     | 
    
         
             
              this.block = block;
         
     | 
| 
      
 2467 
     | 
    
         
            +
              this.attrs = [];
         
     | 
| 
      
 2468 
     | 
    
         
            +
              this.call = call;
         
     | 
| 
       2106 
2469 
     | 
    
         
             
            };
         
     | 
| 
       2107 
2470 
     | 
    
         | 
| 
       2108 
2471 
     | 
    
         
             
            /**
         
     | 
| 
       2109 
     | 
    
         
            -
             * Inherit from ` 
     | 
| 
      
 2472 
     | 
    
         
            +
             * Inherit from `Attrs`.
         
     | 
| 
       2110 
2473 
     | 
    
         
             
             */
         
     | 
| 
       2111 
2474 
     | 
    
         | 
| 
       2112 
     | 
    
         
            -
            Mixin.prototype = new  
     | 
| 
      
 2475 
     | 
    
         
            +
            Mixin.prototype = new Attrs;
         
     | 
| 
       2113 
2476 
     | 
    
         
             
            Mixin.prototype.constructor = Mixin;
         
     | 
| 
       2114 
2477 
     | 
    
         | 
| 
       2115 
2478 
     | 
    
         | 
| 
         @@ -2131,6 +2494,18 @@ require.register("nodes/node.js", function(module, exports, require){ 
     | 
|
| 
       2131 
2494 
     | 
    
         
             
             */
         
     | 
| 
       2132 
2495 
     | 
    
         | 
| 
       2133 
2496 
     | 
    
         
             
            var Node = module.exports = function Node(){};
         
     | 
| 
      
 2497 
     | 
    
         
            +
             
     | 
| 
      
 2498 
     | 
    
         
            +
            /**
         
     | 
| 
      
 2499 
     | 
    
         
            +
             * Clone this node (return itself)
         
     | 
| 
      
 2500 
     | 
    
         
            +
             *
         
     | 
| 
      
 2501 
     | 
    
         
            +
             * @return {Node}
         
     | 
| 
      
 2502 
     | 
    
         
            +
             * @api private
         
     | 
| 
      
 2503 
     | 
    
         
            +
             */
         
     | 
| 
      
 2504 
     | 
    
         
            +
             
     | 
| 
      
 2505 
     | 
    
         
            +
            Node.prototype.clone = function(){
         
     | 
| 
      
 2506 
     | 
    
         
            +
              return this;
         
     | 
| 
      
 2507 
     | 
    
         
            +
            };
         
     | 
| 
      
 2508 
     | 
    
         
            +
             
     | 
| 
       2134 
2509 
     | 
    
         
             
            }); // module: nodes/node.js
         
     | 
| 
       2135 
2510 
     | 
    
         | 
| 
       2136 
2511 
     | 
    
         
             
            require.register("nodes/tag.js", function(module, exports, require){
         
     | 
| 
         @@ -2145,8 +2520,9 @@ require.register("nodes/tag.js", function(module, exports, require){ 
     | 
|
| 
       2145 
2520 
     | 
    
         
             
             * Module dependencies.
         
     | 
| 
       2146 
2521 
     | 
    
         
             
             */
         
     | 
| 
       2147 
2522 
     | 
    
         | 
| 
       2148 
     | 
    
         
            -
            var  
     | 
| 
       2149 
     | 
    
         
            -
                Block = require('./block') 
     | 
| 
      
 2523 
     | 
    
         
            +
            var Attrs = require('./attrs'),
         
     | 
| 
      
 2524 
     | 
    
         
            +
                Block = require('./block'),
         
     | 
| 
      
 2525 
     | 
    
         
            +
                inlineTags = require('../inline-tags');
         
     | 
| 
       2150 
2526 
     | 
    
         | 
| 
       2151 
2527 
     | 
    
         
             
            /**
         
     | 
| 
       2152 
2528 
     | 
    
         
             
             * Initialize a `Tag` node with the given tag `name` and optional `block`.
         
     | 
| 
         @@ -2163,60 +2539,73 @@ var Tag = module.exports = function Tag(name, block) { 
     | 
|
| 
       2163 
2539 
     | 
    
         
             
            };
         
     | 
| 
       2164 
2540 
     | 
    
         | 
| 
       2165 
2541 
     | 
    
         
             
            /**
         
     | 
| 
       2166 
     | 
    
         
            -
             * Inherit from ` 
     | 
| 
      
 2542 
     | 
    
         
            +
             * Inherit from `Attrs`.
         
     | 
| 
       2167 
2543 
     | 
    
         
             
             */
         
     | 
| 
       2168 
2544 
     | 
    
         | 
| 
       2169 
     | 
    
         
            -
            Tag.prototype = new  
     | 
| 
      
 2545 
     | 
    
         
            +
            Tag.prototype = new Attrs;
         
     | 
| 
       2170 
2546 
     | 
    
         
             
            Tag.prototype.constructor = Tag;
         
     | 
| 
       2171 
2547 
     | 
    
         | 
| 
       2172 
2548 
     | 
    
         | 
| 
       2173 
2549 
     | 
    
         
             
            /**
         
     | 
| 
       2174 
     | 
    
         
            -
             *  
     | 
| 
       2175 
     | 
    
         
            -
             * part of a raw js object literal, so to quote a value you must
         
     | 
| 
       2176 
     | 
    
         
            -
             * '"quote me"', otherwise or example 'user.name' is literal JavaScript.
         
     | 
| 
      
 2550 
     | 
    
         
            +
             * Clone this tag.
         
     | 
| 
       2177 
2551 
     | 
    
         
             
             *
         
     | 
| 
       2178 
     | 
    
         
            -
             * @ 
     | 
| 
       2179 
     | 
    
         
            -
             * @ 
     | 
| 
       2180 
     | 
    
         
            -
             * @return {Tag} for chaining
         
     | 
| 
       2181 
     | 
    
         
            -
             * @api public
         
     | 
| 
      
 2552 
     | 
    
         
            +
             * @return {Tag}
         
     | 
| 
      
 2553 
     | 
    
         
            +
             * @api private
         
     | 
| 
       2182 
2554 
     | 
    
         
             
             */
         
     | 
| 
       2183 
2555 
     | 
    
         | 
| 
       2184 
     | 
    
         
            -
            Tag.prototype. 
     | 
| 
       2185 
     | 
    
         
            -
              this. 
     | 
| 
       2186 
     | 
    
         
            -
               
     | 
| 
      
 2556 
     | 
    
         
            +
            Tag.prototype.clone = function(){
         
     | 
| 
      
 2557 
     | 
    
         
            +
              var clone = new Tag(this.name, this.block.clone());
         
     | 
| 
      
 2558 
     | 
    
         
            +
              clone.line = this.line;
         
     | 
| 
      
 2559 
     | 
    
         
            +
              clone.attrs = this.attrs;
         
     | 
| 
      
 2560 
     | 
    
         
            +
              clone.textOnly = this.textOnly;
         
     | 
| 
      
 2561 
     | 
    
         
            +
              return clone;
         
     | 
| 
       2187 
2562 
     | 
    
         
             
            };
         
     | 
| 
       2188 
2563 
     | 
    
         | 
| 
       2189 
2564 
     | 
    
         
             
            /**
         
     | 
| 
       2190 
     | 
    
         
            -
             *  
     | 
| 
      
 2565 
     | 
    
         
            +
             * Check if this tag is an inline tag.
         
     | 
| 
       2191 
2566 
     | 
    
         
             
             *
         
     | 
| 
       2192 
     | 
    
         
            -
             * @ 
     | 
| 
       2193 
     | 
    
         
            -
             * @api  
     | 
| 
      
 2567 
     | 
    
         
            +
             * @return {Boolean}
         
     | 
| 
      
 2568 
     | 
    
         
            +
             * @api private
         
     | 
| 
       2194 
2569 
     | 
    
         
             
             */
         
     | 
| 
       2195 
2570 
     | 
    
         | 
| 
       2196 
     | 
    
         
            -
            Tag.prototype. 
     | 
| 
       2197 
     | 
    
         
            -
               
     | 
| 
       2198 
     | 
    
         
            -
                if (this.attrs[i] && this.attrs[i].name == name) {
         
     | 
| 
       2199 
     | 
    
         
            -
                  delete this.attrs[i];
         
     | 
| 
       2200 
     | 
    
         
            -
                }
         
     | 
| 
       2201 
     | 
    
         
            -
              }
         
     | 
| 
      
 2571 
     | 
    
         
            +
            Tag.prototype.isInline = function(){
         
     | 
| 
      
 2572 
     | 
    
         
            +
              return ~inlineTags.indexOf(this.name);
         
     | 
| 
       2202 
2573 
     | 
    
         
             
            };
         
     | 
| 
       2203 
2574 
     | 
    
         | 
| 
       2204 
2575 
     | 
    
         
             
            /**
         
     | 
| 
       2205 
     | 
    
         
            -
             *  
     | 
| 
      
 2576 
     | 
    
         
            +
             * Check if this tag's contents can be inlined.  Used for pretty printing.
         
     | 
| 
       2206 
2577 
     | 
    
         
             
             *
         
     | 
| 
       2207 
     | 
    
         
            -
             * @ 
     | 
| 
       2208 
     | 
    
         
            -
             * @ 
     | 
| 
       2209 
     | 
    
         
            -
             * @api public
         
     | 
| 
      
 2578 
     | 
    
         
            +
             * @return {Boolean}
         
     | 
| 
      
 2579 
     | 
    
         
            +
             * @api private
         
     | 
| 
       2210 
2580 
     | 
    
         
             
             */
         
     | 
| 
       2211 
2581 
     | 
    
         | 
| 
       2212 
     | 
    
         
            -
            Tag.prototype. 
     | 
| 
       2213 
     | 
    
         
            -
               
     | 
| 
       2214 
     | 
    
         
            -
             
     | 
| 
       2215 
     | 
    
         
            -
             
     | 
| 
      
 2582 
     | 
    
         
            +
            Tag.prototype.canInline = function(){
         
     | 
| 
      
 2583 
     | 
    
         
            +
              var nodes = this.block.nodes;
         
     | 
| 
      
 2584 
     | 
    
         
            +
             
     | 
| 
      
 2585 
     | 
    
         
            +
              function isInline(node){
         
     | 
| 
      
 2586 
     | 
    
         
            +
                // Recurse if the node is a block
         
     | 
| 
      
 2587 
     | 
    
         
            +
                if (node.isBlock) return node.nodes.every(isInline);
         
     | 
| 
      
 2588 
     | 
    
         
            +
                return node.isText || (node.isInline && node.isInline());
         
     | 
| 
      
 2589 
     | 
    
         
            +
              }
         
     | 
| 
      
 2590 
     | 
    
         
            +
              
         
     | 
| 
      
 2591 
     | 
    
         
            +
              // Empty tag
         
     | 
| 
      
 2592 
     | 
    
         
            +
              if (!nodes.length) return true;
         
     | 
| 
      
 2593 
     | 
    
         
            +
              
         
     | 
| 
      
 2594 
     | 
    
         
            +
              // Text-only or inline-only tag
         
     | 
| 
      
 2595 
     | 
    
         
            +
              if (1 == nodes.length) return isInline(nodes[0]);
         
     | 
| 
      
 2596 
     | 
    
         
            +
              
         
     | 
| 
      
 2597 
     | 
    
         
            +
              // Multi-line inline-only tag
         
     | 
| 
      
 2598 
     | 
    
         
            +
              if (this.block.nodes.every(isInline)) {
         
     | 
| 
      
 2599 
     | 
    
         
            +
                for (var i = 1, len = nodes.length; i < len; ++i) {
         
     | 
| 
      
 2600 
     | 
    
         
            +
                  if (nodes[i-1].isText && nodes[i].isText)
         
     | 
| 
      
 2601 
     | 
    
         
            +
                    return false;
         
     | 
| 
       2216 
2602 
     | 
    
         
             
                }
         
     | 
| 
      
 2603 
     | 
    
         
            +
                return true;
         
     | 
| 
       2217 
2604 
     | 
    
         
             
              }
         
     | 
| 
      
 2605 
     | 
    
         
            +
              
         
     | 
| 
      
 2606 
     | 
    
         
            +
              // Mixed tag
         
     | 
| 
      
 2607 
     | 
    
         
            +
              return false;
         
     | 
| 
       2218 
2608 
     | 
    
         
             
            };
         
     | 
| 
       2219 
     | 
    
         
            -
             
     | 
| 
       2220 
2609 
     | 
    
         
             
            }); // module: nodes/tag.js
         
     | 
| 
       2221 
2610 
     | 
    
         | 
| 
       2222 
2611 
     | 
    
         
             
            require.register("nodes/text.js", function(module, exports, require){
         
     | 
| 
         @@ -2241,8 +2630,8 @@ var Node = require('./node'); 
     | 
|
| 
       2241 
2630 
     | 
    
         
             
             */
         
     | 
| 
       2242 
2631 
     | 
    
         | 
| 
       2243 
2632 
     | 
    
         
             
            var Text = module.exports = function Text(line) {
         
     | 
| 
       2244 
     | 
    
         
            -
              this. 
     | 
| 
       2245 
     | 
    
         
            -
              if ('string' == typeof line) this. 
     | 
| 
      
 2633 
     | 
    
         
            +
              this.val = '';
         
     | 
| 
      
 2634 
     | 
    
         
            +
              if ('string' == typeof line) this.val = line;
         
     | 
| 
       2246 
2635 
     | 
    
         
             
            };
         
     | 
| 
       2247 
2636 
     | 
    
         | 
| 
       2248 
2637 
     | 
    
         
             
            /**
         
     | 
| 
         @@ -2254,17 +2643,10 @@ Text.prototype.constructor = Text; 
     | 
|
| 
       2254 
2643 
     | 
    
         | 
| 
       2255 
2644 
     | 
    
         | 
| 
       2256 
2645 
     | 
    
         
             
            /**
         
     | 
| 
       2257 
     | 
    
         
            -
             *  
     | 
| 
       2258 
     | 
    
         
            -
             *
         
     | 
| 
       2259 
     | 
    
         
            -
             * @param {Node} node
         
     | 
| 
       2260 
     | 
    
         
            -
             * @return {Number}
         
     | 
| 
       2261 
     | 
    
         
            -
             * @api public
         
     | 
| 
      
 2646 
     | 
    
         
            +
             * Flag as text.
         
     | 
| 
       2262 
2647 
     | 
    
         
             
             */
         
     | 
| 
       2263 
2648 
     | 
    
         | 
| 
       2264 
     | 
    
         
            -
            Text.prototype. 
     | 
| 
       2265 
     | 
    
         
            -
              return this.nodes.push(node);
         
     | 
| 
       2266 
     | 
    
         
            -
            };
         
     | 
| 
       2267 
     | 
    
         
            -
             
     | 
| 
      
 2649 
     | 
    
         
            +
            Text.prototype.isText = true;
         
     | 
| 
       2268 
2650 
     | 
    
         
             
            }); // module: nodes/text.js
         
     | 
| 
       2269 
2651 
     | 
    
         | 
| 
       2270 
2652 
     | 
    
         
             
            require.register("parser.js", function(module, exports, require){
         
     | 
| 
         @@ -2280,7 +2662,8 @@ require.register("parser.js", function(module, exports, require){ 
     | 
|
| 
       2280 
2662 
     | 
    
         
             
             */
         
     | 
| 
       2281 
2663 
     | 
    
         | 
| 
       2282 
2664 
     | 
    
         
             
            var Lexer = require('./lexer')
         
     | 
| 
       2283 
     | 
    
         
            -
              , nodes = require('./nodes') 
     | 
| 
      
 2665 
     | 
    
         
            +
              , nodes = require('./nodes')
         
     | 
| 
      
 2666 
     | 
    
         
            +
              , utils = require('./utils');
         
     | 
| 
       2284 
2667 
     | 
    
         | 
| 
       2285 
2668 
     | 
    
         
             
            /**
         
     | 
| 
       2286 
2669 
     | 
    
         
             
             * Initialize `Parser` with the given input `str` and `filename`.
         
     | 
| 
         @@ -2296,6 +2679,7 @@ var Parser = exports = module.exports = function Parser(str, filename, options){ 
     | 
|
| 
       2296 
2679 
     | 
    
         
             
              this.lexer = new Lexer(str, options);
         
     | 
| 
       2297 
2680 
     | 
    
         
             
              this.filename = filename;
         
     | 
| 
       2298 
2681 
     | 
    
         
             
              this.blocks = {};
         
     | 
| 
      
 2682 
     | 
    
         
            +
              this.mixins = {};
         
     | 
| 
       2299 
2683 
     | 
    
         
             
              this.options = options;
         
     | 
| 
       2300 
2684 
     | 
    
         
             
              this.contexts = [this];
         
     | 
| 
       2301 
2685 
     | 
    
         
             
            };
         
     | 
| 
         @@ -2404,6 +2788,9 @@ Parser.prototype = { 
     | 
|
| 
       2404 
2788 
     | 
    
         
             
                  this.context(parser);
         
     | 
| 
       2405 
2789 
     | 
    
         
             
                  var ast = parser.parse();
         
     | 
| 
       2406 
2790 
     | 
    
         
             
                  this.context();
         
     | 
| 
      
 2791 
     | 
    
         
            +
                  // hoist mixins
         
     | 
| 
      
 2792 
     | 
    
         
            +
                  for (var name in this.mixins)
         
     | 
| 
      
 2793 
     | 
    
         
            +
                    ast.unshift(this.mixins[name]);
         
     | 
| 
       2407 
2794 
     | 
    
         
             
                  return ast;
         
     | 
| 
       2408 
2795 
     | 
    
         
             
                }
         
     | 
| 
       2409 
2796 
     | 
    
         | 
| 
         @@ -2448,8 +2835,10 @@ Parser.prototype = { 
     | 
|
| 
       2448 
2835 
     | 
    
         
             
               * | text
         
     | 
| 
       2449 
2836 
     | 
    
         
             
               * | each
         
     | 
| 
       2450 
2837 
     | 
    
         
             
               * | code
         
     | 
| 
      
 2838 
     | 
    
         
            +
               * | yield
         
     | 
| 
       2451 
2839 
     | 
    
         
             
               * | id
         
     | 
| 
       2452 
2840 
     | 
    
         
             
               * | class
         
     | 
| 
      
 2841 
     | 
    
         
            +
               * | interpolation
         
     | 
| 
       2453 
2842 
     | 
    
         
             
               */
         
     | 
| 
       2454 
2843 
     | 
    
         | 
| 
       2455 
2844 
     | 
    
         
             
              parseExpr: function(){
         
     | 
| 
         @@ -2482,6 +2871,15 @@ Parser.prototype = { 
     | 
|
| 
       2482 
2871 
     | 
    
         
             
                    return this.parseEach();
         
     | 
| 
       2483 
2872 
     | 
    
         
             
                  case 'code':
         
     | 
| 
       2484 
2873 
     | 
    
         
             
                    return this.parseCode();
         
     | 
| 
      
 2874 
     | 
    
         
            +
                  case 'call':
         
     | 
| 
      
 2875 
     | 
    
         
            +
                    return this.parseCall();
         
     | 
| 
      
 2876 
     | 
    
         
            +
                  case 'interpolation':
         
     | 
| 
      
 2877 
     | 
    
         
            +
                    return this.parseInterpolation();
         
     | 
| 
      
 2878 
     | 
    
         
            +
                  case 'yield':
         
     | 
| 
      
 2879 
     | 
    
         
            +
                    this.advance();
         
     | 
| 
      
 2880 
     | 
    
         
            +
                    var block = new nodes.Block;
         
     | 
| 
      
 2881 
     | 
    
         
            +
                    block.yield = true;
         
     | 
| 
      
 2882 
     | 
    
         
            +
                    return block;
         
     | 
| 
       2485 
2883 
     | 
    
         
             
                  case 'id':
         
     | 
| 
       2486 
2884 
     | 
    
         
             
                  case 'class':
         
     | 
| 
       2487 
2885 
     | 
    
         
             
                    var tok = this.advance();
         
     | 
| 
         @@ -2640,6 +3038,10 @@ Parser.prototype = { 
     | 
|
| 
       2640 
3038 
     | 
    
         
             
                  , node = new nodes.Each(tok.code, tok.val, tok.key);
         
     | 
| 
       2641 
3039 
     | 
    
         
             
                node.line = this.line();
         
     | 
| 
       2642 
3040 
     | 
    
         
             
                node.block = this.block();
         
     | 
| 
      
 3041 
     | 
    
         
            +
                if (this.peek().type == 'code' && this.peek().val == 'else') {
         
     | 
| 
      
 3042 
     | 
    
         
            +
                  this.advance();
         
     | 
| 
      
 3043 
     | 
    
         
            +
                  node.alternative = this.block();
         
     | 
| 
      
 3044 
     | 
    
         
            +
                }
         
     | 
| 
       2643 
3045 
     | 
    
         
             
                return node;
         
     | 
| 
       2644 
3046 
     | 
    
         
             
              },
         
     | 
| 
       2645 
3047 
     | 
    
         | 
| 
         @@ -2657,7 +3059,7 @@ Parser.prototype = { 
     | 
|
| 
       2657 
3059 
     | 
    
         
             
                if (!this.filename)
         
     | 
| 
       2658 
3060 
     | 
    
         
             
                  throw new Error('the "filename" option is required to extend templates');
         
     | 
| 
       2659 
3061 
     | 
    
         | 
| 
       2660 
     | 
    
         
            -
                var path =  
     | 
| 
      
 3062 
     | 
    
         
            +
                var path = this.expect('extends').val.trim()
         
     | 
| 
       2661 
3063 
     | 
    
         
             
                  , dir = dirname(this.filename);
         
     | 
| 
       2662 
3064 
     | 
    
         | 
| 
       2663 
3065 
     | 
    
         
             
                var path = join(dir, path + '.jade')
         
     | 
| 
         @@ -2715,7 +3117,7 @@ Parser.prototype = { 
     | 
|
| 
       2715 
3117 
     | 
    
         
             
                  , basename = path.basename
         
     | 
| 
       2716 
3118 
     | 
    
         
             
                  , join = path.join;
         
     | 
| 
       2717 
3119 
     | 
    
         | 
| 
       2718 
     | 
    
         
            -
                var path =  
     | 
| 
      
 3120 
     | 
    
         
            +
                var path = this.expect('include').val.trim()
         
     | 
| 
       2719 
3121 
     | 
    
         
             
                  , dir = dirname(this.filename);
         
     | 
| 
       2720 
3122 
     | 
    
         | 
| 
       2721 
3123 
     | 
    
         
             
                if (!this.filename)
         
     | 
| 
         @@ -2736,6 +3138,8 @@ Parser.prototype = { 
     | 
|
| 
       2736 
3138 
     | 
    
         
             
                var path = join(dir, path)
         
     | 
| 
       2737 
3139 
     | 
    
         
             
                  , str = fs.readFileSync(path, 'utf8')
         
     | 
| 
       2738 
3140 
     | 
    
         
             
                 , parser = new Parser(str, path, this.options);
         
     | 
| 
      
 3141 
     | 
    
         
            +
                parser.blocks = utils.merge({}, this.blocks);
         
     | 
| 
      
 3142 
     | 
    
         
            +
                parser.mixins = this.mixins;
         
     | 
| 
       2739 
3143 
     | 
    
         | 
| 
       2740 
3144 
     | 
    
         
             
                this.context(parser);
         
     | 
| 
       2741 
3145 
     | 
    
         
             
                var ast = parser.parse();
         
     | 
| 
         @@ -2743,12 +3147,27 @@ Parser.prototype = { 
     | 
|
| 
       2743 
3147 
     | 
    
         
             
                ast.filename = path;
         
     | 
| 
       2744 
3148 
     | 
    
         | 
| 
       2745 
3149 
     | 
    
         
             
                if ('indent' == this.peek().type) {
         
     | 
| 
       2746 
     | 
    
         
            -
                  ast. 
     | 
| 
      
 3150 
     | 
    
         
            +
                  ast.includeBlock().push(this.block());
         
     | 
| 
       2747 
3151 
     | 
    
         
             
                }
         
     | 
| 
       2748 
3152 
     | 
    
         | 
| 
       2749 
3153 
     | 
    
         
             
                return ast;
         
     | 
| 
       2750 
3154 
     | 
    
         
             
              },
         
     | 
| 
       2751 
3155 
     | 
    
         | 
| 
      
 3156 
     | 
    
         
            +
              /**
         
     | 
| 
      
 3157 
     | 
    
         
            +
               * call ident block
         
     | 
| 
      
 3158 
     | 
    
         
            +
               */
         
     | 
| 
      
 3159 
     | 
    
         
            +
             
     | 
| 
      
 3160 
     | 
    
         
            +
              parseCall: function(){
         
     | 
| 
      
 3161 
     | 
    
         
            +
                var tok = this.expect('call')
         
     | 
| 
      
 3162 
     | 
    
         
            +
                  , name = tok.val
         
     | 
| 
      
 3163 
     | 
    
         
            +
                  , args = tok.args
         
     | 
| 
      
 3164 
     | 
    
         
            +
                  , mixin = new nodes.Mixin(name, args, new nodes.Block, true);
         
     | 
| 
      
 3165 
     | 
    
         
            +
             
     | 
| 
      
 3166 
     | 
    
         
            +
                this.tag(mixin);
         
     | 
| 
      
 3167 
     | 
    
         
            +
                if (mixin.block.isEmpty()) mixin.block = null;
         
     | 
| 
      
 3168 
     | 
    
         
            +
                return mixin;
         
     | 
| 
      
 3169 
     | 
    
         
            +
              },
         
     | 
| 
      
 3170 
     | 
    
         
            +
             
     | 
| 
       2752 
3171 
     | 
    
         
             
              /**
         
     | 
| 
       2753 
3172 
     | 
    
         
             
               * mixin block
         
     | 
| 
       2754 
3173 
     | 
    
         
             
               */
         
     | 
| 
         @@ -2756,11 +3175,18 @@ Parser.prototype = { 
     | 
|
| 
       2756 
3175 
     | 
    
         
             
              parseMixin: function(){
         
     | 
| 
       2757 
3176 
     | 
    
         
             
                var tok = this.expect('mixin')
         
     | 
| 
       2758 
3177 
     | 
    
         
             
                  , name = tok.val
         
     | 
| 
       2759 
     | 
    
         
            -
                  , args = tok.args 
     | 
| 
       2760 
     | 
    
         
            -
             
     | 
| 
       2761 
     | 
    
         
            -
             
     | 
| 
       2762 
     | 
    
         
            -
             
     | 
| 
       2763 
     | 
    
         
            -
                 
     | 
| 
      
 3178 
     | 
    
         
            +
                  , args = tok.args
         
     | 
| 
      
 3179 
     | 
    
         
            +
                  , mixin;
         
     | 
| 
      
 3180 
     | 
    
         
            +
             
     | 
| 
      
 3181 
     | 
    
         
            +
                // definition
         
     | 
| 
      
 3182 
     | 
    
         
            +
                if ('indent' == this.peek().type) {
         
     | 
| 
      
 3183 
     | 
    
         
            +
                  mixin = new nodes.Mixin(name, args, this.block(), false);
         
     | 
| 
      
 3184 
     | 
    
         
            +
                  this.mixins[name] = mixin;
         
     | 
| 
      
 3185 
     | 
    
         
            +
                  return mixin;
         
     | 
| 
      
 3186 
     | 
    
         
            +
                // call
         
     | 
| 
      
 3187 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 3188 
     | 
    
         
            +
                  return new nodes.Mixin(name, args, null, true);
         
     | 
| 
      
 3189 
     | 
    
         
            +
                }
         
     | 
| 
       2764 
3190 
     | 
    
         
             
              },
         
     | 
| 
       2765 
3191 
     | 
    
         | 
| 
       2766 
3192 
     | 
    
         
             
              /**
         
     | 
| 
         @@ -2768,32 +3194,31 @@ Parser.prototype = { 
     | 
|
| 
       2768 
3194 
     | 
    
         
             
               */
         
     | 
| 
       2769 
3195 
     | 
    
         | 
| 
       2770 
3196 
     | 
    
         
             
              parseTextBlock: function(){
         
     | 
| 
       2771 
     | 
    
         
            -
                var  
     | 
| 
       2772 
     | 
    
         
            -
                 
     | 
| 
      
 3197 
     | 
    
         
            +
                var block = new nodes.Block;
         
     | 
| 
      
 3198 
     | 
    
         
            +
                block.line = this.line();
         
     | 
| 
       2773 
3199 
     | 
    
         
             
                var spaces = this.expect('indent').val;
         
     | 
| 
       2774 
3200 
     | 
    
         
             
                if (null == this._spaces) this._spaces = spaces;
         
     | 
| 
       2775 
3201 
     | 
    
         
             
                var indent = Array(spaces - this._spaces + 1).join(' ');
         
     | 
| 
       2776 
3202 
     | 
    
         
             
                while ('outdent' != this.peek().type) {
         
     | 
| 
       2777 
3203 
     | 
    
         
             
                  switch (this.peek().type) {
         
     | 
| 
       2778 
3204 
     | 
    
         
             
                    case 'newline':
         
     | 
| 
       2779 
     | 
    
         
            -
                      text.push('\\n');
         
     | 
| 
       2780 
3205 
     | 
    
         
             
                      this.advance();
         
     | 
| 
       2781 
3206 
     | 
    
         
             
                      break;
         
     | 
| 
       2782 
3207 
     | 
    
         
             
                    case 'indent':
         
     | 
| 
       2783 
     | 
    
         
            -
                      text.push('\\n');
         
     | 
| 
       2784 
3208 
     | 
    
         
             
                      this.parseTextBlock().nodes.forEach(function(node){
         
     | 
| 
       2785 
     | 
    
         
            -
                         
     | 
| 
      
 3209 
     | 
    
         
            +
                        block.push(node);
         
     | 
| 
       2786 
3210 
     | 
    
         
             
                      });
         
     | 
| 
       2787 
     | 
    
         
            -
                      text.push('\\n');
         
     | 
| 
       2788 
3211 
     | 
    
         
             
                      break;
         
     | 
| 
       2789 
3212 
     | 
    
         
             
                    default:
         
     | 
| 
       2790 
     | 
    
         
            -
                      text. 
     | 
| 
      
 3213 
     | 
    
         
            +
                      var text = new nodes.Text(indent + this.advance().val);
         
     | 
| 
      
 3214 
     | 
    
         
            +
                      text.line = this.line();
         
     | 
| 
      
 3215 
     | 
    
         
            +
                      block.push(text);
         
     | 
| 
       2791 
3216 
     | 
    
         
             
                  }
         
     | 
| 
       2792 
3217 
     | 
    
         
             
                }
         
     | 
| 
       2793 
3218 
     | 
    
         | 
| 
       2794 
3219 
     | 
    
         
             
                if (spaces == this._spaces) this._spaces = null;
         
     | 
| 
       2795 
3220 
     | 
    
         
             
                this.expect('outdent');
         
     | 
| 
       2796 
     | 
    
         
            -
                return  
     | 
| 
      
 3221 
     | 
    
         
            +
                return block;
         
     | 
| 
       2797 
3222 
     | 
    
         
             
              },
         
     | 
| 
       2798 
3223 
     | 
    
         | 
| 
       2799 
3224 
     | 
    
         
             
              /**
         
     | 
| 
         @@ -2815,6 +3240,17 @@ Parser.prototype = { 
     | 
|
| 
       2815 
3240 
     | 
    
         
             
                return block;
         
     | 
| 
       2816 
3241 
     | 
    
         
             
              },
         
     | 
| 
       2817 
3242 
     | 
    
         | 
| 
      
 3243 
     | 
    
         
            +
              /**
         
     | 
| 
      
 3244 
     | 
    
         
            +
               * interpolation (attrs | class | id)* (text | code | ':')? newline* block?
         
     | 
| 
      
 3245 
     | 
    
         
            +
               */
         
     | 
| 
      
 3246 
     | 
    
         
            +
              
         
     | 
| 
      
 3247 
     | 
    
         
            +
              parseInterpolation: function(){
         
     | 
| 
      
 3248 
     | 
    
         
            +
                var tok = this.advance();
         
     | 
| 
      
 3249 
     | 
    
         
            +
                var tag = new nodes.Tag(tok.val);
         
     | 
| 
      
 3250 
     | 
    
         
            +
                tag.buffer = true;
         
     | 
| 
      
 3251 
     | 
    
         
            +
                return this.tag(tag);
         
     | 
| 
      
 3252 
     | 
    
         
            +
              },
         
     | 
| 
      
 3253 
     | 
    
         
            +
             
     | 
| 
       2818 
3254 
     | 
    
         
             
              /**
         
     | 
| 
       2819 
3255 
     | 
    
         
             
               * tag (attrs | class | id)* (text | code | ':')? newline* block?
         
     | 
| 
       2820 
3256 
     | 
    
         
             
               */
         
     | 
| 
         @@ -2829,9 +3265,20 @@ Parser.prototype = { 
     | 
|
| 
       2829 
3265 
     | 
    
         
             
                  }
         
     | 
| 
       2830 
3266 
     | 
    
         
             
                }
         
     | 
| 
       2831 
3267 
     | 
    
         | 
| 
       2832 
     | 
    
         
            -
                var  
     | 
| 
       2833 
     | 
    
         
            -
                  , tag = new nodes.Tag( 
     | 
| 
       2834 
     | 
    
         
            -
             
     | 
| 
      
 3268 
     | 
    
         
            +
                var tok = this.advance()
         
     | 
| 
      
 3269 
     | 
    
         
            +
                  , tag = new nodes.Tag(tok.val);
         
     | 
| 
      
 3270 
     | 
    
         
            +
             
     | 
| 
      
 3271 
     | 
    
         
            +
                tag.selfClosing = tok.selfClosing;
         
     | 
| 
      
 3272 
     | 
    
         
            +
             
     | 
| 
      
 3273 
     | 
    
         
            +
                return this.tag(tag);
         
     | 
| 
      
 3274 
     | 
    
         
            +
              },
         
     | 
| 
      
 3275 
     | 
    
         
            +
             
     | 
| 
      
 3276 
     | 
    
         
            +
              /**
         
     | 
| 
      
 3277 
     | 
    
         
            +
               * Parse tag.
         
     | 
| 
      
 3278 
     | 
    
         
            +
               */
         
     | 
| 
      
 3279 
     | 
    
         
            +
             
     | 
| 
      
 3280 
     | 
    
         
            +
              tag: function(tag){
         
     | 
| 
      
 3281 
     | 
    
         
            +
                var dot;
         
     | 
| 
       2835 
3282 
     | 
    
         | 
| 
       2836 
3283 
     | 
    
         
             
                tag.line = this.line();
         
     | 
| 
       2837 
3284 
     | 
    
         | 
| 
         @@ -2845,12 +3292,17 @@ Parser.prototype = { 
     | 
|
| 
       2845 
3292 
     | 
    
         
             
                        tag.setAttribute(tok.type, "'" + tok.val + "'");
         
     | 
| 
       2846 
3293 
     | 
    
         
             
                        continue;
         
     | 
| 
       2847 
3294 
     | 
    
         
             
                      case 'attrs':
         
     | 
| 
       2848 
     | 
    
         
            -
                        var  
     | 
| 
      
 3295 
     | 
    
         
            +
                        var tok = this.advance()
         
     | 
| 
      
 3296 
     | 
    
         
            +
                          , obj = tok.attrs
         
     | 
| 
      
 3297 
     | 
    
         
            +
                          , escaped = tok.escaped
         
     | 
| 
       2849 
3298 
     | 
    
         
             
                          , names = Object.keys(obj);
         
     | 
| 
      
 3299 
     | 
    
         
            +
             
     | 
| 
      
 3300 
     | 
    
         
            +
                        if (tok.selfClosing) tag.selfClosing = true;
         
     | 
| 
      
 3301 
     | 
    
         
            +
             
     | 
| 
       2850 
3302 
     | 
    
         
             
                        for (var i = 0, len = names.length; i < len; ++i) {
         
     | 
| 
       2851 
3303 
     | 
    
         
             
                          var name = names[i]
         
     | 
| 
       2852 
3304 
     | 
    
         
             
                            , val = obj[name];
         
     | 
| 
       2853 
     | 
    
         
            -
                          tag.setAttribute(name, val);
         
     | 
| 
      
 3305 
     | 
    
         
            +
                          tag.setAttribute(name, val, escaped[name]);
         
     | 
| 
       2854 
3306 
     | 
    
         
             
                        }
         
     | 
| 
       2855 
3307 
     | 
    
         
             
                        continue;
         
     | 
| 
       2856 
3308 
     | 
    
         
             
                      default:
         
     | 
| 
         @@ -2867,7 +3319,7 @@ Parser.prototype = { 
     | 
|
| 
       2867 
3319 
     | 
    
         
             
                // (text | code | ':')?
         
     | 
| 
       2868 
3320 
     | 
    
         
             
                switch (this.peek().type) {
         
     | 
| 
       2869 
3321 
     | 
    
         
             
                  case 'text':
         
     | 
| 
       2870 
     | 
    
         
            -
                    tag. 
     | 
| 
      
 3322 
     | 
    
         
            +
                    tag.block.push(this.parseText());
         
     | 
| 
       2871 
3323 
     | 
    
         
             
                    break;
         
     | 
| 
       2872 
3324 
     | 
    
         
             
                  case 'code':
         
     | 
| 
       2873 
3325 
     | 
    
         
             
                    tag.code = this.parseCode();
         
     | 
| 
         @@ -2875,7 +3327,7 @@ Parser.prototype = { 
     | 
|
| 
       2875 
3327 
     | 
    
         
             
                  case ':':
         
     | 
| 
       2876 
3328 
     | 
    
         
             
                    this.advance();
         
     | 
| 
       2877 
3329 
     | 
    
         
             
                    tag.block = new nodes.Block;
         
     | 
| 
       2878 
     | 
    
         
            -
                    tag.block.push(this. 
     | 
| 
      
 3330 
     | 
    
         
            +
                    tag.block.push(this.parseExpr());
         
     | 
| 
       2879 
3331 
     | 
    
         
             
                    break;
         
     | 
| 
       2880 
3332 
     | 
    
         
             
                }
         
     | 
| 
       2881 
3333 
     | 
    
         | 
| 
         @@ -2947,41 +3399,97 @@ if (!Object.keys) { 
     | 
|
| 
       2947 
3399 
     | 
    
         
             
                  }
         
     | 
| 
       2948 
3400 
     | 
    
         
             
                }
         
     | 
| 
       2949 
3401 
     | 
    
         
             
                return arr;
         
     | 
| 
       2950 
     | 
    
         
            -
              } 
     | 
| 
      
 3402 
     | 
    
         
            +
              }
         
     | 
| 
      
 3403 
     | 
    
         
            +
            }
         
     | 
| 
      
 3404 
     | 
    
         
            +
             
     | 
| 
      
 3405 
     | 
    
         
            +
            /**
         
     | 
| 
      
 3406 
     | 
    
         
            +
             * Merge two attribute objects giving precedence
         
     | 
| 
      
 3407 
     | 
    
         
            +
             * to values in object `b`. Classes are special-cased
         
     | 
| 
      
 3408 
     | 
    
         
            +
             * allowing for arrays and merging/joining appropriately
         
     | 
| 
      
 3409 
     | 
    
         
            +
             * resulting in a string.
         
     | 
| 
      
 3410 
     | 
    
         
            +
             *
         
     | 
| 
      
 3411 
     | 
    
         
            +
             * @param {Object} a
         
     | 
| 
      
 3412 
     | 
    
         
            +
             * @param {Object} b
         
     | 
| 
      
 3413 
     | 
    
         
            +
             * @return {Object} a
         
     | 
| 
      
 3414 
     | 
    
         
            +
             * @api private
         
     | 
| 
      
 3415 
     | 
    
         
            +
             */
         
     | 
| 
      
 3416 
     | 
    
         
            +
             
     | 
| 
      
 3417 
     | 
    
         
            +
            exports.merge = function merge(a, b) {
         
     | 
| 
      
 3418 
     | 
    
         
            +
              var ac = a['class'];
         
     | 
| 
      
 3419 
     | 
    
         
            +
              var bc = b['class'];
         
     | 
| 
      
 3420 
     | 
    
         
            +
             
     | 
| 
      
 3421 
     | 
    
         
            +
              if (ac || bc) {
         
     | 
| 
      
 3422 
     | 
    
         
            +
                ac = ac || [];
         
     | 
| 
      
 3423 
     | 
    
         
            +
                bc = bc || [];
         
     | 
| 
      
 3424 
     | 
    
         
            +
                if (!Array.isArray(ac)) ac = [ac];
         
     | 
| 
      
 3425 
     | 
    
         
            +
                if (!Array.isArray(bc)) bc = [bc];
         
     | 
| 
      
 3426 
     | 
    
         
            +
                ac = ac.filter(nulls);
         
     | 
| 
      
 3427 
     | 
    
         
            +
                bc = bc.filter(nulls);
         
     | 
| 
      
 3428 
     | 
    
         
            +
                a['class'] = ac.concat(bc).join(' ');
         
     | 
| 
      
 3429 
     | 
    
         
            +
              }
         
     | 
| 
      
 3430 
     | 
    
         
            +
             
     | 
| 
      
 3431 
     | 
    
         
            +
              for (var key in b) {
         
     | 
| 
      
 3432 
     | 
    
         
            +
                if (key != 'class') {
         
     | 
| 
      
 3433 
     | 
    
         
            +
                  a[key] = b[key];
         
     | 
| 
      
 3434 
     | 
    
         
            +
                }
         
     | 
| 
      
 3435 
     | 
    
         
            +
              }
         
     | 
| 
      
 3436 
     | 
    
         
            +
             
     | 
| 
      
 3437 
     | 
    
         
            +
              return a;
         
     | 
| 
      
 3438 
     | 
    
         
            +
            };
         
     | 
| 
      
 3439 
     | 
    
         
            +
             
     | 
| 
      
 3440 
     | 
    
         
            +
            /**
         
     | 
| 
      
 3441 
     | 
    
         
            +
             * Filter null `val`s.
         
     | 
| 
      
 3442 
     | 
    
         
            +
             *
         
     | 
| 
      
 3443 
     | 
    
         
            +
             * @param {Mixed} val
         
     | 
| 
      
 3444 
     | 
    
         
            +
             * @return {Mixed}
         
     | 
| 
      
 3445 
     | 
    
         
            +
             * @api private
         
     | 
| 
      
 3446 
     | 
    
         
            +
             */
         
     | 
| 
      
 3447 
     | 
    
         
            +
             
     | 
| 
      
 3448 
     | 
    
         
            +
            function nulls(val) {
         
     | 
| 
      
 3449 
     | 
    
         
            +
              return val != null;
         
     | 
| 
       2951 
3450 
     | 
    
         
             
            }
         
     | 
| 
       2952 
3451 
     | 
    
         | 
| 
       2953 
3452 
     | 
    
         
             
            /**
         
     | 
| 
       2954 
3453 
     | 
    
         
             
             * Render the given attributes object.
         
     | 
| 
       2955 
3454 
     | 
    
         
             
             *
         
     | 
| 
       2956 
3455 
     | 
    
         
             
             * @param {Object} obj
         
     | 
| 
      
 3456 
     | 
    
         
            +
             * @param {Object} escaped
         
     | 
| 
       2957 
3457 
     | 
    
         
             
             * @return {String}
         
     | 
| 
       2958 
3458 
     | 
    
         
             
             * @api private
         
     | 
| 
       2959 
3459 
     | 
    
         
             
             */
         
     | 
| 
       2960 
3460 
     | 
    
         | 
| 
       2961 
     | 
    
         
            -
            exports.attrs = function attrs(obj){
         
     | 
| 
      
 3461 
     | 
    
         
            +
            exports.attrs = function attrs(obj, escaped){
         
     | 
| 
       2962 
3462 
     | 
    
         
             
              var buf = []
         
     | 
| 
       2963 
3463 
     | 
    
         
             
                , terse = obj.terse;
         
     | 
| 
      
 3464 
     | 
    
         
            +
             
     | 
| 
       2964 
3465 
     | 
    
         
             
              delete obj.terse;
         
     | 
| 
       2965 
3466 
     | 
    
         
             
              var keys = Object.keys(obj)
         
     | 
| 
       2966 
3467 
     | 
    
         
             
                , len = keys.length;
         
     | 
| 
      
 3468 
     | 
    
         
            +
             
     | 
| 
       2967 
3469 
     | 
    
         
             
              if (len) {
         
     | 
| 
       2968 
3470 
     | 
    
         
             
                buf.push('');
         
     | 
| 
       2969 
3471 
     | 
    
         
             
                for (var i = 0; i < len; ++i) {
         
     | 
| 
       2970 
3472 
     | 
    
         
             
                  var key = keys[i]
         
     | 
| 
       2971 
3473 
     | 
    
         
             
                    , val = obj[key];
         
     | 
| 
      
 3474 
     | 
    
         
            +
             
     | 
| 
       2972 
3475 
     | 
    
         
             
                  if ('boolean' == typeof val || null == val) {
         
     | 
| 
       2973 
3476 
     | 
    
         
             
                    if (val) {
         
     | 
| 
       2974 
3477 
     | 
    
         
             
                      terse
         
     | 
| 
       2975 
3478 
     | 
    
         
             
                        ? buf.push(key)
         
     | 
| 
       2976 
3479 
     | 
    
         
             
                        : buf.push(key + '="' + key + '"');
         
     | 
| 
       2977 
3480 
     | 
    
         
             
                    }
         
     | 
| 
      
 3481 
     | 
    
         
            +
                  } else if (0 == key.indexOf('data') && 'string' != typeof val) {
         
     | 
| 
      
 3482 
     | 
    
         
            +
                    buf.push(key + "='" + JSON.stringify(val) + "'");
         
     | 
| 
       2978 
3483 
     | 
    
         
             
                  } else if ('class' == key && Array.isArray(val)) {
         
     | 
| 
       2979 
3484 
     | 
    
         
             
                    buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
         
     | 
| 
       2980 
     | 
    
         
            -
                  } else {
         
     | 
| 
      
 3485 
     | 
    
         
            +
                  } else if (escaped && escaped[key]) {
         
     | 
| 
       2981 
3486 
     | 
    
         
             
                    buf.push(key + '="' + exports.escape(val) + '"');
         
     | 
| 
      
 3487 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 3488 
     | 
    
         
            +
                    buf.push(key + '="' + val + '"');
         
     | 
| 
       2982 
3489 
     | 
    
         
             
                  }
         
     | 
| 
       2983 
3490 
     | 
    
         
             
                }
         
     | 
| 
       2984 
3491 
     | 
    
         
             
              }
         
     | 
| 
      
 3492 
     | 
    
         
            +
             
     | 
| 
       2985 
3493 
     | 
    
         
             
              return buf.join(' ');
         
     | 
| 
       2986 
3494 
     | 
    
         
             
            };
         
     | 
| 
       2987 
3495 
     | 
    
         | 
| 
         @@ -2995,7 +3503,7 @@ exports.attrs = function attrs(obj){ 
     | 
|
| 
       2995 
3503 
     | 
    
         | 
| 
       2996 
3504 
     | 
    
         
             
            exports.escape = function escape(html){
         
     | 
| 
       2997 
3505 
     | 
    
         
             
              return String(html)
         
     | 
| 
       2998 
     | 
    
         
            -
                .replace(/&( 
     | 
| 
      
 3506 
     | 
    
         
            +
                .replace(/&(?!(\w+|\#\d+);)/g, '&')
         
     | 
| 
       2999 
3507 
     | 
    
         
             
                .replace(/</g, '<')
         
     | 
| 
       3000 
3508 
     | 
    
         
             
                .replace(/>/g, '>')
         
     | 
| 
       3001 
3509 
     | 
    
         
             
                .replace(/"/g, '"');
         
     | 
| 
         @@ -3018,7 +3526,7 @@ exports.rethrow = function rethrow(err, filename, lineno){ 
     | 
|
| 
       3018 
3526 
     | 
    
         
             
                , str = require('fs').readFileSync(filename, 'utf8')
         
     | 
| 
       3019 
3527 
     | 
    
         
             
                , lines = str.split('\n')
         
     | 
| 
       3020 
3528 
     | 
    
         
             
                , start = Math.max(lineno - context, 0)
         
     | 
| 
       3021 
     | 
    
         
            -
                , end = Math.min(lines.length, lineno + context); 
     | 
| 
      
 3529 
     | 
    
         
            +
                , end = Math.min(lines.length, lineno + context);
         
     | 
| 
       3022 
3530 
     | 
    
         | 
| 
       3023 
3531 
     | 
    
         
             
              // Error context
         
     | 
| 
       3024 
3532 
     | 
    
         
             
              var context = lines.slice(start, end).map(function(line, i){
         
     | 
| 
         @@ -3031,7 +3539,7 @@ exports.rethrow = function rethrow(err, filename, lineno){ 
     | 
|
| 
       3031 
3539 
     | 
    
         | 
| 
       3032 
3540 
     | 
    
         
             
              // Alter exception message
         
     | 
| 
       3033 
3541 
     | 
    
         
             
              err.path = filename;
         
     | 
| 
       3034 
     | 
    
         
            -
              err.message = (filename || 'Jade') + ':' + lineno 
     | 
| 
      
 3542 
     | 
    
         
            +
              err.message = (filename || 'Jade') + ':' + lineno
         
     | 
| 
       3035 
3543 
     | 
    
         
             
                + '\n' + context + '\n\n' + err.message;
         
     | 
| 
       3036 
3544 
     | 
    
         
             
              throw err;
         
     | 
| 
       3037 
3545 
     | 
    
         
             
            };
         
     | 
| 
         @@ -3051,6 +3559,7 @@ module.exports = [ 
     | 
|
| 
       3051 
3559 
     | 
    
         
             
              , 'img'
         
     | 
| 
       3052 
3560 
     | 
    
         
             
              , 'link'
         
     | 
| 
       3053 
3561 
     | 
    
         
             
              , 'input'
         
     | 
| 
      
 3562 
     | 
    
         
            +
              , 'source'
         
     | 
| 
       3054 
3563 
     | 
    
         
             
              , 'area'
         
     | 
| 
       3055 
3564 
     | 
    
         
             
              , 'base'
         
     | 
| 
       3056 
3565 
     | 
    
         
             
              , 'col'
         
     | 
| 
         @@ -3078,7 +3587,7 @@ require.register("utils.js", function(module, exports, require){ 
     | 
|
| 
       3078 
3587 
     | 
    
         
             
            var interpolate = exports.interpolate = function(str){
         
     | 
| 
       3079 
3588 
     | 
    
         
             
              return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){
         
     | 
| 
       3080 
3589 
     | 
    
         
             
                return escape
         
     | 
| 
       3081 
     | 
    
         
            -
                  ? str
         
     | 
| 
      
 3590 
     | 
    
         
            +
                  ? str.slice(1)
         
     | 
| 
       3082 
3591 
     | 
    
         
             
                  : "' + "
         
     | 
| 
       3083 
3592 
     | 
    
         
             
                    + ('!' == flag ? '' : 'escape')
         
     | 
| 
       3084 
3593 
     | 
    
         
             
                    + "((interp = " + code.replace(/\\'/g, "'")
         
     | 
| 
         @@ -3109,4 +3618,23 @@ var escape = exports.escape = function(str) { 
     | 
|
| 
       3109 
3618 
     | 
    
         
             
            exports.text = function(str){
         
     | 
| 
       3110 
3619 
     | 
    
         
             
              return interpolate(escape(str));
         
     | 
| 
       3111 
3620 
     | 
    
         
             
            };
         
     | 
| 
      
 3621 
     | 
    
         
            +
             
     | 
| 
      
 3622 
     | 
    
         
            +
            /**
         
     | 
| 
      
 3623 
     | 
    
         
            +
             * Merge `b` into `a`.
         
     | 
| 
      
 3624 
     | 
    
         
            +
             *
         
     | 
| 
      
 3625 
     | 
    
         
            +
             * @param {Object} a
         
     | 
| 
      
 3626 
     | 
    
         
            +
             * @param {Object} b
         
     | 
| 
      
 3627 
     | 
    
         
            +
             * @return {Object}
         
     | 
| 
      
 3628 
     | 
    
         
            +
             * @api public
         
     | 
| 
      
 3629 
     | 
    
         
            +
             */
         
     | 
| 
      
 3630 
     | 
    
         
            +
             
     | 
| 
      
 3631 
     | 
    
         
            +
            exports.merge = function(a, b) {
         
     | 
| 
      
 3632 
     | 
    
         
            +
              for (var key in b) a[key] = b[key];
         
     | 
| 
      
 3633 
     | 
    
         
            +
              return a;
         
     | 
| 
      
 3634 
     | 
    
         
            +
            };
         
     | 
| 
      
 3635 
     | 
    
         
            +
             
     | 
| 
      
 3636 
     | 
    
         
            +
             
     | 
| 
       3112 
3637 
     | 
    
         
             
            }); // module: utils.js
         
     | 
| 
      
 3638 
     | 
    
         
            +
             
     | 
| 
      
 3639 
     | 
    
         
            +
            window.jade = require("jade");
         
     | 
| 
      
 3640 
     | 
    
         
            +
            })();
         
     |