2 * lodash (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
9 var baseSlice = require('lodash._baseslice'),
10 baseToString = require('lodash._basetostring'),
11 toString = require('lodash.tostring');
13 /** Used as references for various `Number` constants. */
15 MAX_SAFE_INTEGER = 9007199254740991,
16 MAX_INTEGER = 1.7976931348623157e+308,
19 /** `Object#toString` result references. */
20 var funcTag = '[object Function]',
21 genTag = '[object GeneratorFunction]',
22 symbolTag = '[object Symbol]';
24 /** Used to match leading and trailing whitespace. */
25 var reTrim = /^\s+|\s+$/g;
27 /** Used to detect bad signed hexadecimal string values. */
28 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
30 /** Used to detect binary string values. */
31 var reIsBinary = /^0b[01]+$/i;
33 /** Used to detect octal string values. */
34 var reIsOctal = /^0o[0-7]+$/i;
36 /** Used to compose unicode character classes. */
37 var rsAstralRange = '\\ud800-\\udfff',
38 rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
39 rsComboSymbolsRange = '\\u20d0-\\u20f0',
40 rsVarRange = '\\ufe0e\\ufe0f';
42 /** Used to compose unicode capture groups. */
43 var rsAstral = '[' + rsAstralRange + ']',
44 rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
45 rsFitz = '\\ud83c[\\udffb-\\udfff]',
46 rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
47 rsNonAstral = '[^' + rsAstralRange + ']',
48 rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
49 rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
52 /** Used to compose unicode regexes. */
53 var reOptMod = rsModifier + '?',
54 rsOptVar = '[' + rsVarRange + ']?',
55 rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
56 rsSeq = rsOptVar + reOptMod + rsOptJoin,
57 rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
59 /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
60 var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
62 /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
63 var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
65 /** Built-in method references without a dependency on `root`. */
66 var freeParseInt = parseInt;
69 * Gets the number of symbols in `string`.
72 * @param {string} string The string to inspect.
73 * @returns {number} Returns the string size.
75 function stringSize(string) {
76 if (!(string && reHasComplexSymbol.test(string))) {
79 var result = reComplexSymbol.lastIndex = 0;
80 while (reComplexSymbol.test(string)) {
87 * Converts `string` to an array.
90 * @param {string} string The string to convert.
91 * @returns {Array} Returns the converted array.
93 function stringToArray(string) {
94 return string.match(reComplexSymbol);
97 /** Used for built-in method references. */
98 var objectProto = Object.prototype;
101 * Used to resolve the
102 * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
105 var objectToString = objectProto.toString;
107 /* Built-in method references for those with the same name as other `lodash` methods. */
108 var nativeCeil = Math.ceil,
109 nativeFloor = Math.floor;
112 * The base implementation of `_.repeat` which doesn't coerce arguments.
115 * @param {string} string The string to repeat.
116 * @param {number} n The number of times to repeat the string.
117 * @returns {string} Returns the repeated string.
119 function baseRepeat(string, n) {
121 if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
124 // Leverage the exponentiation by squaring algorithm for a faster repeat.
125 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
130 n = nativeFloor(n / 2);
140 * Casts `array` to a slice if it's needed.
143 * @param {Array} array The array to inspect.
144 * @param {number} start The start position.
145 * @param {number} [end=array.length] The end position.
146 * @returns {Array} Returns the cast slice.
148 function castSlice(array, start, end) {
149 var length = array.length;
150 end = end === undefined ? length : end;
151 return (!start && end >= length) ? array : baseSlice(array, start, end);
155 * Creates the padding for `string` based on `length`. The `chars` string
156 * is truncated if the number of characters exceeds `length`.
159 * @param {number} length The padding length.
160 * @param {string} [chars=' '] The string used as padding.
161 * @returns {string} Returns the padding for `string`.
163 function createPadding(length, chars) {
164 chars = chars === undefined ? ' ' : baseToString(chars);
166 var charsLength = chars.length;
167 if (charsLength < 2) {
168 return charsLength ? baseRepeat(chars, length) : chars;
170 var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
171 return reHasComplexSymbol.test(chars)
172 ? castSlice(stringToArray(result), 0, length).join('')
173 : result.slice(0, length);
177 * Checks if `value` is classified as a `Function` object.
183 * @param {*} value The value to check.
184 * @returns {boolean} Returns `true` if `value` is correctly classified,
191 * _.isFunction(/abc/);
194 function isFunction(value) {
195 // The use of `Object#toString` avoids issues with the `typeof` operator
196 // in Safari 8 which returns 'object' for typed array and weak map constructors,
197 // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
198 var tag = isObject(value) ? objectToString.call(value) : '';
199 return tag == funcTag || tag == genTag;
203 * Checks if `value` is the
204 * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
205 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
211 * @param {*} value The value to check.
212 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
218 * _.isObject([1, 2, 3]);
221 * _.isObject(_.noop);
227 function isObject(value) {
228 var type = typeof value;
229 return !!value && (type == 'object' || type == 'function');
233 * Checks if `value` is object-like. A value is object-like if it's not `null`
234 * and has a `typeof` result of "object".
240 * @param {*} value The value to check.
241 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
244 * _.isObjectLike({});
247 * _.isObjectLike([1, 2, 3]);
250 * _.isObjectLike(_.noop);
253 * _.isObjectLike(null);
256 function isObjectLike(value) {
257 return !!value && typeof value == 'object';
261 * Checks if `value` is classified as a `Symbol` primitive or object.
267 * @param {*} value The value to check.
268 * @returns {boolean} Returns `true` if `value` is correctly classified,
272 * _.isSymbol(Symbol.iterator);
278 function isSymbol(value) {
279 return typeof value == 'symbol' ||
280 (isObjectLike(value) && objectToString.call(value) == symbolTag);
284 * Converts `value` to a finite number.
290 * @param {*} value The value to convert.
291 * @returns {number} Returns the converted number.
297 * _.toFinite(Number.MIN_VALUE);
300 * _.toFinite(Infinity);
301 * // => 1.7976931348623157e+308
306 function toFinite(value) {
308 return value === 0 ? value : 0;
310 value = toNumber(value);
311 if (value === INFINITY || value === -INFINITY) {
312 var sign = (value < 0 ? -1 : 1);
313 return sign * MAX_INTEGER;
315 return value === value ? value : 0;
319 * Converts `value` to an integer.
321 * **Note:** This function is loosely based on
322 * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
328 * @param {*} value The value to convert.
329 * @returns {number} Returns the converted integer.
335 * _.toInteger(Number.MIN_VALUE);
338 * _.toInteger(Infinity);
339 * // => 1.7976931348623157e+308
341 * _.toInteger('3.2');
344 function toInteger(value) {
345 var result = toFinite(value),
346 remainder = result % 1;
348 return result === result ? (remainder ? result - remainder : result) : 0;
352 * Converts `value` to a number.
358 * @param {*} value The value to process.
359 * @returns {number} Returns the number.
365 * _.toNumber(Number.MIN_VALUE);
368 * _.toNumber(Infinity);
374 function toNumber(value) {
375 if (typeof value == 'number') {
378 if (isSymbol(value)) {
381 if (isObject(value)) {
382 var other = isFunction(value.valueOf) ? value.valueOf() : value;
383 value = isObject(other) ? (other + '') : other;
385 if (typeof value != 'string') {
386 return value === 0 ? value : +value;
388 value = value.replace(reTrim, '');
389 var isBinary = reIsBinary.test(value);
390 return (isBinary || reIsOctal.test(value))
391 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
392 : (reIsBadHex.test(value) ? NAN : +value);
396 * Pads `string` on the left side if it's shorter than `length`. Padding
397 * characters are truncated if they exceed `length`.
403 * @param {string} [string=''] The string to pad.
404 * @param {number} [length=0] The padding length.
405 * @param {string} [chars=' '] The string used as padding.
406 * @returns {string} Returns the padded string.
409 * _.padStart('abc', 6);
412 * _.padStart('abc', 6, '_-');
415 * _.padStart('abc', 3);
418 function padStart(string, length, chars) {
419 string = toString(string);
420 length = toInteger(length);
422 var strLength = length ? stringSize(string) : 0;
423 return (length && strLength < length)
424 ? (createPadding(length - strLength, chars) + string)
428 module.exports = padStart;