Timoney, Daniel (dt5972) | 324ee36 | 2017-02-15 10:37:53 -0500 | [diff] [blame] | 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ |
| 2 | (function (process){ |
| 3 | /* |
| 4 | * EJS Embedded JavaScript templates |
| 5 | * Copyright 2112 Matthew Eernisse (mde@fleegix.org) |
| 6 | * |
| 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | * you may not use this file except in compliance with the License. |
| 9 | * You may obtain a copy of the License at |
| 10 | * |
| 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | * |
| 13 | * Unless required by applicable law or agreed to in writing, software |
| 14 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | * See the License for the specific language governing permissions and |
| 17 | * limitations under the License. |
| 18 | * |
| 19 | */ |
| 20 | |
| 21 | 'use strict'; |
| 22 | |
| 23 | var fs = require('fs') |
| 24 | , utils = require('./utils') |
| 25 | , jsCache = {} |
| 26 | , _VERSION_STRING = require('../package.json').version |
| 27 | , _DEFAULT_DELIMITER = '%' |
| 28 | , _DEFAULT_LOCALS_NAME = 'locals' |
| 29 | , _REGEX_STRING = '(<%%|<%=|<%-|<%#|<%|%>|-%>)' |
| 30 | , _OPTS = [ 'cache', 'filename', 'delimiter', 'scope', 'context' |
| 31 | , 'debug', 'compileDebug', 'client', '_with' |
| 32 | ] |
| 33 | , _TRAILING_SEMCOL = /;\s*$/; |
| 34 | |
| 35 | exports.localsName = _DEFAULT_LOCALS_NAME; |
| 36 | |
| 37 | exports.resolveInclude = function(name, filename) { |
| 38 | var path = require('path') |
| 39 | , dirname = path.dirname |
| 40 | , extname = path.extname |
| 41 | , resolve = path.resolve |
| 42 | , includePath = resolve(dirname(filename), name) |
| 43 | , ext = extname(name); |
| 44 | if (!ext) { |
| 45 | includePath += '.ejs'; |
| 46 | } |
| 47 | return includePath; |
| 48 | } |
| 49 | |
| 50 | |
| 51 | // Returns a possibly cached template function, set by options.cache. |
| 52 | // `template` is the string of EJS to compile. |
| 53 | // If template is undefined then the file specified in options.filename is |
| 54 | // read. |
| 55 | function handleCache(options, template) { |
| 56 | var fn |
| 57 | , path = options.filename |
| 58 | , hasTemplate = template !== undefined; |
| 59 | |
| 60 | if (options.cache) { |
| 61 | if (!path) { |
| 62 | throw new Error('cache option requires a filename'); |
| 63 | } |
| 64 | fn = jsCache[path]; |
| 65 | if (fn) { |
| 66 | return fn; |
| 67 | } |
| 68 | if (!hasTemplate) { |
| 69 | template = fs.readFileSync(path, {encoding: 'utf8'}); |
| 70 | } |
| 71 | } |
| 72 | else if (!hasTemplate) { |
| 73 | if (!path) { |
| 74 | throw new Error('Internal EJS error: no file name or template ' |
| 75 | + 'provided'); |
| 76 | } |
| 77 | template = fs.readFileSync(path, {encoding: 'utf8'}); |
| 78 | } |
| 79 | fn = exports.compile(template.trim(), options); |
| 80 | if (options.cache) { |
| 81 | jsCache[path] = fn; |
| 82 | } |
| 83 | return fn; |
| 84 | } |
| 85 | |
| 86 | function includeFile(path, options) { |
| 87 | var opts = utils.shallowCopy({}, options || /* istanbul ignore next */ {}); |
| 88 | if (!opts.filename) { |
| 89 | throw new Error('`include` requires the \'filename\' option.'); |
| 90 | } |
| 91 | opts.filename = exports.resolveInclude(path, opts.filename); |
| 92 | return handleCache(opts); |
| 93 | } |
| 94 | |
| 95 | function includeSource(path, options) { |
| 96 | var opts = utils.shallowCopy({}, options || {}) |
| 97 | , includePath |
| 98 | , template; |
| 99 | if (!opts.filename) { |
| 100 | throw new Error('`include` requires the \'filename\' option.'); |
| 101 | } |
| 102 | includePath = exports.resolveInclude(path, opts.filename); |
| 103 | template = fs.readFileSync(includePath).toString().trim(); |
| 104 | |
| 105 | opts.filename = includePath; |
| 106 | var templ = new Template(template, opts); |
| 107 | templ.generateSource(); |
| 108 | return templ.source; |
| 109 | } |
| 110 | |
| 111 | function rethrow(err, str, filename, lineno){ |
| 112 | var lines = str.split('\n') |
| 113 | , start = Math.max(lineno - 3, 0) |
| 114 | , end = Math.min(lines.length, lineno + 3); |
| 115 | |
| 116 | // Error context |
| 117 | var context = lines.slice(start, end).map(function (line, i){ |
| 118 | var curr = i + start + 1; |
| 119 | return (curr == lineno ? ' >> ' : ' ') |
| 120 | + curr |
| 121 | + '| ' |
| 122 | + line; |
| 123 | }).join('\n'); |
| 124 | |
| 125 | // Alter exception message |
| 126 | err.path = filename; |
| 127 | err.message = (filename || 'ejs') + ':' |
| 128 | + lineno + '\n' |
| 129 | + context + '\n\n' |
| 130 | + err.message; |
| 131 | |
| 132 | throw err; |
| 133 | } |
| 134 | |
| 135 | function cpOptsInData(data, opts) { |
| 136 | _OPTS.forEach(function (p) { |
| 137 | if (typeof data[p] != 'undefined') { |
| 138 | opts[p] = data[p]; |
| 139 | } |
| 140 | }); |
| 141 | delete data.__expressRender__; |
| 142 | } |
| 143 | |
| 144 | function compile(template, opts) { |
| 145 | var templ; |
| 146 | |
| 147 | // v1 compat |
| 148 | // 'scope' is 'context' |
| 149 | // FIXME: Remove this in a future version |
| 150 | if (opts && opts.scope) { |
| 151 | if (!opts.context) { |
| 152 | opts.context = opts.scope; |
| 153 | } |
| 154 | delete opts.scope; |
| 155 | } |
| 156 | templ = new Template(template, opts); |
| 157 | return templ.compile(); |
| 158 | } |
| 159 | exports.compile = compile; |
| 160 | |
| 161 | // template, [data], [opts] |
| 162 | // Have to include an empty data object if you want opts and no data |
| 163 | exports.render = function (template, data, opts) { |
| 164 | data = data || {}; |
| 165 | opts = opts || {}; |
| 166 | var fn; |
| 167 | |
| 168 | // No options object -- if there are optiony names |
| 169 | // in the data, copy them to options |
| 170 | if (arguments.length == 2) { |
| 171 | cpOptsInData(data, opts); |
| 172 | } |
| 173 | |
| 174 | fn = handleCache(opts, template); |
| 175 | return fn.call(opts.context, data); |
| 176 | }; |
| 177 | |
| 178 | // path, [data], [opts], cb |
| 179 | // Have to include an empty data object if you want opts and no data |
| 180 | exports.renderFile = function () { |
| 181 | var args = Array.prototype.slice.call(arguments) |
| 182 | , path = args.shift() |
| 183 | , cb = args.pop() |
| 184 | , data = args.shift() || {} |
| 185 | , opts = args.pop() || {} |
| 186 | , result |
| 187 | , failed = false; |
| 188 | |
| 189 | // No options object -- if there are optiony names |
| 190 | // in the data, copy them to options |
| 191 | if (arguments.length == 3) { |
| 192 | cpOptsInData(data, opts); |
| 193 | } |
| 194 | opts.filename = path; |
| 195 | |
| 196 | try { |
| 197 | result = handleCache(opts)(data); |
| 198 | } |
| 199 | catch(err) { |
| 200 | return process.nextTick(function () { |
| 201 | cb(err); |
| 202 | }); |
| 203 | } |
| 204 | process.nextTick(function () { |
| 205 | cb(null, result); |
| 206 | }); |
| 207 | }; |
| 208 | |
| 209 | exports.clearCache = function () { |
| 210 | jsCache = {}; |
| 211 | }; |
| 212 | |
| 213 | function Template(text, opts) { |
| 214 | opts = opts || {}; |
| 215 | var options = {}; |
| 216 | this.templateText = text; |
| 217 | this.mode = null; |
| 218 | this.truncate = false; |
| 219 | this.currentLine = 1; |
| 220 | this.source = ''; |
| 221 | options.client = opts.client || false; |
| 222 | options.escapeFunction = opts.escape || utils.escapeXML; |
| 223 | options.compileDebug = opts.compileDebug !== false; |
| 224 | options.debug = !!opts.debug; |
| 225 | options.filename = opts.filename; |
| 226 | options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER; |
| 227 | options._with = typeof opts._with != 'undefined' ? opts._with : true; |
| 228 | options.cache = opts.cache || false; |
| 229 | this.opts = options; |
| 230 | |
| 231 | this.regex = this.createRegex(); |
| 232 | } |
| 233 | |
| 234 | Template.modes = { |
| 235 | EVAL: 'eval' |
| 236 | , ESCAPED: 'escaped' |
| 237 | , RAW: 'raw' |
| 238 | , COMMENT: 'comment' |
| 239 | , LITERAL: 'literal' |
| 240 | }; |
| 241 | |
| 242 | Template.prototype = new function () { |
| 243 | this.createRegex = function () { |
| 244 | var str = _REGEX_STRING |
| 245 | , delim = utils.escapeRegExpChars(this.opts.delimiter); |
| 246 | str = str.replace(/%/g, delim); |
| 247 | return new RegExp(str); |
| 248 | }; |
| 249 | |
| 250 | this.compile = function () { |
| 251 | var src |
| 252 | , fn |
| 253 | , opts = this.opts |
| 254 | , escape = opts.escapeFunction; |
| 255 | |
| 256 | if (!this.source) { |
| 257 | this.generateSource(); |
| 258 | var prepended = 'var __output = [];'; |
| 259 | if (opts._with !== false) { |
| 260 | prepended += ' with (' + exports.localsName + ' || {}) { '; |
| 261 | } |
| 262 | this.source = prepended + this.source; |
| 263 | if (opts._with !== false) { |
| 264 | this.source += '}'; |
| 265 | } |
| 266 | this.source += ';return __output.join("").trim();'; |
| 267 | } |
| 268 | |
| 269 | if (opts.compileDebug) { |
| 270 | src = 'var __line = 1' + |
| 271 | ', __lines = ' + JSON.stringify(this.templateText) + |
| 272 | ', __filename = ' + (opts.filename ? |
| 273 | JSON.stringify(opts.filename) : 'undefined') + |
| 274 | '; try {' + |
| 275 | this.source + '} catch (e) { rethrow(e, __lines, __filename, __line); }'; |
| 276 | } |
| 277 | else { |
| 278 | src = this.source; |
| 279 | } |
| 280 | |
| 281 | if (opts.debug) { |
| 282 | console.log(src); |
| 283 | } |
| 284 | |
| 285 | if (opts.client) { |
| 286 | if (escape !== utils.escapeXML) { |
| 287 | src = 'escape = escape || ' + escape.toString() + ';\n' + src; |
| 288 | } |
| 289 | else { |
| 290 | src = utils.escapeFuncStr |
| 291 | + 'escape = escape || ' |
| 292 | + escape.toString() + ';\n' |
| 293 | + src; |
| 294 | } |
| 295 | if (opts.compileDebug) { |
| 296 | src = 'rethrow = rethrow || ' + rethrow.toString() + ';\n' + src; |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | try { |
| 301 | fn = new Function(exports.localsName + ', escape, include, rethrow', src); |
| 302 | } |
| 303 | catch(e) { |
| 304 | if (e instanceof SyntaxError) { |
| 305 | if (opts.filename) { |
| 306 | e.message += ' in ' + opts.filename; |
| 307 | } |
| 308 | e.message += ' while compiling ejs'; |
| 309 | throw e; |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | if (opts.client) { |
| 314 | return fn; |
| 315 | } |
| 316 | |
| 317 | // Return a callable function which will execute the function |
| 318 | // created by the source-code, with the passed data as locals |
| 319 | return function (data) { |
| 320 | var include = function (path, includeData) { |
| 321 | var d = utils.shallowCopy({}, data); |
| 322 | if (includeData) { |
| 323 | d = utils.shallowCopy(d, includeData); |
| 324 | } |
| 325 | return includeFile(path, opts)(d); |
| 326 | }; |
| 327 | return fn(data || {}, escape, include, rethrow); |
| 328 | }; |
| 329 | |
| 330 | }; |
| 331 | |
| 332 | this.generateSource = function () { |
| 333 | var self = this |
| 334 | , matches = this.parseTemplateText() |
| 335 | , d = this.opts.delimiter; |
| 336 | |
| 337 | if (matches && matches.length) { |
| 338 | matches.forEach(function (line, index) { |
| 339 | var closing |
| 340 | , include |
| 341 | , includeOpts |
| 342 | , includeSrc; |
| 343 | // If this is an opening tag, check for closing tags |
| 344 | // FIXME: May end up with some false positives here |
| 345 | // Better to store modes as k/v with '<' + delimiter as key |
| 346 | // Then this can simply check against the map |
| 347 | if ( line.indexOf('<' + d) === 0 // If it is a tag |
| 348 | && line.indexOf('<' + d + d) !== 0) { // and is not escaped |
| 349 | closing = matches[index + 2]; |
| 350 | if (!(closing == d + '>' || closing == '-' + d + '>')) { |
| 351 | throw new Error('Could not find matching close tag for "' + line + '".'); |
| 352 | } |
| 353 | } |
| 354 | // HACK: backward-compat `include` preprocessor directives |
| 355 | if ((include = line.match(/^\s*include\s+(\S+)/))) { |
| 356 | includeOpts = utils.shallowCopy({}, self.opts); |
| 357 | includeSrc = includeSource(include[1], includeOpts); |
| 358 | includeSrc = ';(function(){' + includeSrc + '})();'; |
| 359 | self.source += includeSrc; |
| 360 | } |
| 361 | else { |
| 362 | self.scanLine(line); |
| 363 | } |
| 364 | }); |
| 365 | } |
| 366 | |
| 367 | }; |
| 368 | |
| 369 | this.parseTemplateText = function () { |
| 370 | var str = this.templateText |
| 371 | , pat = this.regex |
| 372 | , result = pat.exec(str) |
| 373 | , arr = [] |
| 374 | , firstPos |
| 375 | , lastPos; |
| 376 | |
| 377 | while (result) { |
| 378 | firstPos = result.index; |
| 379 | lastPos = pat.lastIndex; |
| 380 | |
| 381 | if (firstPos !== 0) { |
| 382 | arr.push(str.substring(0, firstPos)); |
| 383 | str = str.slice(firstPos); |
| 384 | } |
| 385 | |
| 386 | arr.push(result[0]); |
| 387 | str = str.slice(result[0].length); |
| 388 | result = pat.exec(str); |
| 389 | } |
| 390 | |
| 391 | if (str) { |
| 392 | arr.push(str); |
| 393 | } |
| 394 | |
| 395 | return arr; |
| 396 | }; |
| 397 | |
| 398 | this.scanLine = function (line) { |
| 399 | var self = this |
| 400 | , d = this.opts.delimiter |
| 401 | , newLineCount = 0; |
| 402 | |
| 403 | function _addOutput() { |
| 404 | if (self.truncate) { |
| 405 | line = line.replace('\n', ''); |
| 406 | } |
| 407 | |
| 408 | // Preserve literal slashes |
| 409 | line = line.replace(/\\/g, '\\\\'); |
| 410 | |
| 411 | // Convert linebreaks |
| 412 | line = line.replace(/\n/g, '\\n'); |
| 413 | line = line.replace(/\r/g, '\\r'); |
| 414 | |
| 415 | // Escape double-quotes |
| 416 | // - this will be the delimiter during execution |
| 417 | line = line.replace(/"/g, '\\"'); |
| 418 | self.source += ';__output.push("' + line + '");'; |
| 419 | } |
| 420 | |
| 421 | newLineCount = (line.split('\n').length - 1); |
| 422 | |
| 423 | switch (line) { |
| 424 | case '<' + d: |
| 425 | this.mode = Template.modes.EVAL; |
| 426 | break; |
| 427 | case '<' + d + '=': |
| 428 | this.mode = Template.modes.ESCAPED; |
| 429 | break; |
| 430 | case '<' + d + '-': |
| 431 | this.mode = Template.modes.RAW; |
| 432 | break; |
| 433 | case '<' + d + '#': |
| 434 | this.mode = Template.modes.COMMENT; |
| 435 | break; |
| 436 | case '<' + d + d: |
| 437 | this.mode = Template.modes.LITERAL; |
| 438 | this.source += ';__output.push("' + line.replace('<' + d + d, '<' + d) + '");'; |
| 439 | break; |
| 440 | case d + '>': |
| 441 | case '-' + d + '>': |
| 442 | if (this.mode == Template.modes.LITERAL) { |
| 443 | _addOutput(); |
| 444 | } |
| 445 | |
| 446 | this.mode = null; |
| 447 | this.truncate = line.indexOf('-') === 0; |
| 448 | break; |
| 449 | default: |
| 450 | // In script mode, depends on type of tag |
| 451 | if (this.mode) { |
| 452 | // If '//' is found without a line break, add a line break. |
| 453 | switch (this.mode) { |
| 454 | case Template.modes.EVAL: |
| 455 | case Template.modes.ESCAPED: |
| 456 | case Template.modes.RAW: |
| 457 | if (line.lastIndexOf('//') > line.lastIndexOf('\n')) { |
| 458 | line += '\n'; |
| 459 | } |
| 460 | } |
| 461 | switch (this.mode) { |
| 462 | // Just executing code |
| 463 | case Template.modes.EVAL: |
| 464 | this.source += ';' + line; |
| 465 | break; |
| 466 | // Exec, esc, and output |
| 467 | case Template.modes.ESCAPED: |
| 468 | // Add the exec'd, escaped result to the output |
| 469 | // Have to prevent the string-coercion of `undefined` and `null` |
| 470 | // in the `escape` function -- making a `join` call like below unnecessary |
| 471 | this.source += ';__output.push(escape(' + |
| 472 | line.replace(_TRAILING_SEMCOL, '').trim() + '))'; |
| 473 | break; |
| 474 | // Exec and output |
| 475 | case Template.modes.RAW: |
| 476 | // Add the exec'd result to the output |
| 477 | // Using `join` here prevents string-coercion of `undefined` and `null` |
| 478 | // without filtering out falsey values like zero |
| 479 | this.source += ';__output.push(' + |
| 480 | line.replace(_TRAILING_SEMCOL, '').trim() + ')'; |
| 481 | break; |
| 482 | case Template.modes.COMMENT: |
| 483 | // Do nothing |
| 484 | break; |
| 485 | // Literal <%% mode, append as raw output |
| 486 | case Template.modes.LITERAL: |
| 487 | _addOutput(); |
| 488 | break; |
| 489 | } |
| 490 | } |
| 491 | // In string mode, just add the output |
| 492 | else { |
| 493 | _addOutput(); |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | if (self.opts.compileDebug && newLineCount) { |
| 498 | this.currentLine += newLineCount; |
| 499 | this.source += ';__line = ' + this.currentLine + ';'; |
| 500 | } |
| 501 | }; |
| 502 | }; |
| 503 | |
| 504 | // Express support |
| 505 | exports.__express = exports.renderFile; |
| 506 | |
| 507 | // Add require support |
| 508 | /* istanbul ignore else */ |
| 509 | if (require.extensions) { |
| 510 | require.extensions['.ejs'] = function (module, filename) { |
| 511 | filename = filename || /* istanbul ignore next */ module.filename; |
| 512 | var options = { |
| 513 | filename: filename |
| 514 | , client: true |
| 515 | } |
| 516 | , template = fs.readFileSync(filename).toString().trim() |
| 517 | , fn = compile(template, options); |
| 518 | module._compile('module.exports = ' + fn.toString() + ';', filename); |
| 519 | }; |
| 520 | } |
| 521 | |
| 522 | exports.VERSION = _VERSION_STRING; |
| 523 | |
| 524 | /* istanbul ignore if */ |
| 525 | if (typeof window != 'undefined') { |
| 526 | window.ejs = exports; |
| 527 | } |
| 528 | |
| 529 | }).call(this,require('_process')) |
| 530 | },{"../package.json":6,"./utils":2,"_process":5,"fs":3,"path":4}],2:[function(require,module,exports){ |
| 531 | /* |
| 532 | * EJS Embedded JavaScript templates |
| 533 | * Copyright 2112 Matthew Eernisse (mde@fleegix.org) |
| 534 | * |
| 535 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 536 | * you may not use this file except in compliance with the License. |
| 537 | * You may obtain a copy of the License at |
| 538 | * |
| 539 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 540 | * |
| 541 | * Unless required by applicable law or agreed to in writing, software |
| 542 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 543 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 544 | * See the License for the specific language governing permissions and |
| 545 | * limitations under the License. |
| 546 | * |
| 547 | */ |
| 548 | |
| 549 | 'use strict'; |
| 550 | |
| 551 | var regExpChars = /[|\\{}()[\]^$+*?.]/g; |
| 552 | |
| 553 | exports.escapeRegExpChars = function (string) { |
| 554 | // istanbul ignore if |
| 555 | if (!string) { |
| 556 | return ''; |
| 557 | } |
| 558 | return String(string).replace(regExpChars, '\\$&'); |
| 559 | }; |
| 560 | |
| 561 | var encodeHTMLRules = { |
| 562 | '&': '&' |
| 563 | , '<': '<' |
| 564 | , '>': '>' |
| 565 | , '"': '"' |
| 566 | , "'": ''' |
| 567 | } |
| 568 | , matchHTML = /[&<>\'"]/g; |
| 569 | |
| 570 | exports.escapeFuncStr = |
| 571 | 'var encodeHTMLRules = {' |
| 572 | + '"&": "&"' |
| 573 | + ', "<": "<"' |
| 574 | + ', ">": ">"' |
| 575 | + ', \'"\': """' |
| 576 | + ', "\'": "'"' |
| 577 | + '}' |
| 578 | + ', matchHTML = /[&<>\'"]/g;'; |
| 579 | |
| 580 | exports.escapeXML = function (markup) { |
| 581 | return markup == undefined |
| 582 | ? '' |
| 583 | : String(markup) |
| 584 | .replace(matchHTML, function(m) { |
| 585 | return encodeHTMLRules[m] || m; |
| 586 | }); |
| 587 | }; |
| 588 | |
| 589 | exports.shallowCopy = function (to, from) { |
| 590 | for (var p in from) { |
| 591 | to[p] = from[p]; |
| 592 | } |
| 593 | return to; |
| 594 | }; |
| 595 | |
| 596 | |
| 597 | },{}],3:[function(require,module,exports){ |
| 598 | |
| 599 | },{}],4:[function(require,module,exports){ |
| 600 | (function (process){ |
| 601 | // Copyright Joyent, Inc. and other Node contributors. |
| 602 | // |
| 603 | // Permission is hereby granted, free of charge, to any person obtaining a |
| 604 | // copy of this software and associated documentation files (the |
| 605 | // "Software"), to deal in the Software without restriction, including |
| 606 | // without limitation the rights to use, copy, modify, merge, publish, |
| 607 | // distribute, sublicense, and/or sell copies of the Software, and to permit |
| 608 | // persons to whom the Software is furnished to do so, subject to the |
| 609 | // following conditions: |
| 610 | // |
| 611 | // The above copyright notice and this permission notice shall be included |
| 612 | // in all copies or substantial portions of the Software. |
| 613 | // |
| 614 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 615 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 616 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
| 617 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| 618 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| 619 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
| 620 | // USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 621 | |
| 622 | // resolves . and .. elements in a path array with directory names there |
| 623 | // must be no slashes, empty elements, or device names (c:\) in the array |
| 624 | // (so also no leading and trailing slashes - it does not distinguish |
| 625 | // relative and absolute paths) |
| 626 | function normalizeArray(parts, allowAboveRoot) { |
| 627 | // if the path tries to go above the root, `up` ends up > 0 |
| 628 | var up = 0; |
| 629 | for (var i = parts.length - 1; i >= 0; i--) { |
| 630 | var last = parts[i]; |
| 631 | if (last === '.') { |
| 632 | parts.splice(i, 1); |
| 633 | } else if (last === '..') { |
| 634 | parts.splice(i, 1); |
| 635 | up++; |
| 636 | } else if (up) { |
| 637 | parts.splice(i, 1); |
| 638 | up--; |
| 639 | } |
| 640 | } |
| 641 | |
| 642 | // if the path is allowed to go above the root, restore leading ..s |
| 643 | if (allowAboveRoot) { |
| 644 | for (; up--; up) { |
| 645 | parts.unshift('..'); |
| 646 | } |
| 647 | } |
| 648 | |
| 649 | return parts; |
| 650 | } |
| 651 | |
| 652 | // Split a filename into [root, dir, basename, ext], unix version |
| 653 | // 'root' is just a slash, or nothing. |
| 654 | var splitPathRe = |
| 655 | /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; |
| 656 | var splitPath = function(filename) { |
| 657 | return splitPathRe.exec(filename).slice(1); |
| 658 | }; |
| 659 | |
| 660 | // path.resolve([from ...], to) |
| 661 | // posix version |
| 662 | exports.resolve = function() { |
| 663 | var resolvedPath = '', |
| 664 | resolvedAbsolute = false; |
| 665 | |
| 666 | for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { |
| 667 | var path = (i >= 0) ? arguments[i] : process.cwd(); |
| 668 | |
| 669 | // Skip empty and invalid entries |
| 670 | if (typeof path !== 'string') { |
| 671 | throw new TypeError('Arguments to path.resolve must be strings'); |
| 672 | } else if (!path) { |
| 673 | continue; |
| 674 | } |
| 675 | |
| 676 | resolvedPath = path + '/' + resolvedPath; |
| 677 | resolvedAbsolute = path.charAt(0) === '/'; |
| 678 | } |
| 679 | |
| 680 | // At this point the path should be resolved to a full absolute path, but |
| 681 | // handle relative paths to be safe (might happen when process.cwd() fails) |
| 682 | |
| 683 | // Normalize the path |
| 684 | resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { |
| 685 | return !!p; |
| 686 | }), !resolvedAbsolute).join('/'); |
| 687 | |
| 688 | return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; |
| 689 | }; |
| 690 | |
| 691 | // path.normalize(path) |
| 692 | // posix version |
| 693 | exports.normalize = function(path) { |
| 694 | var isAbsolute = exports.isAbsolute(path), |
| 695 | trailingSlash = substr(path, -1) === '/'; |
| 696 | |
| 697 | // Normalize the path |
| 698 | path = normalizeArray(filter(path.split('/'), function(p) { |
| 699 | return !!p; |
| 700 | }), !isAbsolute).join('/'); |
| 701 | |
| 702 | if (!path && !isAbsolute) { |
| 703 | path = '.'; |
| 704 | } |
| 705 | if (path && trailingSlash) { |
| 706 | path += '/'; |
| 707 | } |
| 708 | |
| 709 | return (isAbsolute ? '/' : '') + path; |
| 710 | }; |
| 711 | |
| 712 | // posix version |
| 713 | exports.isAbsolute = function(path) { |
| 714 | return path.charAt(0) === '/'; |
| 715 | }; |
| 716 | |
| 717 | // posix version |
| 718 | exports.join = function() { |
| 719 | var paths = Array.prototype.slice.call(arguments, 0); |
| 720 | return exports.normalize(filter(paths, function(p, index) { |
| 721 | if (typeof p !== 'string') { |
| 722 | throw new TypeError('Arguments to path.join must be strings'); |
| 723 | } |
| 724 | return p; |
| 725 | }).join('/')); |
| 726 | }; |
| 727 | |
| 728 | |
| 729 | // path.relative(from, to) |
| 730 | // posix version |
| 731 | exports.relative = function(from, to) { |
| 732 | from = exports.resolve(from).substr(1); |
| 733 | to = exports.resolve(to).substr(1); |
| 734 | |
| 735 | function trim(arr) { |
| 736 | var start = 0; |
| 737 | for (; start < arr.length; start++) { |
| 738 | if (arr[start] !== '') break; |
| 739 | } |
| 740 | |
| 741 | var end = arr.length - 1; |
| 742 | for (; end >= 0; end--) { |
| 743 | if (arr[end] !== '') break; |
| 744 | } |
| 745 | |
| 746 | if (start > end) return []; |
| 747 | return arr.slice(start, end - start + 1); |
| 748 | } |
| 749 | |
| 750 | var fromParts = trim(from.split('/')); |
| 751 | var toParts = trim(to.split('/')); |
| 752 | |
| 753 | var length = Math.min(fromParts.length, toParts.length); |
| 754 | var samePartsLength = length; |
| 755 | for (var i = 0; i < length; i++) { |
| 756 | if (fromParts[i] !== toParts[i]) { |
| 757 | samePartsLength = i; |
| 758 | break; |
| 759 | } |
| 760 | } |
| 761 | |
| 762 | var outputParts = []; |
| 763 | for (var i = samePartsLength; i < fromParts.length; i++) { |
| 764 | outputParts.push('..'); |
| 765 | } |
| 766 | |
| 767 | outputParts = outputParts.concat(toParts.slice(samePartsLength)); |
| 768 | |
| 769 | return outputParts.join('/'); |
| 770 | }; |
| 771 | |
| 772 | exports.sep = '/'; |
| 773 | exports.delimiter = ':'; |
| 774 | |
| 775 | exports.dirname = function(path) { |
| 776 | var result = splitPath(path), |
| 777 | root = result[0], |
| 778 | dir = result[1]; |
| 779 | |
| 780 | if (!root && !dir) { |
| 781 | // No dirname whatsoever |
| 782 | return '.'; |
| 783 | } |
| 784 | |
| 785 | if (dir) { |
| 786 | // It has a dirname, strip trailing slash |
| 787 | dir = dir.substr(0, dir.length - 1); |
| 788 | } |
| 789 | |
| 790 | return root + dir; |
| 791 | }; |
| 792 | |
| 793 | |
| 794 | exports.basename = function(path, ext) { |
| 795 | var f = splitPath(path)[2]; |
| 796 | // TODO: make this comparison case-insensitive on windows? |
| 797 | if (ext && f.substr(-1 * ext.length) === ext) { |
| 798 | f = f.substr(0, f.length - ext.length); |
| 799 | } |
| 800 | return f; |
| 801 | }; |
| 802 | |
| 803 | |
| 804 | exports.extname = function(path) { |
| 805 | return splitPath(path)[3]; |
| 806 | }; |
| 807 | |
| 808 | function filter (xs, f) { |
| 809 | if (xs.filter) return xs.filter(f); |
| 810 | var res = []; |
| 811 | for (var i = 0; i < xs.length; i++) { |
| 812 | if (f(xs[i], i, xs)) res.push(xs[i]); |
| 813 | } |
| 814 | return res; |
| 815 | } |
| 816 | |
| 817 | // String.prototype.substr - negative index don't work in IE8 |
| 818 | var substr = 'ab'.substr(-1) === 'b' |
| 819 | ? function (str, start, len) { return str.substr(start, len) } |
| 820 | : function (str, start, len) { |
| 821 | if (start < 0) start = str.length + start; |
| 822 | return str.substr(start, len); |
| 823 | } |
| 824 | ; |
| 825 | |
| 826 | }).call(this,require('_process')) |
| 827 | },{"_process":5}],5:[function(require,module,exports){ |
| 828 | // shim for using process in browser |
| 829 | |
| 830 | var process = module.exports = {}; |
| 831 | var queue = []; |
| 832 | var draining = false; |
| 833 | |
| 834 | function drainQueue() { |
| 835 | if (draining) { |
| 836 | return; |
| 837 | } |
| 838 | draining = true; |
| 839 | var currentQueue; |
| 840 | var len = queue.length; |
| 841 | while(len) { |
| 842 | currentQueue = queue; |
| 843 | queue = []; |
| 844 | var i = -1; |
| 845 | while (++i < len) { |
| 846 | currentQueue[i](); |
| 847 | } |
| 848 | len = queue.length; |
| 849 | } |
| 850 | draining = false; |
| 851 | } |
| 852 | process.nextTick = function (fun) { |
| 853 | queue.push(fun); |
| 854 | if (!draining) { |
| 855 | setTimeout(drainQueue, 0); |
| 856 | } |
| 857 | }; |
| 858 | |
| 859 | process.title = 'browser'; |
| 860 | process.browser = true; |
| 861 | process.env = {}; |
| 862 | process.argv = []; |
| 863 | process.version = ''; // empty string to avoid regexp issues |
| 864 | |
| 865 | function noop() {} |
| 866 | |
| 867 | process.on = noop; |
| 868 | process.addListener = noop; |
| 869 | process.once = noop; |
| 870 | process.off = noop; |
| 871 | process.removeListener = noop; |
| 872 | process.removeAllListeners = noop; |
| 873 | process.emit = noop; |
| 874 | |
| 875 | process.binding = function (name) { |
| 876 | throw new Error('process.binding is not supported'); |
| 877 | }; |
| 878 | |
| 879 | // TODO(shtylman) |
| 880 | process.cwd = function () { return '/' }; |
| 881 | process.chdir = function (dir) { |
| 882 | throw new Error('process.chdir is not supported'); |
| 883 | }; |
| 884 | process.umask = function() { return 0; }; |
| 885 | |
| 886 | },{}],6:[function(require,module,exports){ |
| 887 | module.exports={ |
| 888 | "name": "ejs", |
| 889 | "description": "Embedded JavaScript templates", |
| 890 | "keywords": [ |
| 891 | "template", |
| 892 | "engine", |
| 893 | "ejs" |
| 894 | ], |
| 895 | "version": "2.2.3", |
| 896 | "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)", |
| 897 | "contributors": [ |
| 898 | "Timothy Gu <timothygu99@gmail.com> (https://timothygu.github.io)" |
| 899 | ], |
| 900 | "license": "Apache-2.0", |
| 901 | "main": "./lib/ejs.js", |
| 902 | "repository": { |
| 903 | "type": "git", |
| 904 | "url": "git://github.com/mde/ejs.git" |
| 905 | }, |
| 906 | "bugs": "https://github.com/mde/ejs/issues", |
| 907 | "homepage": "https://github.com/mde/ejs", |
| 908 | "dependencies": {}, |
| 909 | "devDependencies": { |
| 910 | "browserify": "^8.0.3", |
| 911 | "uglify-js": "^2.4.16", |
| 912 | "mocha": "^2.1.0", |
| 913 | "jake": "^8.0.0", |
| 914 | "istanbul": "~0.3.5" |
| 915 | }, |
| 916 | "engines": { |
| 917 | "node": ">=0.10.0" |
| 918 | }, |
| 919 | "scripts": { |
| 920 | "test": "mocha", |
| 921 | "coverage": "istanbul cover node_modules/mocha/bin/_mocha" |
| 922 | } |
| 923 | } |
| 924 | },{}]},{},[1]); |