index.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /**
  2. * lodash 4.2.4 (Custom Build) <https://lodash.com/>
  3. * Build: `lodash modularize exports="npm" -o ./`
  4. * Copyright jQuery Foundation and other contributors <https://jquery.org/>
  5. * Released under MIT license <https://lodash.com/license>
  6. * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  7. * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  8. */
  9. var assignInWith = require('lodash.assigninwith'),
  10. keys = require('lodash.keys'),
  11. reInterpolate = require('lodash._reinterpolate'),
  12. rest = require('lodash.rest'),
  13. templateSettings = require('lodash.templatesettings'),
  14. toString = require('lodash.tostring');
  15. /** Used as references for various `Number` constants. */
  16. var MAX_SAFE_INTEGER = 9007199254740991;
  17. /** `Object#toString` result references. */
  18. var errorTag = '[object Error]',
  19. funcTag = '[object Function]',
  20. genTag = '[object GeneratorFunction]';
  21. /** Used to match empty string literals in compiled template source. */
  22. var reEmptyStringLeading = /\b__p \+= '';/g,
  23. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  24. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  25. /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */
  26. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  27. /** Used to detect unsigned integer values. */
  28. var reIsUint = /^(?:0|[1-9]\d*)$/;
  29. /** Used to ensure capturing order of template delimiters. */
  30. var reNoMatch = /($^)/;
  31. /** Used to match unescaped characters in compiled string literals. */
  32. var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
  33. /** Used to escape characters for inclusion in compiled string literals. */
  34. var stringEscapes = {
  35. '\\': '\\',
  36. "'": "'",
  37. '\n': 'n',
  38. '\r': 'r',
  39. '\u2028': 'u2028',
  40. '\u2029': 'u2029'
  41. };
  42. /**
  43. * A faster alternative to `Function#apply`, this function invokes `func`
  44. * with the `this` binding of `thisArg` and the arguments of `args`.
  45. *
  46. * @private
  47. * @param {Function} func The function to invoke.
  48. * @param {*} thisArg The `this` binding of `func`.
  49. * @param {...*} args The arguments to invoke `func` with.
  50. * @returns {*} Returns the result of `func`.
  51. */
  52. function apply(func, thisArg, args) {
  53. var length = args.length;
  54. switch (length) {
  55. case 0: return func.call(thisArg);
  56. case 1: return func.call(thisArg, args[0]);
  57. case 2: return func.call(thisArg, args[0], args[1]);
  58. case 3: return func.call(thisArg, args[0], args[1], args[2]);
  59. }
  60. return func.apply(thisArg, args);
  61. }
  62. /**
  63. * A specialized version of `_.map` for arrays without support for iteratee
  64. * shorthands.
  65. *
  66. * @private
  67. * @param {Array} array The array to iterate over.
  68. * @param {Function} iteratee The function invoked per iteration.
  69. * @returns {Array} Returns the new mapped array.
  70. */
  71. function arrayMap(array, iteratee) {
  72. var index = -1,
  73. length = array.length,
  74. result = Array(length);
  75. while (++index < length) {
  76. result[index] = iteratee(array[index], index, array);
  77. }
  78. return result;
  79. }
  80. /**
  81. * The base implementation of `_.values` and `_.valuesIn` which creates an
  82. * array of `object` property values corresponding to the property names
  83. * of `props`.
  84. *
  85. * @private
  86. * @param {Object} object The object to query.
  87. * @param {Array} props The property names to get values for.
  88. * @returns {Object} Returns the array of property values.
  89. */
  90. function baseValues(object, props) {
  91. return arrayMap(props, function(key) {
  92. return object[key];
  93. });
  94. }
  95. /**
  96. * Used by `_.template` to escape characters for inclusion in compiled string literals.
  97. *
  98. * @private
  99. * @param {string} chr The matched character to escape.
  100. * @returns {string} Returns the escaped character.
  101. */
  102. function escapeStringChar(chr) {
  103. return '\\' + stringEscapes[chr];
  104. }
  105. /**
  106. * Checks if `value` is a valid array-like index.
  107. *
  108. * @private
  109. * @param {*} value The value to check.
  110. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  111. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  112. */
  113. function isIndex(value, length) {
  114. value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
  115. length = length == null ? MAX_SAFE_INTEGER : length;
  116. return value > -1 && value % 1 == 0 && value < length;
  117. }
  118. /** Used for built-in method references. */
  119. var objectProto = Object.prototype;
  120. /** Used to check objects for own properties. */
  121. var hasOwnProperty = objectProto.hasOwnProperty;
  122. /**
  123. * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  124. * of values.
  125. */
  126. var objectToString = objectProto.toString;
  127. /**
  128. * Used by `_.defaults` to customize its `_.assignIn` use.
  129. *
  130. * @private
  131. * @param {*} objValue The destination value.
  132. * @param {*} srcValue The source value.
  133. * @param {string} key The key of the property to assign.
  134. * @param {Object} object The parent object of `objValue`.
  135. * @returns {*} Returns the value to assign.
  136. */
  137. function assignInDefaults(objValue, srcValue, key, object) {
  138. if (objValue === undefined ||
  139. (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
  140. return srcValue;
  141. }
  142. return objValue;
  143. }
  144. /**
  145. * The base implementation of `_.property` without support for deep paths.
  146. *
  147. * @private
  148. * @param {string} key The key of the property to get.
  149. * @returns {Function} Returns the new function.
  150. */
  151. function baseProperty(key) {
  152. return function(object) {
  153. return object == null ? undefined : object[key];
  154. };
  155. }
  156. /**
  157. * Gets the "length" property value of `object`.
  158. *
  159. * **Note:** This function is used to avoid a
  160. * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
  161. * Safari on at least iOS 8.1-8.3 ARM64.
  162. *
  163. * @private
  164. * @param {Object} object The object to query.
  165. * @returns {*} Returns the "length" value.
  166. */
  167. var getLength = baseProperty('length');
  168. /**
  169. * Checks if the given arguments are from an iteratee call.
  170. *
  171. * @private
  172. * @param {*} value The potential iteratee value argument.
  173. * @param {*} index The potential iteratee index or key argument.
  174. * @param {*} object The potential iteratee object argument.
  175. * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
  176. * else `false`.
  177. */
  178. function isIterateeCall(value, index, object) {
  179. if (!isObject(object)) {
  180. return false;
  181. }
  182. var type = typeof index;
  183. if (type == 'number'
  184. ? (isArrayLike(object) && isIndex(index, object.length))
  185. : (type == 'string' && index in object)
  186. ) {
  187. return eq(object[index], value);
  188. }
  189. return false;
  190. }
  191. /**
  192. * Performs a
  193. * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
  194. * comparison between two values to determine if they are equivalent.
  195. *
  196. * @static
  197. * @memberOf _
  198. * @since 4.0.0
  199. * @category Lang
  200. * @param {*} value The value to compare.
  201. * @param {*} other The other value to compare.
  202. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  203. * @example
  204. *
  205. * var object = { 'user': 'fred' };
  206. * var other = { 'user': 'fred' };
  207. *
  208. * _.eq(object, object);
  209. * // => true
  210. *
  211. * _.eq(object, other);
  212. * // => false
  213. *
  214. * _.eq('a', 'a');
  215. * // => true
  216. *
  217. * _.eq('a', Object('a'));
  218. * // => false
  219. *
  220. * _.eq(NaN, NaN);
  221. * // => true
  222. */
  223. function eq(value, other) {
  224. return value === other || (value !== value && other !== other);
  225. }
  226. /**
  227. * Checks if `value` is array-like. A value is considered array-like if it's
  228. * not a function and has a `value.length` that's an integer greater than or
  229. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  230. *
  231. * @static
  232. * @memberOf _
  233. * @since 4.0.0
  234. * @category Lang
  235. * @param {*} value The value to check.
  236. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  237. * @example
  238. *
  239. * _.isArrayLike([1, 2, 3]);
  240. * // => true
  241. *
  242. * _.isArrayLike(document.body.children);
  243. * // => true
  244. *
  245. * _.isArrayLike('abc');
  246. * // => true
  247. *
  248. * _.isArrayLike(_.noop);
  249. * // => false
  250. */
  251. function isArrayLike(value) {
  252. return value != null && isLength(getLength(value)) && !isFunction(value);
  253. }
  254. /**
  255. * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
  256. * `SyntaxError`, `TypeError`, or `URIError` object.
  257. *
  258. * @static
  259. * @memberOf _
  260. * @since 3.0.0
  261. * @category Lang
  262. * @param {*} value The value to check.
  263. * @returns {boolean} Returns `true` if `value` is an error object,
  264. * else `false`.
  265. * @example
  266. *
  267. * _.isError(new Error);
  268. * // => true
  269. *
  270. * _.isError(Error);
  271. * // => false
  272. */
  273. function isError(value) {
  274. if (!isObjectLike(value)) {
  275. return false;
  276. }
  277. return (objectToString.call(value) == errorTag) ||
  278. (typeof value.message == 'string' && typeof value.name == 'string');
  279. }
  280. /**
  281. * Checks if `value` is classified as a `Function` object.
  282. *
  283. * @static
  284. * @memberOf _
  285. * @since 0.1.0
  286. * @category Lang
  287. * @param {*} value The value to check.
  288. * @returns {boolean} Returns `true` if `value` is correctly classified,
  289. * else `false`.
  290. * @example
  291. *
  292. * _.isFunction(_);
  293. * // => true
  294. *
  295. * _.isFunction(/abc/);
  296. * // => false
  297. */
  298. function isFunction(value) {
  299. // The use of `Object#toString` avoids issues with the `typeof` operator
  300. // in Safari 8 which returns 'object' for typed array and weak map constructors,
  301. // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
  302. var tag = isObject(value) ? objectToString.call(value) : '';
  303. return tag == funcTag || tag == genTag;
  304. }
  305. /**
  306. * Checks if `value` is a valid array-like length.
  307. *
  308. * **Note:** This function is loosely based on
  309. * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
  310. *
  311. * @static
  312. * @memberOf _
  313. * @since 4.0.0
  314. * @category Lang
  315. * @param {*} value The value to check.
  316. * @returns {boolean} Returns `true` if `value` is a valid length,
  317. * else `false`.
  318. * @example
  319. *
  320. * _.isLength(3);
  321. * // => true
  322. *
  323. * _.isLength(Number.MIN_VALUE);
  324. * // => false
  325. *
  326. * _.isLength(Infinity);
  327. * // => false
  328. *
  329. * _.isLength('3');
  330. * // => false
  331. */
  332. function isLength(value) {
  333. return typeof value == 'number' &&
  334. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
  335. }
  336. /**
  337. * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
  338. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  339. *
  340. * @static
  341. * @memberOf _
  342. * @since 0.1.0
  343. * @category Lang
  344. * @param {*} value The value to check.
  345. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  346. * @example
  347. *
  348. * _.isObject({});
  349. * // => true
  350. *
  351. * _.isObject([1, 2, 3]);
  352. * // => true
  353. *
  354. * _.isObject(_.noop);
  355. * // => true
  356. *
  357. * _.isObject(null);
  358. * // => false
  359. */
  360. function isObject(value) {
  361. var type = typeof value;
  362. return !!value && (type == 'object' || type == 'function');
  363. }
  364. /**
  365. * Checks if `value` is object-like. A value is object-like if it's not `null`
  366. * and has a `typeof` result of "object".
  367. *
  368. * @static
  369. * @memberOf _
  370. * @since 4.0.0
  371. * @category Lang
  372. * @param {*} value The value to check.
  373. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  374. * @example
  375. *
  376. * _.isObjectLike({});
  377. * // => true
  378. *
  379. * _.isObjectLike([1, 2, 3]);
  380. * // => true
  381. *
  382. * _.isObjectLike(_.noop);
  383. * // => false
  384. *
  385. * _.isObjectLike(null);
  386. * // => false
  387. */
  388. function isObjectLike(value) {
  389. return !!value && typeof value == 'object';
  390. }
  391. /**
  392. * Creates a compiled template function that can interpolate data properties
  393. * in "interpolate" delimiters, HTML-escape interpolated data properties in
  394. * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
  395. * properties may be accessed as free variables in the template. If a setting
  396. * object is given it takes precedence over `_.templateSettings` values.
  397. *
  398. * **Note:** In the development build `_.template` utilizes
  399. * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
  400. * for easier debugging.
  401. *
  402. * For more information on precompiling templates see
  403. * [lodash's custom builds documentation](https://lodash.com/custom-builds).
  404. *
  405. * For more information on Chrome extension sandboxes see
  406. * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
  407. *
  408. * @static
  409. * @since 0.1.0
  410. * @memberOf _
  411. * @category String
  412. * @param {string} [string=''] The template string.
  413. * @param {Object} [options={}] The options object.
  414. * @param {RegExp} [options.escape=_.templateSettings.escape]
  415. * The HTML "escape" delimiter.
  416. * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
  417. * The "evaluate" delimiter.
  418. * @param {Object} [options.imports=_.templateSettings.imports]
  419. * An object to import into the template as free variables.
  420. * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
  421. * The "interpolate" delimiter.
  422. * @param {string} [options.sourceURL='templateSources[n]']
  423. * The sourceURL of the compiled template.
  424. * @param {string} [options.variable='obj']
  425. * The data object variable name.
  426. * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
  427. * @returns {Function} Returns the compiled template function.
  428. * @example
  429. *
  430. * // Use the "interpolate" delimiter to create a compiled template.
  431. * var compiled = _.template('hello <%= user %>!');
  432. * compiled({ 'user': 'fred' });
  433. * // => 'hello fred!'
  434. *
  435. * // Use the HTML "escape" delimiter to escape data property values.
  436. * var compiled = _.template('<b><%- value %></b>');
  437. * compiled({ 'value': '<script>' });
  438. * // => '<b>&lt;script&gt;</b>'
  439. *
  440. * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
  441. * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
  442. * compiled({ 'users': ['fred', 'barney'] });
  443. * // => '<li>fred</li><li>barney</li>'
  444. *
  445. * // Use the internal `print` function in "evaluate" delimiters.
  446. * var compiled = _.template('<% print("hello " + user); %>!');
  447. * compiled({ 'user': 'barney' });
  448. * // => 'hello barney!'
  449. *
  450. * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
  451. * var compiled = _.template('hello ${ user }!');
  452. * compiled({ 'user': 'pebbles' });
  453. * // => 'hello pebbles!'
  454. *
  455. * // Use custom template delimiters.
  456. * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
  457. * var compiled = _.template('hello {{ user }}!');
  458. * compiled({ 'user': 'mustache' });
  459. * // => 'hello mustache!'
  460. *
  461. * // Use backslashes to treat delimiters as plain text.
  462. * var compiled = _.template('<%= "\\<%- value %\\>" %>');
  463. * compiled({ 'value': 'ignored' });
  464. * // => '<%- value %>'
  465. *
  466. * // Use the `imports` option to import `jQuery` as `jq`.
  467. * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
  468. * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
  469. * compiled({ 'users': ['fred', 'barney'] });
  470. * // => '<li>fred</li><li>barney</li>'
  471. *
  472. * // Use the `sourceURL` option to specify a custom sourceURL for the template.
  473. * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
  474. * compiled(data);
  475. * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
  476. *
  477. * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
  478. * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
  479. * compiled.source;
  480. * // => function(data) {
  481. * // var __t, __p = '';
  482. * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
  483. * // return __p;
  484. * // }
  485. *
  486. * // Use the `source` property to inline compiled templates for meaningful
  487. * // line numbers in error messages and stack traces.
  488. * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
  489. * var JST = {\
  490. * "main": ' + _.template(mainText).source + '\
  491. * };\
  492. * ');
  493. */
  494. function template(string, options, guard) {
  495. // Based on John Resig's `tmpl` implementation
  496. // (http://ejohn.org/blog/javascript-micro-templating/)
  497. // and Laura Doktorova's doT.js (https://github.com/olado/doT).
  498. var settings = templateSettings.imports._.templateSettings || templateSettings;
  499. if (guard && isIterateeCall(string, options, guard)) {
  500. options = undefined;
  501. }
  502. string = toString(string);
  503. options = assignInWith({}, options, settings, assignInDefaults);
  504. var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
  505. importsKeys = keys(imports),
  506. importsValues = baseValues(imports, importsKeys);
  507. var isEscaping,
  508. isEvaluating,
  509. index = 0,
  510. interpolate = options.interpolate || reNoMatch,
  511. source = "__p += '";
  512. // Compile the regexp to match each delimiter.
  513. var reDelimiters = RegExp(
  514. (options.escape || reNoMatch).source + '|' +
  515. interpolate.source + '|' +
  516. (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
  517. (options.evaluate || reNoMatch).source + '|$'
  518. , 'g');
  519. // Use a sourceURL for easier debugging.
  520. var sourceURL = 'sourceURL' in options ? '//# sourceURL=' + options.sourceURL + '\n' : '';
  521. string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
  522. interpolateValue || (interpolateValue = esTemplateValue);
  523. // Escape characters that can't be included in string literals.
  524. source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
  525. // Replace delimiters with snippets.
  526. if (escapeValue) {
  527. isEscaping = true;
  528. source += "' +\n__e(" + escapeValue + ") +\n'";
  529. }
  530. if (evaluateValue) {
  531. isEvaluating = true;
  532. source += "';\n" + evaluateValue + ";\n__p += '";
  533. }
  534. if (interpolateValue) {
  535. source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
  536. }
  537. index = offset + match.length;
  538. // The JS engine embedded in Adobe products needs `match` returned in
  539. // order to produce the correct `offset` value.
  540. return match;
  541. });
  542. source += "';\n";
  543. // If `variable` is not specified wrap a with-statement around the generated
  544. // code to add the data object to the top of the scope chain.
  545. var variable = options.variable;
  546. if (!variable) {
  547. source = 'with (obj) {\n' + source + '\n}\n';
  548. }
  549. // Cleanup code by stripping empty strings.
  550. source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
  551. .replace(reEmptyStringMiddle, '$1')
  552. .replace(reEmptyStringTrailing, '$1;');
  553. // Frame code as the function body.
  554. source = 'function(' + (variable || 'obj') + ') {\n' +
  555. (variable
  556. ? ''
  557. : 'obj || (obj = {});\n'
  558. ) +
  559. "var __t, __p = ''" +
  560. (isEscaping
  561. ? ', __e = _.escape'
  562. : ''
  563. ) +
  564. (isEvaluating
  565. ? ', __j = Array.prototype.join;\n' +
  566. "function print() { __p += __j.call(arguments, '') }\n"
  567. : ';\n'
  568. ) +
  569. source +
  570. 'return __p\n}';
  571. var result = attempt(function() {
  572. return Function(importsKeys, sourceURL + 'return ' + source)
  573. .apply(undefined, importsValues);
  574. });
  575. // Provide the compiled function's source by its `toString` method or
  576. // the `source` property as a convenience for inlining compiled templates.
  577. result.source = source;
  578. if (isError(result)) {
  579. throw result;
  580. }
  581. return result;
  582. }
  583. /**
  584. * Attempts to invoke `func`, returning either the result or the caught error
  585. * object. Any additional arguments are provided to `func` when it's invoked.
  586. *
  587. * @static
  588. * @memberOf _
  589. * @since 3.0.0
  590. * @category Util
  591. * @param {Function} func The function to attempt.
  592. * @param {...*} [args] The arguments to invoke `func` with.
  593. * @returns {*} Returns the `func` result or error object.
  594. * @example
  595. *
  596. * // Avoid throwing errors for invalid selectors.
  597. * var elements = _.attempt(function(selector) {
  598. * return document.querySelectorAll(selector);
  599. * }, '>_>');
  600. *
  601. * if (_.isError(elements)) {
  602. * elements = [];
  603. * }
  604. */
  605. var attempt = rest(function(func, args) {
  606. try {
  607. return apply(func, undefined, args);
  608. } catch (e) {
  609. return isError(e) ? e : new Error(e);
  610. }
  611. });
  612. module.exports = template;