Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*!
- * Lo-Dash v0.5.0-rc.1 <http://lodash.com>
- * Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
- * Based on Underscore.js 1.3.3, copyright 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
- * <http://documentcloud.github.com/underscore>
- * Available under MIT license <http://lodash.com/license>
- */
- ;(function(window, undefined) {
- 'use strict';
- /**
- * Used to cache the last `_.templateSettings.evaluate` delimiter to avoid
- * unnecessarily assigning `reEvaluateDelimiter` a new generated regexp.
- * Assigned in `_.template`.
- */
- var lastEvaluateDelimiter;
- /**
- * Used to cache the last template `options.variable` to avoid unnecessarily
- * assigning `reDoubleVariable` a new generated regexp. Assigned in `_.template`.
- */
- var lastVariable;
- /**
- * Used to match potentially incorrect data object references, like `obj.obj`,
- * in compiled templates. Assigned in `_.template`.
- */
- var reDoubleVariable;
- /**
- * Used to match "evaluate" delimiters, including internal delimiters,
- * in template text. Assigned in `_.template`.
- */
- var reEvaluateDelimiter;
- /** Detect free variable `exports` */
- var freeExports = typeof exports == 'object' && exports &&
- (typeof global == 'object' && global && global == global.global && (window = global), exports);
- /** Native prototype shortcuts */
- var ArrayProto = Array.prototype,
- BoolProto = Boolean.prototype,
- ObjectProto = Object.prototype,
- NumberProto = Number.prototype,
- StringProto = String.prototype;
- /** Used to generate unique IDs */
- var idCounter = 0;
- /** Used to restore the original `_` reference in `noConflict` */
- var oldDash = window._;
- /** Used to detect delimiter values that should be processed by `tokenizeEvaluate` */
- var reComplexDelimiter = /[-+=!~*%&^<>|{(\/]|\[\D|\b(?:delete|in|instanceof|new|typeof|void)\b/;
- /** Used to match empty string literals in compiled template source */
- var reEmptyStringLeading = /\b__p \+= '';/g,
- reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
- reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
- /** Used to match regexp flags from their coerced string values */
- var reFlags = /\w*$/;
- /** Used to insert the data object variable into compiled template source */
- var reInsertVariable = /(?:__e|__t = )\(\s*(?![\d\s"']|this\.)/g;
- /** Used to match tokens in template text */
- var reToken = /__token__(\d+)/g;
- /** Used to match unescaped characters in strings for inclusion in HTML */
- var reUnescapedHtml = /[&<"']/g;
- /** Used to match unescaped characters in compiled string literals */
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
- /** Used to fix the JScript [[DontEnum]] bug */
- var shadowed = [
- 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
- 'toLocaleString', 'toString', 'valueOf'
- ];
- /** Used to make template sourceURLs easier to identify */
- var templateCounter = 0;
- /** Used to replace template delimiters */
- var token = '__token__';
- /** Used to store tokenized template text snippets */
- var tokenized = [];
- /** Native method shortcuts */
- var concat = ArrayProto.concat,
- hasOwnProperty = ObjectProto.hasOwnProperty,
- push = ArrayProto.push,
- propertyIsEnumerable = ObjectProto.propertyIsEnumerable,
- slice = ArrayProto.slice,
- toString = ObjectProto.toString;
- /* Native method shortcuts for methods with the same name as other `lodash` methods */
- var nativeIsFinite = window.isFinite;
- /** `Object#toString` result shortcuts */
- var argsClass = '[object Arguments]',
- arrayClass = '[object Array]',
- boolClass = '[object Boolean]',
- dateClass = '[object Date]',
- funcClass = '[object Function]',
- numberClass = '[object Number]',
- objectClass = '[object Object]',
- regexpClass = '[object RegExp]',
- stringClass = '[object String]';
- /** Timer shortcuts */
- var clearTimeout = window.clearTimeout,
- setTimeout = window.setTimeout;
- /** Detect if an `arguments` object's indexes are non-enumerable (IE < 9) */
- /**
- * Detect lack of support for accessing string characters by index:
- * IE < 8 can't access characters by index and IE 8 can only access
- * characters by index on string literals.
- */
- var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx';
- /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */
- var isKeysFast = nativeKeys && /^.+$|true/.test(nativeKeys + !!window.attachEvent);
- /** Detect if sourceURL syntax is usable without erroring */
- try {
- // The JS engine in Adobe products, like InDesign, will throw a syntax error
- // when it encounters a single line comment beginning with the `@` symbol.
- // The JS engine in Narwhal will generate the function `function anonymous(){//}`
- // and throw a syntax error. In IE, `@` symbols are part of its non-standard
- // conditional compilation support. The `@cc_on` statement activates its support
- // while the trailing ` !` induces a syntax error to exlude it. Compatibility
- // modes in IE > 8 require a space before the `!` to induce a syntax error.
- // See http://msdn.microsoft.com/en-us/library/121hztk3(v=vs.94).aspx
- var useSourceURL = (Function('//@cc_on !')(), true);
- } catch(e){ }
- /** Used to identify object classifications that are array-like */
- var arrayLikeClasses = {};
- arrayLikeClasses[boolClass] = arrayLikeClasses[dateClass] = arrayLikeClasses[funcClass] =
- arrayLikeClasses[numberClass] = arrayLikeClasses[objectClass] = arrayLikeClasses[regexpClass] = false;
- arrayLikeClasses[argsClass] = arrayLikeClasses[arrayClass] = arrayLikeClasses[stringClass] = true;
- /** Used to identify object classifications that `_.clone` supports */
- var cloneableClasses = {};
- cloneableClasses[argsClass] = cloneableClasses[funcClass] = false;
- cloneableClasses[arrayClass] = cloneableClasses[boolClass] = cloneableClasses[dateClass] =
- cloneableClasses[numberClass] = cloneableClasses[objectClass] = cloneableClasses[regexpClass] =
- cloneableClasses[stringClass] = true;
- /**
- * Used to escape characters for inclusion in HTML.
- * The `>` and `/` characters don't require escaping in HTML and have no
- * special meaning unless they're part of a tag or an unquoted attribute value
- * http://mathiasbynens.be/notes/ambiguous-ampersands (semi-related fun fact)
- */
- var htmlEscapes = {
- '&': '&',
- '<': '<',
- '"': '"',
- "'": '''
- };
- /** Used to determine if values are of the language type Object */
- var objectTypes = {
- 'boolean': false,
- 'function': true,
- 'object': true,
- 'number': false,
- 'string': false,
- 'undefined': false,
- 'unknown': true
- };
- /** Used to escape characters for inclusion in compiled string literals */
- var stringEscapes = {
- '\\': '\\',
- "'": "'",
- '\n': 'n',
- '\r': 'r',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
- /*--------------------------------------------------------------------------*/
- /**
- * The `lodash` function.
- *
- * @name _
- * @constructor
- * @param {Mixed} value The value to wrap in a `LoDash` instance.
- * @returns {Object} Returns a `LoDash` instance.
- */
- function lodash(value) {
- // allow invoking `lodash` without the `new` operator
- return
- }
- /**
- * By default, the template delimiters used by Lo-Dash are similar to those in
- * embedded Ruby (ERB). Change the following template settings to use alternative
- * delimiters.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- lodash.templateSettings = {
- /**
- * Used to detect `data` property values to be HTML-escaped.
- *
- * @static
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'escape': /<%-([\s\S]+?)%>/g,
- /**
- * Used to detect code to be evaluated.
- *
- * @static
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'evaluate': /<%([\s\S]+?)%>/g,
- /**
- * Used to detect `data` property values to inject.
- *
- * @static
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'interpolate': /<%=([\s\S]+?)%>/g,
- /**
- * Used to reference the data object in the template text.
- *
- * @static
- * @memberOf _.templateSettings
- * @type String
- */
- 'variable': 'obj'
- };
- /*--------------------------------------------------------------------------*/
- /**
- * The template used to create iterator functions.
- *
- * @private
- * @param {Obect} data The data object used to populate the text.
- * @returns {String} Returns the interpolated text.
- */
- var iteratorTemplate = function(obj) {
- var __p = '';
- if (obj.useStrict) {
- __p += '\'use strict\';\n';
- } ;
- __p += 'var index, value, iteratee = ' +
- obj.firstArg +
- ', result';
- if (obj.init) {
- __p += ' = ' +
- obj.init ;
- } ;
- __p += ';\n' +
- obj.exit +
- ';\n' +
- obj.top +
- ';\n';
- if (obj.arrayBranch) {
- __p += 'var length = iteratee.length; index = -1; ';
- if (obj.objectBranch) {
- __p += '\nif (length === length >>> 0) {';
- } ;
- if (obj.noCharByIndex) {
- __p += '\n if (toString.call(iteratee) == stringClass) {\n iteratee = iteratee.split(\'\')\n } ';
- } ;
- __p +=
- obj.arrayBranch.beforeLoop +
- ';\n while (++index < length) {\n value = iteratee[index];\n ' +
- obj.arrayBranch.inLoop +
- '\n } ';
- if (obj.objectBranch) {
- __p += '\n}';
- } ;
- } ;
- if (obj.objectBranch) {
- if (obj.arrayBranch) {
- __p += '\nelse { ';
- } else if (obj.noArgsEnum) {
- __p += '\n var length = iteratee.length; index = -1;\n if (length && isArguments(iteratee)) {\n while (++index < length) {\n value = iteratee[index += \'\'];\n ' +
- obj.objectBranch.inLoop +
- '\n }\n } else { ';
- } ;
- if (!obj.hasDontEnumBug) {
- __p += '\n var skipProto = typeof iteratee == \'function\' && \n propertyIsEnumerable.call(iteratee, \'prototype\');\n ';
- } ;
- if (obj.isKeysFast && obj.useHas) {
- __p += '\n var ownIndex = -1,\n ownProps = nativeKeys(iteratee),\n length = ownProps.length;\n\n ' +
- obj.objectBranch.beforeLoop +
- ';\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n if (!(skipProto && index == \'prototype\')) {\n value = iteratee[index];\n ' +
- obj.objectBranch.inLoop +
- '\n }\n } ';
- } else {
- __p +=
- obj.objectBranch.beforeLoop +
- ';\n for (index in iteratee) { ';
- if (obj.hasDontEnumBug) {
- if (obj.useHas) {
- __p += 'if (hasOwnProperty.call(iteratee, index)) {\n ';
- } ;
- __p += ' value = iteratee[index];\n ' +
- obj.objectBranch.inLoop +
- ';\n ';
- if (obj.useHas) {
- __p += '}';
- } ;
- } else {
- __p += '\n if (!(skipProto && index == \'prototype\')';
- if (obj.useHas) {
- __p += ' &&\n hasOwnProperty.call(iteratee, index)';
- } ;
- __p += ') {\n value = iteratee[index];\n ' +
- obj.objectBranch.inLoop +
- '\n } ';
- } ;
- __p += '\n } ';
- } ;
- if (obj.hasDontEnumBug) {
- __p += '\n\n var ctor = iteratee.constructor;\n ';
- for (var k = 0; k < 7; k++) {
- __p += '\n index = \'' +
- obj.shadowed[k] +
- '\';\n if (';
- if (obj.shadowed[k] == 'constructor') {
- __p += '!(ctor && ctor.prototype === iteratee) && ';
- } ;
- __p += 'hasOwnProperty.call(iteratee, index)) {\n value = iteratee[index];\n ' +
- obj.objectBranch.inLoop +
- '\n } ';
- } ;
- } ;
- if (obj.arrayBranch || obj.noArgsEnum) {
- __p += '\n}';
- } ;
- } ;
- __p +=
- obj.bottom +
- ';\nreturn result';
- return __p
- };
- /**
- * Reusable iterator options shared by
- * `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `groupBy`, `map`,
- * `reject`, `some`, and `sortBy`.
- */
- var baseIteratorOptions = {
- 'args': 'collection, callback, thisArg',
- 'init': 'collection',
- 'top':
- 'if (!callback) {\n' +
- ' callback = identity\n' +
- '}\n' +
- 'else if (thisArg) callback = iteratorBind(callback, thisArg)',
- 'inLoop': 'if (callback(value, index, collection) === false) return result'
- };
- /** Reusable iterator options for `countBy`, `groupBy`, and `sortBy` */
- var countByIteratorOptions = {
- 'init': '{}',
- 'top':
- 'var prop;\n' +
- 'if (typeof callback != \'function\') {\n' +
- ' var valueProp = callback;\n' +
- ' callback = function(value) { return value[valueProp] }\n' +
- '}\n' +
- 'else if (thisArg) callback = iteratorBind(callback, thisArg)',
- 'inLoop':
- 'prop = callback(value, index, collection);\n' +
- '(hasOwnProperty.call(result, prop) ? result[prop]++ : result[prop] = 1)'
- };
- /** Reusable iterator options for `every` and `some` */
- var everyIteratorOptions = {
- 'init': 'true',
- 'inLoop': 'if (!callback(value, index, collection)) return !result'
- };
- /** Reusable iterator options for `defaults` and `extend` */
- var extendIteratorOptions = {
- 'useHas': false,
- 'useStrict': false,
- 'args': 'object',
- 'init': 'object',
- 'top':
- 'for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {\n' +
- ' if (iteratee = arguments[argsIndex]) {',
- 'inLoop': 'result[index] = value',
- 'bottom': ' }\n}'
- };
- /** Reusable iterator options for `filter`, `reject`, and `where` */
- var filterIteratorOptions = {
- 'init': '[]',
- 'inLoop': 'callback(value, index, collection) && result.push(value)'
- };
- /** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
- var forEachIteratorOptions = {
- 'top': 'if (thisArg) callback = iteratorBind(callback, thisArg)'
- };
- /** Reusable iterator options for `forIn` and `forOwn` */
- var forOwnIteratorOptions = {
- 'inLoop': {
- 'object': baseIteratorOptions.inLoop
- }
- };
- /** Reusable iterator options for `invoke`, `map`, `pluck`, and `sortBy` */
- var mapIteratorOptions = {
- 'init': '',
- 'exit': 'if (!collection) return []',
- 'beforeLoop': {
- 'array': 'result = Array(length)',
- 'object': 'result = ' + (isKeysFast ? 'Array(length)' : '[]')
- },
- 'inLoop': {
- 'array': 'result[index] = callback(value, index, collection)',
- 'object': 'result' + (isKeysFast ? '[ownIndex] = ' : '.push') + '(callback(value, index, collection))'
- }
- };
- /*--------------------------------------------------------------------------*/
- /**
- * Creates a new function optimized for searching large arrays for a given `value`,
- * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {Mixed} value The value to search for.
- * @param {Number} [fromIndex=0] The index to start searching from.
- * @param {Number} [largeSize=30] The length at which an array is considered large.
- * @returns {Boolean} Returns `true` if `value` is found, else `false`.
- */
- function cachedContains(array, fromIndex, largeSize) {
- fromIndex || (fromIndex = 0);
- var length = array.length,
- isLarge = (length - fromIndex) >= (largeSize || 30),
- cache = isLarge ? {} : array;
- if (isLarge) {
- // init value cache
- var key,
- index = fromIndex - 1;
- while (++index < length) {
- // manually coerce `value` to string because `hasOwnProperty`, in some
- // older versions of Firefox, coerces objects incorrectly
- key = array[index] + '';
- (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]);
- }
- }
- return function(value) {
- if (isLarge) {
- var key = value + '';
- return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1;
- }
- return indexOf(cache, value, fromIndex) > -1;
- }
- }
- /**
- * Used by `sortBy` to compare transformed values of `collection`, sorting
- * them in ascending order.
- *
- * @private
- * @param {Object} a The object to compare to `b`.
- * @param {Object} b The object to compare to `a`.
- * @returns {Number} Returns `-1` if `a` < `b`, `0` if `a` == `b`, or `1` if `a` > `b`.
- */
- function compareAscending(a, b) {
- a = a.criteria;
- b = b.criteria;
- if (a === undefined) {
- return 1;
- }
- if (b === undefined) {
- return -1;
- }
- return a < b ? -1 : a > b ? 1 : 0;
- }
- /**
- * Used by `template` to replace tokens with their corresponding code snippets.
- *
- * @private
- * @param {String} match The matched token.
- * @param {String} index The `tokenized` index of the code snippet.
- * @returns {String} Returns the code snippet.
- */
- function detokenize(match, index) {
- return tokenized[index];
- }
- /**
- * Used by `template` to escape characters for inclusion in compiled
- * string literals.
- *
- * @private
- * @param {String} match The matched character to escape.
- * @returns {String} Returns the escaped character.
- */
- function escapeStringChar(match) {
- return '\\' + stringEscapes[match];
- }
- /**
- * Used by `escape` to escape characters for inclusion in HTML.
- *
- * @private
- * @param {String} match The matched character to escape.
- * @returns {String} Returns the escaped character.
- */
- function escapeHtmlChar(match) {
- return htmlEscapes[match];
- }
- /**
- * Creates a new function that, when called, invokes `func` with the `this`
- * binding of `thisArg` and the arguments (value, index, object).
- *
- * @private
- * @param {Function} func The function to bind.
- * @param {Mixed} [thisArg] The `this` binding of `func`.
- * @returns {Function} Returns the new bound function.
- */
- function iteratorBind(func, thisArg) {
- return function(value, index, object) {
- return func.call(thisArg, value, index, object);
- };
- }
- /**
- * A no-operation function.
- *
- * @private
- */
- function noop() {
- // no operation performed
- }
- /**
- * Used by `template` to replace "escape" template delimiters with tokens.
- *
- * @private
- * @param {String} match The matched template delimiter.
- * @param {String} value The delimiter value.
- * @returns {String} Returns a token.
- */
- function tokenizeEscape(match, value) {
- if (reComplexDelimiter.test(value)) {
- return '<e%-' + value + '%>';
- }
- var index = tokenized.length;
- tokenized[index] = "' +\n__e(" + value + ") +\n'";
- return token + index;
- }
- /**
- * Used by `template` to replace "evaluate" template delimiters, or complex
- * "escape" and "interpolate" delimiters, with tokens.
- *
- * @private
- * @param {String} match The matched template delimiter.
- * @param {String} escapeValue The complex "escape" delimiter value.
- * @param {String} interpolateValue The complex "interpolate" delimiter value.
- * @param {String} [evaluateValue] The "evaluate" delimiter value.
- * @returns {String} Returns a token.
- */
- function tokenizeEvaluate(match, escapeValue, interpolateValue, evaluateValue) {
- var index = tokenized.length;
- if (escapeValue) {
- tokenized[index] = "' +\n__e(" + escapeValue + ") +\n'";
- } else if (evaluateValue) {
- tokenized[index] = "';\n" + evaluateValue + ";\n__p += '";
- } else if (interpolateValue) {
- tokenized[index] = "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
- }
- return token + index;
- }
- /**
- * Used by `template` to replace "interpolate" template delimiters with tokens.
- *
- * @private
- * @param {String} match The matched template delimiter.
- * @param {String} value The delimiter value.
- * @returns {String} Returns a token.
- */
- function tokenizeInterpolate(match, value) {
- if (reComplexDelimiter.test(value)) {
- return '<e%=' + value + '%>';
- }
- var index = tokenized.length;
- tokenized[index] = "' +\n((__t = (" + value + ")) == null ? '' : __t) +\n'";
- return token + index;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Escapes a string for inclusion in HTML, replacing `&`, `<`, `"`, and `'`
- * characters.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {String} string The string to escape.
- * @returns {String} Returns the escaped string.
- * @example
- *
- * _.escape('Moe, Larry & Curly');
- * // => "Moe, Larry & Curly"
- */
- function escape(string) {
- return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar);
- }
- /**
- * A micro-templating method that handles arbitrary delimiters, preserves
- * whitespace, and correctly escapes quotes within interpolated code.
- *
- * Note: For Chrome extensions use the `lodash csp` build and see
- * http://code.google.com/chrome/extensions/trunk/sandboxingEval.html
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {String} text The template text.
- * @param {Obect} data The data object used to populate the text.
- * @param {Object} options The options object.
- * @returns {Function|String} Returns a compiled function when no `data` object
- * is given, else it returns the interpolated text.
- * @example
- *
- * // using compiled template
- * var compiled = _.template('hello: <%= name %>');
- * compiled({ 'name': 'moe' });
- * // => 'hello: moe'
- *
- * var list = '<% _.forEach(people, function(name) { %> <li><%= name %></li> <% }); %>';
- * _.template(list, { 'people': ['moe', 'larry', 'curly'] });
- * // => '<li>moe</li><li>larry</li><li>curly</li>'
- *
- * var template = _.template('<b><%- value %></b>');
- * template({ 'value': '<script>' });
- * // => '<b><script></b>'
- *
- * // using `print`
- * var compiled = _.template('<% print("Hello " + epithet); %>');
- * compiled({ 'epithet': 'stooge' });
- * // => 'Hello stooge.'
- *
- * // using custom template settings
- * _.templateSettings = {
- * 'interpolate': /\{\{(.+?)\}\}/g
- * };
- *
- * var template = _.template('Hello {{ name }}!');
- * template({ 'name': 'Mustache' });
- * // => 'Hello Mustache!'
- *
- * // using the `variable` option
- * _.template('<%= data.hasWith %>', { 'hasWith': 'no' }, { 'variable': 'data' });
- * // => 'no'
- *
- * // using the `source` property
- * <script>
- * JST.project = <%= _.template(jstText).source %>;
- * </script>
- */
- function template(text, data, options) {
- // based on John Resig's `tmpl` implementation
- // http://ejohn.org/blog/javascript-micro-templating/
- // and Laura Doktorova's doT.js
- // https://github.com/olado/doT
- options || (options = {});
- var isEvaluating,
- result,
- escapeDelimiter = options.escape,
- evaluateDelimiter = options.evaluate,
- interpolateDelimiter = options.interpolate,
- settings = lodash.templateSettings,
- variable = options.variable;
- // use default settings if no options object is provided
- if (escapeDelimiter == null) {
- escapeDelimiter = settings.escape;
- }
- if (evaluateDelimiter == null) {
- // use `false` as the fallback value, instead of leaving it `undefined`,
- // so the initial assignment of `reEvaluateDelimiter` will still occur
- evaluateDelimiter = settings.evaluate || false;
- }
- if (interpolateDelimiter == null) {
- interpolateDelimiter = settings.interpolate;
- }
- // tokenize delimiters to avoid escaping them
- if (escapeDelimiter) {
- text = text.replace(escapeDelimiter, tokenizeEscape);
- }
- if (interpolateDelimiter) {
- text = text.replace(interpolateDelimiter, tokenizeInterpolate);
- }
- if (evaluateDelimiter != lastEvaluateDelimiter) {
- // generate `reEvaluateDelimiter` to match `_.templateSettings.evaluate`
- // and internal `<e%- %>`, `<e%= %>` delimiters
- lastEvaluateDelimiter = evaluateDelimiter;
- reEvaluateDelimiter = RegExp(
- '<e%-([\\s\\S]+?)%>|<e%=([\\s\\S]+?)%>' +
- (evaluateDelimiter ? '|' + evaluateDelimiter.source : '')
- , 'g');
- }
- isEvaluating = tokenized.length;
- text = text.replace(reEvaluateDelimiter, tokenizeEvaluate);
- isEvaluating = isEvaluating != tokenized.length;
- // escape characters that cannot be included in string literals and
- // detokenize delimiter code snippets
- text = "__p += '" + text
- .replace(reUnescapedString, escapeStringChar)
- .replace(reToken, detokenize) + "';\n";
- // clear stored code snippets
- tokenized.length = 0;
- // if `options.variable` is not specified and the template contains "evaluate"
- // delimiters, wrap a with-statement around the generated code to add the
- // data object to the top of the scope chain
- if (!variable) {
- variable = settings.variable || lastVariable || 'obj';
- if (isEvaluating) {
- text = 'with (' + variable + ') {\n' + text + '\n}\n';
- }
- else {
- if (variable != lastVariable) {
- // generate `reDoubleVariable` to match references like `obj.obj` inside
- // transformed "escape" and "interpolate" delimiters
- lastVariable = variable;
- reDoubleVariable = RegExp('(\\(\\s*)' + variable + '\\.' + variable + '\\b', 'g');
- }
- // avoid a with-statement by prepending data object references to property names
- text = text
- .replace(reInsertVariable, '$&' + variable + '.')
- .replace(reDoubleVariable, '$1__d');
- }
- }
- // cleanup code by stripping empty strings
- text = ( isEvaluating ? text.replace(reEmptyStringLeading, '') : text)
- .replace(reEmptyStringMiddle, '$1')
- .replace(reEmptyStringTrailing, '$1;');
- // frame code as the function body
- text = 'function(' + variable + ') {\n' +
- variable + ' || (' + variable + ' = {});\n' +
- 'var __t, __p = \'\', __e = _.escape' +
- (isEvaluating
- ? ', __j = Array.prototype.join;\n' +
- 'function print() { __p += __j.call(arguments, \'\') }\n'
- : ', __d = ' + variable + '.' + variable + ' || ' + variable + ';\n'
- ) +
- text +
- 'return __p\n}';
- // add a sourceURL for easier debugging
- // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- if (useSourceURL) {
- text += '\n//@ sourceURL=/lodash/template/source[' + (templateCounter++) + ']';
- }
- try {
- result = Function('_', 'return ' + text)(lodash);
- } catch(e) {
- // defer syntax errors until the compiled template is executed to allow
- // examining the `source` property beforehand and for consistency,
- // because other template related errors occur at execution
- result = function() { throw e; };
- }
- if (data) {
- return result(data);
- }
- // provide the compiled function's source via its `toString` method, in
- // supported environments, or the `source` property as a convenience for
- // build time precompilation
- result.source = text;
- return result;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * Enables method chaining on the wrapper object.
- *
- * @name chain
- * @deprecated
- * @memberOf _
- * @category Chaining
- * @returns {Mixed} Returns the wrapper object.
- * @example
- *
- * _([1, 2, 3]).value();
- * // => [1, 2, 3]
- */
- function wrapperChain() {
- this._chain = true;
- return this;
- }
- /**
- * Extracts the wrapped value.
- *
- * @name value
- * @memberOf _
- * @category Chaining
- * @returns {Mixed} Returns the wrapped value.
- * @example
- *
- * _([1, 2, 3]).value();
- * // => [1, 2, 3]
- */
- function wrapperValue() {
- return this._wrapped;
- }
- /*--------------------------------------------------------------------------*/
- /**
- * The semantic version number.
- *
- * @static
- * @memberOf _
- * @type String
- */
- lodash.VERSION = '0.5.0-rc.1';
- lodash.escape = escape;
- lodash.template = template;
- /*--------------------------------------------------------------------------*/
- // expose Lo-Dash
- // some AMD build optimizers, like r.js, check for specific condition patterns like the following:
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
- // Expose Lo-Dash to the global object even when an AMD loader is present in
- // case Lo-Dash was injected by a third-party script and not intended to be
- // loaded as a module. The global assignment can be reverted in the Lo-Dash
- // module via its `noConflict()` method.
- window._ = lodash;
- // define as an anonymous module so, through path mapping, it can be
- // referenced as the "underscore" module
- define(function() {
- return lodash;
- });
- }
- // check for `exports` after `define` in case a build optimizer adds an `exports` object
- else if (freeExports) {
- // in Node.js or RingoJS v0.8.0+
- if (typeof module == 'object' && module && module.exports == freeExports) {
- (module.exports = lodash)._ = lodash;
- }
- // in Narwhal or RingoJS v0.7.0-
- else {
- freeExports._ = lodash;
- }
- }
- else {
- // in a browser or Rhino
- window._ = lodash;
- }
- }(this));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement