ejs.js 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ejs = f()}})(function(){var define,module,exports;return (function(){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}return e})()({1:[function(require,module,exports){
  2. /*
  3. * EJS Embedded JavaScript templates
  4. * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19. 'use strict';
  20. /**
  21. * @file Embedded JavaScript templating engine. {@link http://ejs.co}
  22. * @author Matthew Eernisse <mde@fleegix.org>
  23. * @author Tiancheng "Timothy" Gu <timothygu99@gmail.com>
  24. * @project EJS
  25. * @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
  26. */
  27. /**
  28. * EJS internal functions.
  29. *
  30. * Technically this "module" lies in the same file as {@link module:ejs}, for
  31. * the sake of organization all the private functions re grouped into this
  32. * module.
  33. *
  34. * @module ejs-internal
  35. * @private
  36. */
  37. /**
  38. * Embedded JavaScript templating engine.
  39. *
  40. * @module ejs
  41. * @public
  42. */
  43. var fs = require('fs');
  44. var path = require('path');
  45. var utils = require('./utils');
  46. var scopeOptionWarned = false;
  47. var _VERSION_STRING = require('../package.json').version;
  48. var _DEFAULT_DELIMITER = '%';
  49. var _DEFAULT_LOCALS_NAME = 'locals';
  50. var _NAME = 'ejs';
  51. var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)';
  52. var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
  53. 'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async'];
  54. // We don't allow 'cache' option to be passed in the data obj for
  55. // the normal `render` call, but this is where Express 2 & 3 put it
  56. // so we make an exception for `renderFile`
  57. var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache');
  58. var _BOM = /^\uFEFF/;
  59. /**
  60. * EJS template function cache. This can be a LRU object from lru-cache NPM
  61. * module. By default, it is {@link module:utils.cache}, a simple in-process
  62. * cache that grows continuously.
  63. *
  64. * @type {Cache}
  65. */
  66. exports.cache = utils.cache;
  67. /**
  68. * Custom file loader. Useful for template preprocessing or restricting access
  69. * to a certain part of the filesystem.
  70. *
  71. * @type {fileLoader}
  72. */
  73. exports.fileLoader = fs.readFileSync;
  74. /**
  75. * Name of the object containing the locals.
  76. *
  77. * This variable is overridden by {@link Options}`.localsName` if it is not
  78. * `undefined`.
  79. *
  80. * @type {String}
  81. * @public
  82. */
  83. exports.localsName = _DEFAULT_LOCALS_NAME;
  84. /**
  85. * Promise implementation -- defaults to the native implementation if available
  86. * This is mostly just for testability
  87. *
  88. * @type {Function}
  89. * @public
  90. */
  91. exports.promiseImpl = (new Function('return this;'))().Promise;
  92. /**
  93. * Get the path to the included file from the parent file path and the
  94. * specified path.
  95. *
  96. * @param {String} name specified path
  97. * @param {String} filename parent file path
  98. * @param {Boolean} isDir parent file path whether is directory
  99. * @return {String}
  100. */
  101. exports.resolveInclude = function(name, filename, isDir) {
  102. var dirname = path.dirname;
  103. var extname = path.extname;
  104. var resolve = path.resolve;
  105. var includePath = resolve(isDir ? filename : dirname(filename), name);
  106. var ext = extname(name);
  107. if (!ext) {
  108. includePath += '.ejs';
  109. }
  110. return includePath;
  111. };
  112. /**
  113. * Get the path to the included file by Options
  114. *
  115. * @param {String} path specified path
  116. * @param {Options} options compilation options
  117. * @return {String}
  118. */
  119. function getIncludePath(path, options) {
  120. var includePath;
  121. var filePath;
  122. var views = options.views;
  123. // Abs path
  124. if (path.charAt(0) == '/') {
  125. includePath = exports.resolveInclude(path.replace(/^\/*/,''), options.root || '/', true);
  126. }
  127. // Relative paths
  128. else {
  129. // Look relative to a passed filename first
  130. if (options.filename) {
  131. filePath = exports.resolveInclude(path, options.filename);
  132. if (fs.existsSync(filePath)) {
  133. includePath = filePath;
  134. }
  135. }
  136. // Then look in any views directories
  137. if (!includePath) {
  138. if (Array.isArray(views) && views.some(function (v) {
  139. filePath = exports.resolveInclude(path, v, true);
  140. return fs.existsSync(filePath);
  141. })) {
  142. includePath = filePath;
  143. }
  144. }
  145. if (!includePath) {
  146. throw new Error('Could not find the include file "' +
  147. options.escapeFunction(path) + '"');
  148. }
  149. }
  150. return includePath;
  151. }
  152. /**
  153. * Get the template from a string or a file, either compiled on-the-fly or
  154. * read from cache (if enabled), and cache the template if needed.
  155. *
  156. * If `template` is not set, the file specified in `options.filename` will be
  157. * read.
  158. *
  159. * If `options.cache` is true, this function reads the file from
  160. * `options.filename` so it must be set prior to calling this function.
  161. *
  162. * @memberof module:ejs-internal
  163. * @param {Options} options compilation options
  164. * @param {String} [template] template source
  165. * @return {(TemplateFunction|ClientFunction)}
  166. * Depending on the value of `options.client`, either type might be returned.
  167. * @static
  168. */
  169. function handleCache(options, template) {
  170. var func;
  171. var filename = options.filename;
  172. var hasTemplate = arguments.length > 1;
  173. if (options.cache) {
  174. if (!filename) {
  175. throw new Error('cache option requires a filename');
  176. }
  177. func = exports.cache.get(filename);
  178. if (func) {
  179. return func;
  180. }
  181. if (!hasTemplate) {
  182. template = fileLoader(filename).toString().replace(_BOM, '');
  183. }
  184. }
  185. else if (!hasTemplate) {
  186. // istanbul ignore if: should not happen at all
  187. if (!filename) {
  188. throw new Error('Internal EJS error: no file name or template '
  189. + 'provided');
  190. }
  191. template = fileLoader(filename).toString().replace(_BOM, '');
  192. }
  193. func = exports.compile(template, options);
  194. if (options.cache) {
  195. exports.cache.set(filename, func);
  196. }
  197. return func;
  198. }
  199. /**
  200. * Try calling handleCache with the given options and data and call the
  201. * callback with the result. If an error occurs, call the callback with
  202. * the error. Used by renderFile().
  203. *
  204. * @memberof module:ejs-internal
  205. * @param {Options} options compilation options
  206. * @param {Object} data template data
  207. * @param {RenderFileCallback} cb callback
  208. * @static
  209. */
  210. function tryHandleCache(options, data, cb) {
  211. var result;
  212. if (!cb) {
  213. if (typeof exports.promiseImpl == 'function') {
  214. return new exports.promiseImpl(function (resolve, reject) {
  215. try {
  216. result = handleCache(options)(data);
  217. resolve(result);
  218. }
  219. catch (err) {
  220. reject(err);
  221. }
  222. });
  223. }
  224. else {
  225. throw new Error('Please provide a callback function');
  226. }
  227. }
  228. else {
  229. try {
  230. result = handleCache(options)(data);
  231. }
  232. catch (err) {
  233. return cb(err);
  234. }
  235. cb(null, result);
  236. }
  237. }
  238. /**
  239. * fileLoader is independent
  240. *
  241. * @param {String} filePath ejs file path.
  242. * @return {String} The contents of the specified file.
  243. * @static
  244. */
  245. function fileLoader(filePath){
  246. return exports.fileLoader(filePath);
  247. }
  248. /**
  249. * Get the template function.
  250. *
  251. * If `options.cache` is `true`, then the template is cached.
  252. *
  253. * @memberof module:ejs-internal
  254. * @param {String} path path for the specified file
  255. * @param {Options} options compilation options
  256. * @return {(TemplateFunction|ClientFunction)}
  257. * Depending on the value of `options.client`, either type might be returned
  258. * @static
  259. */
  260. function includeFile(path, options) {
  261. var opts = utils.shallowCopy({}, options);
  262. opts.filename = getIncludePath(path, opts);
  263. return handleCache(opts);
  264. }
  265. /**
  266. * Get the JavaScript source of an included file.
  267. *
  268. * @memberof module:ejs-internal
  269. * @param {String} path path for the specified file
  270. * @param {Options} options compilation options
  271. * @return {Object}
  272. * @static
  273. */
  274. function includeSource(path, options) {
  275. var opts = utils.shallowCopy({}, options);
  276. var includePath;
  277. var template;
  278. includePath = getIncludePath(path, opts);
  279. template = fileLoader(includePath).toString().replace(_BOM, '');
  280. opts.filename = includePath;
  281. var templ = new Template(template, opts);
  282. templ.generateSource();
  283. return {
  284. source: templ.source,
  285. filename: includePath,
  286. template: template
  287. };
  288. }
  289. /**
  290. * Re-throw the given `err` in context to the `str` of ejs, `filename`, and
  291. * `lineno`.
  292. *
  293. * @implements RethrowCallback
  294. * @memberof module:ejs-internal
  295. * @param {Error} err Error object
  296. * @param {String} str EJS source
  297. * @param {String} filename file name of the EJS file
  298. * @param {String} lineno line number of the error
  299. * @static
  300. */
  301. function rethrow(err, str, flnm, lineno, esc){
  302. var lines = str.split('\n');
  303. var start = Math.max(lineno - 3, 0);
  304. var end = Math.min(lines.length, lineno + 3);
  305. var filename = esc(flnm); // eslint-disable-line
  306. // Error context
  307. var context = lines.slice(start, end).map(function (line, i){
  308. var curr = i + start + 1;
  309. return (curr == lineno ? ' >> ' : ' ')
  310. + curr
  311. + '| '
  312. + line;
  313. }).join('\n');
  314. // Alter exception message
  315. err.path = filename;
  316. err.message = (filename || 'ejs') + ':'
  317. + lineno + '\n'
  318. + context + '\n\n'
  319. + err.message;
  320. throw err;
  321. }
  322. function stripSemi(str){
  323. return str.replace(/;(\s*$)/, '$1');
  324. }
  325. /**
  326. * Compile the given `str` of ejs into a template function.
  327. *
  328. * @param {String} template EJS template
  329. *
  330. * @param {Options} opts compilation options
  331. *
  332. * @return {(TemplateFunction|ClientFunction)}
  333. * Depending on the value of `opts.client`, either type might be returned.
  334. * Note that the return type of the function also depends on the value of `opts.async`.
  335. * @public
  336. */
  337. exports.compile = function compile(template, opts) {
  338. var templ;
  339. // v1 compat
  340. // 'scope' is 'context'
  341. // FIXME: Remove this in a future version
  342. if (opts && opts.scope) {
  343. if (!scopeOptionWarned){
  344. console.warn('`scope` option is deprecated and will be removed in EJS 3');
  345. scopeOptionWarned = true;
  346. }
  347. if (!opts.context) {
  348. opts.context = opts.scope;
  349. }
  350. delete opts.scope;
  351. }
  352. templ = new Template(template, opts);
  353. return templ.compile();
  354. };
  355. /**
  356. * Render the given `template` of ejs.
  357. *
  358. * If you would like to include options but not data, you need to explicitly
  359. * call this function with `data` being an empty object or `null`.
  360. *
  361. * @param {String} template EJS template
  362. * @param {Object} [data={}] template data
  363. * @param {Options} [opts={}] compilation and rendering options
  364. * @return {(String|Promise<String>)}
  365. * Return value type depends on `opts.async`.
  366. * @public
  367. */
  368. exports.render = function (template, d, o) {
  369. var data = d || {};
  370. var opts = o || {};
  371. // No options object -- if there are optiony names
  372. // in the data, copy them to options
  373. if (arguments.length == 2) {
  374. utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
  375. }
  376. return handleCache(opts, template)(data);
  377. };
  378. /**
  379. * Render an EJS file at the given `path` and callback `cb(err, str)`.
  380. *
  381. * If you would like to include options but not data, you need to explicitly
  382. * call this function with `data` being an empty object or `null`.
  383. *
  384. * @param {String} path path to the EJS file
  385. * @param {Object} [data={}] template data
  386. * @param {Options} [opts={}] compilation and rendering options
  387. * @param {RenderFileCallback} cb callback
  388. * @public
  389. */
  390. exports.renderFile = function () {
  391. var args = Array.prototype.slice.call(arguments);
  392. var filename = args.shift();
  393. var cb;
  394. var opts = {filename: filename};
  395. var data;
  396. var viewOpts;
  397. // Do we have a callback?
  398. if (typeof arguments[arguments.length - 1] == 'function') {
  399. cb = args.pop();
  400. }
  401. // Do we have data/opts?
  402. if (args.length) {
  403. // Should always have data obj
  404. data = args.shift();
  405. // Normal passed opts (data obj + opts obj)
  406. if (args.length) {
  407. // Use shallowCopy so we don't pollute passed in opts obj with new vals
  408. utils.shallowCopy(opts, args.pop());
  409. }
  410. // Special casing for Express (settings + opts-in-data)
  411. else {
  412. // Express 3 and 4
  413. if (data.settings) {
  414. // Pull a few things from known locations
  415. if (data.settings.views) {
  416. opts.views = data.settings.views;
  417. }
  418. if (data.settings['view cache']) {
  419. opts.cache = true;
  420. }
  421. // Undocumented after Express 2, but still usable, esp. for
  422. // items that are unsafe to be passed along with data, like `root`
  423. viewOpts = data.settings['view options'];
  424. if (viewOpts) {
  425. utils.shallowCopy(opts, viewOpts);
  426. }
  427. }
  428. // Express 2 and lower, values set in app.locals, or people who just
  429. // want to pass options in their data. NOTE: These values will override
  430. // anything previously set in settings or settings['view options']
  431. utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS);
  432. }
  433. opts.filename = filename;
  434. }
  435. else {
  436. data = {};
  437. }
  438. return tryHandleCache(opts, data, cb);
  439. };
  440. /**
  441. * Clear intermediate JavaScript cache. Calls {@link Cache#reset}.
  442. * @public
  443. */
  444. exports.clearCache = function () {
  445. exports.cache.reset();
  446. };
  447. function Template(text, opts) {
  448. opts = opts || {};
  449. var options = {};
  450. this.templateText = text;
  451. this.mode = null;
  452. this.truncate = false;
  453. this.currentLine = 1;
  454. this.source = '';
  455. this.dependencies = [];
  456. options.client = opts.client || false;
  457. options.escapeFunction = opts.escape || utils.escapeXML;
  458. options.compileDebug = opts.compileDebug !== false;
  459. options.debug = !!opts.debug;
  460. options.filename = opts.filename;
  461. options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER;
  462. options.strict = opts.strict || false;
  463. options.context = opts.context;
  464. options.cache = opts.cache || false;
  465. options.rmWhitespace = opts.rmWhitespace;
  466. options.root = opts.root;
  467. options.outputFunctionName = opts.outputFunctionName;
  468. options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
  469. options.views = opts.views;
  470. options.async = opts.async;
  471. if (options.strict) {
  472. options._with = false;
  473. }
  474. else {
  475. options._with = typeof opts._with != 'undefined' ? opts._with : true;
  476. }
  477. this.opts = options;
  478. this.regex = this.createRegex();
  479. }
  480. Template.modes = {
  481. EVAL: 'eval',
  482. ESCAPED: 'escaped',
  483. RAW: 'raw',
  484. COMMENT: 'comment',
  485. LITERAL: 'literal'
  486. };
  487. Template.prototype = {
  488. createRegex: function () {
  489. var str = _REGEX_STRING;
  490. var delim = utils.escapeRegExpChars(this.opts.delimiter);
  491. str = str.replace(/%/g, delim);
  492. return new RegExp(str);
  493. },
  494. compile: function () {
  495. var src;
  496. var fn;
  497. var opts = this.opts;
  498. var prepended = '';
  499. var appended = '';
  500. var escapeFn = opts.escapeFunction;
  501. var asyncCtor;
  502. if (!this.source) {
  503. this.generateSource();
  504. prepended += ' var __output = [], __append = __output.push.bind(__output);' + '\n';
  505. if (opts.outputFunctionName) {
  506. prepended += ' var ' + opts.outputFunctionName + ' = __append;' + '\n';
  507. }
  508. if (opts._with !== false) {
  509. prepended += ' with (' + opts.localsName + ' || {}) {' + '\n';
  510. appended += ' }' + '\n';
  511. }
  512. appended += ' return __output.join("");' + '\n';
  513. this.source = prepended + this.source + appended;
  514. }
  515. if (opts.compileDebug) {
  516. src = 'var __line = 1' + '\n'
  517. + ' , __lines = ' + JSON.stringify(this.templateText) + '\n'
  518. + ' , __filename = ' + (opts.filename ?
  519. JSON.stringify(opts.filename) : 'undefined') + ';' + '\n'
  520. + 'try {' + '\n'
  521. + this.source
  522. + '} catch (e) {' + '\n'
  523. + ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
  524. + '}' + '\n';
  525. }
  526. else {
  527. src = this.source;
  528. }
  529. if (opts.client) {
  530. src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src;
  531. if (opts.compileDebug) {
  532. src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src;
  533. }
  534. }
  535. if (opts.strict) {
  536. src = '"use strict";\n' + src;
  537. }
  538. if (opts.debug) {
  539. console.log(src);
  540. }
  541. try {
  542. if (opts.async) {
  543. // Have to use generated function for this, since in envs without support,
  544. // it breaks in parsing
  545. try {
  546. asyncCtor = (new Function('return (async function(){}).constructor;'))();
  547. }
  548. catch(e) {
  549. if (e instanceof SyntaxError) {
  550. throw new Error('This environment does not support async/await');
  551. }
  552. else {
  553. throw e;
  554. }
  555. }
  556. }
  557. else {
  558. asyncCtor = Function;
  559. }
  560. fn = new asyncCtor(opts.localsName + ', escapeFn, include, rethrow', src);
  561. }
  562. catch(e) {
  563. // istanbul ignore else
  564. if (e instanceof SyntaxError) {
  565. if (opts.filename) {
  566. e.message += ' in ' + opts.filename;
  567. }
  568. e.message += ' while compiling ejs\n\n';
  569. e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n';
  570. e.message += 'https://github.com/RyanZim/EJS-Lint';
  571. if (!e.async) {
  572. e.message += '\n';
  573. e.message += 'Or, if you meant to create an async function, pass async: true as an option.';
  574. }
  575. }
  576. throw e;
  577. }
  578. if (opts.client) {
  579. fn.dependencies = this.dependencies;
  580. return fn;
  581. }
  582. // Return a callable function which will execute the function
  583. // created by the source-code, with the passed data as locals
  584. // Adds a local `include` function which allows full recursive include
  585. var returnedFn = function (data) {
  586. var include = function (path, includeData) {
  587. var d = utils.shallowCopy({}, data);
  588. if (includeData) {
  589. d = utils.shallowCopy(d, includeData);
  590. }
  591. return includeFile(path, opts)(d);
  592. };
  593. return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]);
  594. };
  595. returnedFn.dependencies = this.dependencies;
  596. return returnedFn;
  597. },
  598. generateSource: function () {
  599. var opts = this.opts;
  600. if (opts.rmWhitespace) {
  601. // Have to use two separate replace here as `^` and `$` operators don't
  602. // work well with `\r`.
  603. this.templateText =
  604. this.templateText.replace(/\r/g, '').replace(/^\s+|\s+$/gm, '');
  605. }
  606. // Slurp spaces and tabs before <%_ and after _%>
  607. this.templateText =
  608. this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
  609. var self = this;
  610. var matches = this.parseTemplateText();
  611. var d = this.opts.delimiter;
  612. if (matches && matches.length) {
  613. matches.forEach(function (line, index) {
  614. var opening;
  615. var closing;
  616. var include;
  617. var includeOpts;
  618. var includeObj;
  619. var includeSrc;
  620. // If this is an opening tag, check for closing tags
  621. // FIXME: May end up with some false positives here
  622. // Better to store modes as k/v with '<' + delimiter as key
  623. // Then this can simply check against the map
  624. if ( line.indexOf('<' + d) === 0 // If it is a tag
  625. && line.indexOf('<' + d + d) !== 0) { // and is not escaped
  626. closing = matches[index + 2];
  627. if (!(closing == d + '>' || closing == '-' + d + '>' || closing == '_' + d + '>')) {
  628. throw new Error('Could not find matching close tag for "' + line + '".');
  629. }
  630. }
  631. // HACK: backward-compat `include` preprocessor directives
  632. if ((include = line.match(/^\s*include\s+(\S+)/))) {
  633. opening = matches[index - 1];
  634. // Must be in EVAL or RAW mode
  635. if (opening && (opening == '<' + d || opening == '<' + d + '-' || opening == '<' + d + '_')) {
  636. includeOpts = utils.shallowCopy({}, self.opts);
  637. includeObj = includeSource(include[1], includeOpts);
  638. if (self.opts.compileDebug) {
  639. includeSrc =
  640. ' ; (function(){' + '\n'
  641. + ' var __line = 1' + '\n'
  642. + ' , __lines = ' + JSON.stringify(includeObj.template) + '\n'
  643. + ' , __filename = ' + JSON.stringify(includeObj.filename) + ';' + '\n'
  644. + ' try {' + '\n'
  645. + includeObj.source
  646. + ' } catch (e) {' + '\n'
  647. + ' rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
  648. + ' }' + '\n'
  649. + ' ; }).call(this)' + '\n';
  650. }else{
  651. includeSrc = ' ; (function(){' + '\n' + includeObj.source +
  652. ' ; }).call(this)' + '\n';
  653. }
  654. self.source += includeSrc;
  655. self.dependencies.push(exports.resolveInclude(include[1],
  656. includeOpts.filename));
  657. return;
  658. }
  659. }
  660. self.scanLine(line);
  661. });
  662. }
  663. },
  664. parseTemplateText: function () {
  665. var str = this.templateText;
  666. var pat = this.regex;
  667. var result = pat.exec(str);
  668. var arr = [];
  669. var firstPos;
  670. while (result) {
  671. firstPos = result.index;
  672. if (firstPos !== 0) {
  673. arr.push(str.substring(0, firstPos));
  674. str = str.slice(firstPos);
  675. }
  676. arr.push(result[0]);
  677. str = str.slice(result[0].length);
  678. result = pat.exec(str);
  679. }
  680. if (str) {
  681. arr.push(str);
  682. }
  683. return arr;
  684. },
  685. _addOutput: function (line) {
  686. if (this.truncate) {
  687. // Only replace single leading linebreak in the line after
  688. // -%> tag -- this is the single, trailing linebreak
  689. // after the tag that the truncation mode replaces
  690. // Handle Win / Unix / old Mac linebreaks -- do the \r\n
  691. // combo first in the regex-or
  692. line = line.replace(/^(?:\r\n|\r|\n)/, '');
  693. this.truncate = false;
  694. }
  695. else if (this.opts.rmWhitespace) {
  696. // rmWhitespace has already removed trailing spaces, just need
  697. // to remove linebreaks
  698. line = line.replace(/^\n/, '');
  699. }
  700. if (!line) {
  701. return line;
  702. }
  703. // Preserve literal slashes
  704. line = line.replace(/\\/g, '\\\\');
  705. // Convert linebreaks
  706. line = line.replace(/\n/g, '\\n');
  707. line = line.replace(/\r/g, '\\r');
  708. // Escape double-quotes
  709. // - this will be the delimiter during execution
  710. line = line.replace(/"/g, '\\"');
  711. this.source += ' ; __append("' + line + '")' + '\n';
  712. },
  713. scanLine: function (line) {
  714. var self = this;
  715. var d = this.opts.delimiter;
  716. var newLineCount = 0;
  717. newLineCount = (line.split('\n').length - 1);
  718. switch (line) {
  719. case '<' + d:
  720. case '<' + d + '_':
  721. this.mode = Template.modes.EVAL;
  722. break;
  723. case '<' + d + '=':
  724. this.mode = Template.modes.ESCAPED;
  725. break;
  726. case '<' + d + '-':
  727. this.mode = Template.modes.RAW;
  728. break;
  729. case '<' + d + '#':
  730. this.mode = Template.modes.COMMENT;
  731. break;
  732. case '<' + d + d:
  733. this.mode = Template.modes.LITERAL;
  734. this.source += ' ; __append("' + line.replace('<' + d + d, '<' + d) + '")' + '\n';
  735. break;
  736. case d + d + '>':
  737. this.mode = Template.modes.LITERAL;
  738. this.source += ' ; __append("' + line.replace(d + d + '>', d + '>') + '")' + '\n';
  739. break;
  740. case d + '>':
  741. case '-' + d + '>':
  742. case '_' + d + '>':
  743. if (this.mode == Template.modes.LITERAL) {
  744. this._addOutput(line);
  745. }
  746. this.mode = null;
  747. this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
  748. break;
  749. default:
  750. // In script mode, depends on type of tag
  751. if (this.mode) {
  752. // If '//' is found without a line break, add a line break.
  753. switch (this.mode) {
  754. case Template.modes.EVAL:
  755. case Template.modes.ESCAPED:
  756. case Template.modes.RAW:
  757. if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
  758. line += '\n';
  759. }
  760. }
  761. switch (this.mode) {
  762. // Just executing code
  763. case Template.modes.EVAL:
  764. this.source += ' ; ' + line + '\n';
  765. break;
  766. // Exec, esc, and output
  767. case Template.modes.ESCAPED:
  768. this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\n';
  769. break;
  770. // Exec and output
  771. case Template.modes.RAW:
  772. this.source += ' ; __append(' + stripSemi(line) + ')' + '\n';
  773. break;
  774. case Template.modes.COMMENT:
  775. // Do nothing
  776. break;
  777. // Literal <%% mode, append as raw output
  778. case Template.modes.LITERAL:
  779. this._addOutput(line);
  780. break;
  781. }
  782. }
  783. // In string mode, just add the output
  784. else {
  785. this._addOutput(line);
  786. }
  787. }
  788. if (self.opts.compileDebug && newLineCount) {
  789. this.currentLine += newLineCount;
  790. this.source += ' ; __line = ' + this.currentLine + '\n';
  791. }
  792. }
  793. };
  794. /**
  795. * Escape characters reserved in XML.
  796. *
  797. * This is simply an export of {@link module:utils.escapeXML}.
  798. *
  799. * If `markup` is `undefined` or `null`, the empty string is returned.
  800. *
  801. * @param {String} markup Input string
  802. * @return {String} Escaped string
  803. * @public
  804. * @func
  805. * */
  806. exports.escapeXML = utils.escapeXML;
  807. /**
  808. * Express.js support.
  809. *
  810. * This is an alias for {@link module:ejs.renderFile}, in order to support
  811. * Express.js out-of-the-box.
  812. *
  813. * @func
  814. */
  815. exports.__express = exports.renderFile;
  816. // Add require support
  817. /* istanbul ignore else */
  818. if (require.extensions) {
  819. require.extensions['.ejs'] = function (module, flnm) {
  820. var filename = flnm || /* istanbul ignore next */ module.filename;
  821. var options = {
  822. filename: filename,
  823. client: true
  824. };
  825. var template = fileLoader(filename).toString();
  826. var fn = exports.compile(template, options);
  827. module._compile('module.exports = ' + fn.toString() + ';', filename);
  828. };
  829. }
  830. /**
  831. * Version of EJS.
  832. *
  833. * @readonly
  834. * @type {String}
  835. * @public
  836. */
  837. exports.VERSION = _VERSION_STRING;
  838. /**
  839. * Name for detection of EJS.
  840. *
  841. * @readonly
  842. * @type {String}
  843. * @public
  844. */
  845. exports.name = _NAME;
  846. /* istanbul ignore if */
  847. if (typeof window != 'undefined') {
  848. window.ejs = exports;
  849. }
  850. },{"../package.json":6,"./utils":2,"fs":3,"path":4}],2:[function(require,module,exports){
  851. /*
  852. * EJS Embedded JavaScript templates
  853. * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
  854. *
  855. * Licensed under the Apache License, Version 2.0 (the "License");
  856. * you may not use this file except in compliance with the License.
  857. * You may obtain a copy of the License at
  858. *
  859. * http://www.apache.org/licenses/LICENSE-2.0
  860. *
  861. * Unless required by applicable law or agreed to in writing, software
  862. * distributed under the License is distributed on an "AS IS" BASIS,
  863. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  864. * See the License for the specific language governing permissions and
  865. * limitations under the License.
  866. *
  867. */
  868. /**
  869. * Private utility functions
  870. * @module utils
  871. * @private
  872. */
  873. 'use strict';
  874. var regExpChars = /[|\\{}()[\]^$+*?.]/g;
  875. /**
  876. * Escape characters reserved in regular expressions.
  877. *
  878. * If `string` is `undefined` or `null`, the empty string is returned.
  879. *
  880. * @param {String} string Input string
  881. * @return {String} Escaped string
  882. * @static
  883. * @private
  884. */
  885. exports.escapeRegExpChars = function (string) {
  886. // istanbul ignore if
  887. if (!string) {
  888. return '';
  889. }
  890. return String(string).replace(regExpChars, '\\$&');
  891. };
  892. var _ENCODE_HTML_RULES = {
  893. '&': '&amp;',
  894. '<': '&lt;',
  895. '>': '&gt;',
  896. '"': '&#34;',
  897. "'": '&#39;'
  898. };
  899. var _MATCH_HTML = /[&<>'"]/g;
  900. function encode_char(c) {
  901. return _ENCODE_HTML_RULES[c] || c;
  902. }
  903. /**
  904. * Stringified version of constants used by {@link module:utils.escapeXML}.
  905. *
  906. * It is used in the process of generating {@link ClientFunction}s.
  907. *
  908. * @readonly
  909. * @type {String}
  910. */
  911. var escapeFuncStr =
  912. 'var _ENCODE_HTML_RULES = {\n'
  913. + ' "&": "&amp;"\n'
  914. + ' , "<": "&lt;"\n'
  915. + ' , ">": "&gt;"\n'
  916. + ' , \'"\': "&#34;"\n'
  917. + ' , "\'": "&#39;"\n'
  918. + ' }\n'
  919. + ' , _MATCH_HTML = /[&<>\'"]/g;\n'
  920. + 'function encode_char(c) {\n'
  921. + ' return _ENCODE_HTML_RULES[c] || c;\n'
  922. + '};\n';
  923. /**
  924. * Escape characters reserved in XML.
  925. *
  926. * If `markup` is `undefined` or `null`, the empty string is returned.
  927. *
  928. * @implements {EscapeCallback}
  929. * @param {String} markup Input string
  930. * @return {String} Escaped string
  931. * @static
  932. * @private
  933. */
  934. exports.escapeXML = function (markup) {
  935. return markup == undefined
  936. ? ''
  937. : String(markup)
  938. .replace(_MATCH_HTML, encode_char);
  939. };
  940. exports.escapeXML.toString = function () {
  941. return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
  942. };
  943. /**
  944. * Naive copy of properties from one object to another.
  945. * Does not recurse into non-scalar properties
  946. * Does not check to see if the property has a value before copying
  947. *
  948. * @param {Object} to Destination object
  949. * @param {Object} from Source object
  950. * @return {Object} Destination object
  951. * @static
  952. * @private
  953. */
  954. exports.shallowCopy = function (to, from) {
  955. from = from || {};
  956. for (var p in from) {
  957. to[p] = from[p];
  958. }
  959. return to;
  960. };
  961. /**
  962. * Naive copy of a list of key names, from one object to another.
  963. * Only copies property if it is actually defined
  964. * Does not recurse into non-scalar properties
  965. *
  966. * @param {Object} to Destination object
  967. * @param {Object} from Source object
  968. * @param {Array} list List of properties to copy
  969. * @return {Object} Destination object
  970. * @static
  971. * @private
  972. */
  973. exports.shallowCopyFromList = function (to, from, list) {
  974. for (var i = 0; i < list.length; i++) {
  975. var p = list[i];
  976. if (typeof from[p] != 'undefined') {
  977. to[p] = from[p];
  978. }
  979. }
  980. return to;
  981. };
  982. /**
  983. * Simple in-process cache implementation. Does not implement limits of any
  984. * sort.
  985. *
  986. * @implements Cache
  987. * @static
  988. * @private
  989. */
  990. exports.cache = {
  991. _data: {},
  992. set: function (key, val) {
  993. this._data[key] = val;
  994. },
  995. get: function (key) {
  996. return this._data[key];
  997. },
  998. reset: function () {
  999. this._data = {};
  1000. }
  1001. };
  1002. },{}],3:[function(require,module,exports){
  1003. },{}],4:[function(require,module,exports){
  1004. (function (process){
  1005. // Copyright Joyent, Inc. and other Node contributors.
  1006. //
  1007. // Permission is hereby granted, free of charge, to any person obtaining a
  1008. // copy of this software and associated documentation files (the
  1009. // "Software"), to deal in the Software without restriction, including
  1010. // without limitation the rights to use, copy, modify, merge, publish,
  1011. // distribute, sublicense, and/or sell copies of the Software, and to permit
  1012. // persons to whom the Software is furnished to do so, subject to the
  1013. // following conditions:
  1014. //
  1015. // The above copyright notice and this permission notice shall be included
  1016. // in all copies or substantial portions of the Software.
  1017. //
  1018. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  1019. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  1020. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  1021. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  1022. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  1023. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  1024. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  1025. // resolves . and .. elements in a path array with directory names there
  1026. // must be no slashes, empty elements, or device names (c:\) in the array
  1027. // (so also no leading and trailing slashes - it does not distinguish
  1028. // relative and absolute paths)
  1029. function normalizeArray(parts, allowAboveRoot) {
  1030. // if the path tries to go above the root, `up` ends up > 0
  1031. var up = 0;
  1032. for (var i = parts.length - 1; i >= 0; i--) {
  1033. var last = parts[i];
  1034. if (last === '.') {
  1035. parts.splice(i, 1);
  1036. } else if (last === '..') {
  1037. parts.splice(i, 1);
  1038. up++;
  1039. } else if (up) {
  1040. parts.splice(i, 1);
  1041. up--;
  1042. }
  1043. }
  1044. // if the path is allowed to go above the root, restore leading ..s
  1045. if (allowAboveRoot) {
  1046. for (; up--; up) {
  1047. parts.unshift('..');
  1048. }
  1049. }
  1050. return parts;
  1051. }
  1052. // Split a filename into [root, dir, basename, ext], unix version
  1053. // 'root' is just a slash, or nothing.
  1054. var splitPathRe =
  1055. /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
  1056. var splitPath = function(filename) {
  1057. return splitPathRe.exec(filename).slice(1);
  1058. };
  1059. // path.resolve([from ...], to)
  1060. // posix version
  1061. exports.resolve = function() {
  1062. var resolvedPath = '',
  1063. resolvedAbsolute = false;
  1064. for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
  1065. var path = (i >= 0) ? arguments[i] : process.cwd();
  1066. // Skip empty and invalid entries
  1067. if (typeof path !== 'string') {
  1068. throw new TypeError('Arguments to path.resolve must be strings');
  1069. } else if (!path) {
  1070. continue;
  1071. }
  1072. resolvedPath = path + '/' + resolvedPath;
  1073. resolvedAbsolute = path.charAt(0) === '/';
  1074. }
  1075. // At this point the path should be resolved to a full absolute path, but
  1076. // handle relative paths to be safe (might happen when process.cwd() fails)
  1077. // Normalize the path
  1078. resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
  1079. return !!p;
  1080. }), !resolvedAbsolute).join('/');
  1081. return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
  1082. };
  1083. // path.normalize(path)
  1084. // posix version
  1085. exports.normalize = function(path) {
  1086. var isAbsolute = exports.isAbsolute(path),
  1087. trailingSlash = substr(path, -1) === '/';
  1088. // Normalize the path
  1089. path = normalizeArray(filter(path.split('/'), function(p) {
  1090. return !!p;
  1091. }), !isAbsolute).join('/');
  1092. if (!path && !isAbsolute) {
  1093. path = '.';
  1094. }
  1095. if (path && trailingSlash) {
  1096. path += '/';
  1097. }
  1098. return (isAbsolute ? '/' : '') + path;
  1099. };
  1100. // posix version
  1101. exports.isAbsolute = function(path) {
  1102. return path.charAt(0) === '/';
  1103. };
  1104. // posix version
  1105. exports.join = function() {
  1106. var paths = Array.prototype.slice.call(arguments, 0);
  1107. return exports.normalize(filter(paths, function(p, index) {
  1108. if (typeof p !== 'string') {
  1109. throw new TypeError('Arguments to path.join must be strings');
  1110. }
  1111. return p;
  1112. }).join('/'));
  1113. };
  1114. // path.relative(from, to)
  1115. // posix version
  1116. exports.relative = function(from, to) {
  1117. from = exports.resolve(from).substr(1);
  1118. to = exports.resolve(to).substr(1);
  1119. function trim(arr) {
  1120. var start = 0;
  1121. for (; start < arr.length; start++) {
  1122. if (arr[start] !== '') break;
  1123. }
  1124. var end = arr.length - 1;
  1125. for (; end >= 0; end--) {
  1126. if (arr[end] !== '') break;
  1127. }
  1128. if (start > end) return [];
  1129. return arr.slice(start, end - start + 1);
  1130. }
  1131. var fromParts = trim(from.split('/'));
  1132. var toParts = trim(to.split('/'));
  1133. var length = Math.min(fromParts.length, toParts.length);
  1134. var samePartsLength = length;
  1135. for (var i = 0; i < length; i++) {
  1136. if (fromParts[i] !== toParts[i]) {
  1137. samePartsLength = i;
  1138. break;
  1139. }
  1140. }
  1141. var outputParts = [];
  1142. for (var i = samePartsLength; i < fromParts.length; i++) {
  1143. outputParts.push('..');
  1144. }
  1145. outputParts = outputParts.concat(toParts.slice(samePartsLength));
  1146. return outputParts.join('/');
  1147. };
  1148. exports.sep = '/';
  1149. exports.delimiter = ':';
  1150. exports.dirname = function(path) {
  1151. var result = splitPath(path),
  1152. root = result[0],
  1153. dir = result[1];
  1154. if (!root && !dir) {
  1155. // No dirname whatsoever
  1156. return '.';
  1157. }
  1158. if (dir) {
  1159. // It has a dirname, strip trailing slash
  1160. dir = dir.substr(0, dir.length - 1);
  1161. }
  1162. return root + dir;
  1163. };
  1164. exports.basename = function(path, ext) {
  1165. var f = splitPath(path)[2];
  1166. // TODO: make this comparison case-insensitive on windows?
  1167. if (ext && f.substr(-1 * ext.length) === ext) {
  1168. f = f.substr(0, f.length - ext.length);
  1169. }
  1170. return f;
  1171. };
  1172. exports.extname = function(path) {
  1173. return splitPath(path)[3];
  1174. };
  1175. function filter (xs, f) {
  1176. if (xs.filter) return xs.filter(f);
  1177. var res = [];
  1178. for (var i = 0; i < xs.length; i++) {
  1179. if (f(xs[i], i, xs)) res.push(xs[i]);
  1180. }
  1181. return res;
  1182. }
  1183. // String.prototype.substr - negative index don't work in IE8
  1184. var substr = 'ab'.substr(-1) === 'b'
  1185. ? function (str, start, len) { return str.substr(start, len) }
  1186. : function (str, start, len) {
  1187. if (start < 0) start = str.length + start;
  1188. return str.substr(start, len);
  1189. }
  1190. ;
  1191. }).call(this,require('_process'))
  1192. },{"_process":5}],5:[function(require,module,exports){
  1193. // shim for using process in browser
  1194. var process = module.exports = {};
  1195. // cached from whatever global is present so that test runners that stub it
  1196. // don't break things. But we need to wrap it in a try catch in case it is
  1197. // wrapped in strict mode code which doesn't define any globals. It's inside a
  1198. // function because try/catches deoptimize in certain engines.
  1199. var cachedSetTimeout;
  1200. var cachedClearTimeout;
  1201. function defaultSetTimout() {
  1202. throw new Error('setTimeout has not been defined');
  1203. }
  1204. function defaultClearTimeout () {
  1205. throw new Error('clearTimeout has not been defined');
  1206. }
  1207. (function () {
  1208. try {
  1209. if (typeof setTimeout === 'function') {
  1210. cachedSetTimeout = setTimeout;
  1211. } else {
  1212. cachedSetTimeout = defaultSetTimout;
  1213. }
  1214. } catch (e) {
  1215. cachedSetTimeout = defaultSetTimout;
  1216. }
  1217. try {
  1218. if (typeof clearTimeout === 'function') {
  1219. cachedClearTimeout = clearTimeout;
  1220. } else {
  1221. cachedClearTimeout = defaultClearTimeout;
  1222. }
  1223. } catch (e) {
  1224. cachedClearTimeout = defaultClearTimeout;
  1225. }
  1226. } ())
  1227. function runTimeout(fun) {
  1228. if (cachedSetTimeout === setTimeout) {
  1229. //normal enviroments in sane situations
  1230. return setTimeout(fun, 0);
  1231. }
  1232. // if setTimeout wasn't available but was latter defined
  1233. if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
  1234. cachedSetTimeout = setTimeout;
  1235. return setTimeout(fun, 0);
  1236. }
  1237. try {
  1238. // when when somebody has screwed with setTimeout but no I.E. maddness
  1239. return cachedSetTimeout(fun, 0);
  1240. } catch(e){
  1241. try {
  1242. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  1243. return cachedSetTimeout.call(null, fun, 0);
  1244. } catch(e){
  1245. // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
  1246. return cachedSetTimeout.call(this, fun, 0);
  1247. }
  1248. }
  1249. }
  1250. function runClearTimeout(marker) {
  1251. if (cachedClearTimeout === clearTimeout) {
  1252. //normal enviroments in sane situations
  1253. return clearTimeout(marker);
  1254. }
  1255. // if clearTimeout wasn't available but was latter defined
  1256. if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
  1257. cachedClearTimeout = clearTimeout;
  1258. return clearTimeout(marker);
  1259. }
  1260. try {
  1261. // when when somebody has screwed with setTimeout but no I.E. maddness
  1262. return cachedClearTimeout(marker);
  1263. } catch (e){
  1264. try {
  1265. // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
  1266. return cachedClearTimeout.call(null, marker);
  1267. } catch (e){
  1268. // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
  1269. // Some versions of I.E. have different rules for clearTimeout vs setTimeout
  1270. return cachedClearTimeout.call(this, marker);
  1271. }
  1272. }
  1273. }
  1274. var queue = [];
  1275. var draining = false;
  1276. var currentQueue;
  1277. var queueIndex = -1;
  1278. function cleanUpNextTick() {
  1279. if (!draining || !currentQueue) {
  1280. return;
  1281. }
  1282. draining = false;
  1283. if (currentQueue.length) {
  1284. queue = currentQueue.concat(queue);
  1285. } else {
  1286. queueIndex = -1;
  1287. }
  1288. if (queue.length) {
  1289. drainQueue();
  1290. }
  1291. }
  1292. function drainQueue() {
  1293. if (draining) {
  1294. return;
  1295. }
  1296. var timeout = runTimeout(cleanUpNextTick);
  1297. draining = true;
  1298. var len = queue.length;
  1299. while(len) {
  1300. currentQueue = queue;
  1301. queue = [];
  1302. while (++queueIndex < len) {
  1303. if (currentQueue) {
  1304. currentQueue[queueIndex].run();
  1305. }
  1306. }
  1307. queueIndex = -1;
  1308. len = queue.length;
  1309. }
  1310. currentQueue = null;
  1311. draining = false;
  1312. runClearTimeout(timeout);
  1313. }
  1314. process.nextTick = function (fun) {
  1315. var args = new Array(arguments.length - 1);
  1316. if (arguments.length > 1) {
  1317. for (var i = 1; i < arguments.length; i++) {
  1318. args[i - 1] = arguments[i];
  1319. }
  1320. }
  1321. queue.push(new Item(fun, args));
  1322. if (queue.length === 1 && !draining) {
  1323. runTimeout(drainQueue);
  1324. }
  1325. };
  1326. // v8 likes predictible objects
  1327. function Item(fun, array) {
  1328. this.fun = fun;
  1329. this.array = array;
  1330. }
  1331. Item.prototype.run = function () {
  1332. this.fun.apply(null, this.array);
  1333. };
  1334. process.title = 'browser';
  1335. process.browser = true;
  1336. process.env = {};
  1337. process.argv = [];
  1338. process.version = ''; // empty string to avoid regexp issues
  1339. process.versions = {};
  1340. function noop() {}
  1341. process.on = noop;
  1342. process.addListener = noop;
  1343. process.once = noop;
  1344. process.off = noop;
  1345. process.removeListener = noop;
  1346. process.removeAllListeners = noop;
  1347. process.emit = noop;
  1348. process.prependListener = noop;
  1349. process.prependOnceListener = noop;
  1350. process.listeners = function (name) { return [] }
  1351. process.binding = function (name) {
  1352. throw new Error('process.binding is not supported');
  1353. };
  1354. process.cwd = function () { return '/' };
  1355. process.chdir = function (dir) {
  1356. throw new Error('process.chdir is not supported');
  1357. };
  1358. process.umask = function() { return 0; };
  1359. },{}],6:[function(require,module,exports){
  1360. module.exports={
  1361. "name": "ejs",
  1362. "description": "Embedded JavaScript templates",
  1363. "keywords": [
  1364. "template",
  1365. "engine",
  1366. "ejs"
  1367. ],
  1368. "version": "2.6.0",
  1369. "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",
  1370. "contributors": [
  1371. "Timothy Gu <timothygu99@gmail.com> (https://timothygu.github.io)"
  1372. ],
  1373. "license": "Apache-2.0",
  1374. "main": "./lib/ejs.js",
  1375. "repository": {
  1376. "type": "git",
  1377. "url": "git://github.com/mde/ejs.git"
  1378. },
  1379. "bugs": "https://github.com/mde/ejs/issues",
  1380. "homepage": "https://github.com/mde/ejs",
  1381. "dependencies": {},
  1382. "devDependencies": {
  1383. "browserify": "^13.1.1",
  1384. "eslint": "^4.14.0",
  1385. "git-directory-deploy": "^1.5.1",
  1386. "istanbul": "~0.4.3",
  1387. "jake": "^8.0.16",
  1388. "jsdoc": "^3.4.0",
  1389. "lru-cache": "^4.0.1",
  1390. "mocha": "^5.0.5",
  1391. "uglify-js": "^3.3.16"
  1392. },
  1393. "engines": {
  1394. "node": ">=0.10.0"
  1395. },
  1396. "scripts": {
  1397. "test": "jake test",
  1398. "lint": "eslint \"**/*.js\" Jakefile",
  1399. "coverage": "istanbul cover node_modules/mocha/bin/_mocha",
  1400. "doc": "jake doc",
  1401. "devdoc": "jake doc[dev]"
  1402. }
  1403. }
  1404. },{}]},{},[1])(1)
  1405. });