| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 | define(['./defaults', './underscore', './templateSettings'], function (defaults, underscore, templateSettings) {  // When customizing `_.templateSettings`, if you don't want to define an  // interpolation, evaluation or escaping regex, we need one that is  // guaranteed not to match.  var noMatch = /(.)^/;  // Certain characters need to be escaped so that they can be put into a  // string literal.  var escapes = {    "'": "'",    '\\': '\\',    '\r': 'r',    '\n': 'n',    '\u2028': 'u2028',    '\u2029': 'u2029'  };  var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;  function escapeChar(match) {    return '\\' + escapes[match];  }  // In order to prevent third-party code injection through  // `_.templateSettings.variable`, we test it against the following regular  // expression. It is intentionally a bit more liberal than just matching valid  // identifiers, but still prevents possible loopholes through defaults or  // destructuring assignment.  var bareIdentifier = /^\s*(\w|\$)+\s*$/;  // JavaScript micro-templating, similar to John Resig's implementation.  // Underscore templating handles arbitrary delimiters, preserves whitespace,  // and correctly escapes quotes within interpolated code.  // NB: `oldSettings` only exists for backwards compatibility.  function template(text, settings, oldSettings) {    if (!settings && oldSettings) settings = oldSettings;    settings = defaults({}, settings, underscore.templateSettings);    // Combine delimiters into one regular expression via alternation.    var matcher = RegExp([      (settings.escape || noMatch).source,      (settings.interpolate || noMatch).source,      (settings.evaluate || noMatch).source    ].join('|') + '|$', 'g');    // Compile the template source, escaping string literals appropriately.    var index = 0;    var source = "__p+='";    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);      index = offset + match.length;      if (escape) {        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";      } else if (interpolate) {        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";      } else if (evaluate) {        source += "';\n" + evaluate + "\n__p+='";      }      // Adobe VMs need the match returned to produce the correct offset.      return match;    });    source += "';\n";    var argument = settings.variable;    if (argument) {      // Insure against third-party code injection. (CVE-2021-23358)      if (!bareIdentifier.test(argument)) throw new Error(        'variable is not a bare identifier: ' + argument      );    } else {      // If a variable is not specified, place data values in local scope.      source = 'with(obj||{}){\n' + source + '}\n';      argument = 'obj';    }    source = "var __t,__p='',__j=Array.prototype.join," +      "print=function(){__p+=__j.call(arguments,'');};\n" +      source + 'return __p;\n';    var render;    try {      render = new Function(argument, '_', source);    } catch (e) {      e.source = source;      throw e;    }    var template = function(data) {      return render.call(this, data, underscore);    };    // Provide the compiled source as a convenience for precompilation.    template.source = 'function(' + argument + '){\n' + source + '}';    return template;  }  return template;});
 |