wallet-core/node_modules/fill-range/index.js

209 lines
4.9 KiB
JavaScript
Raw Normal View History

2016-10-10 03:43:44 +02:00
/*!
* fill-range <https://github.com/jonschlinkert/fill-range>
*
2018-09-20 02:56:13 +02:00
* Copyright (c) 2014-2015, 2017, Jon Schlinkert.
* Released under the MIT License.
2016-10-10 03:43:44 +02:00
*/
'use strict';
2018-09-20 02:56:13 +02:00
var util = require('util');
2016-10-10 03:43:44 +02:00
var isNumber = require('is-number');
2018-09-20 02:56:13 +02:00
var extend = require('extend-shallow');
var repeat = require('repeat-string');
var toRegex = require('to-regex-range');
2016-10-10 03:43:44 +02:00
/**
* Return a range of numbers or letters.
*
2018-09-20 02:56:13 +02:00
* @param {String} `start` Start of the range
* @param {String} `stop` End of the range
2016-10-10 03:43:44 +02:00
* @param {String} `step` Increment or decrement to use.
* @param {Function} `fn` Custom function to modify each element in the range.
* @return {Array}
*/
2018-09-20 02:56:13 +02:00
function fillRange(start, stop, step, options) {
if (typeof start === 'undefined') {
return [];
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (typeof stop === 'undefined' || start === stop) {
// special case, for handling negative zero
var isString = typeof start === 'string';
if (isNumber(start) && !toNumber(start)) {
return [isString ? '0' : 0];
}
return [start];
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (typeof step !== 'number' && typeof step !== 'string') {
options = step;
step = undefined;
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (typeof options === 'function') {
options = { transform: options };
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
var opts = extend({step: step}, options);
if (opts.step && !isValidNumber(opts.step)) {
if (opts.strictRanges === true) {
throw new TypeError('expected options.step to be a number');
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
return [];
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
opts.isNumber = isValidNumber(start) && isValidNumber(stop);
if (!opts.isNumber && !isValid(start, stop)) {
if (opts.strictRanges === true) {
throw new RangeError('invalid range arguments: ' + util.inspect([start, stop]));
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
return [];
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
opts.isPadded = isPadded(start) || isPadded(stop);
opts.toString = opts.stringify
|| typeof opts.step === 'string'
|| typeof start === 'string'
|| typeof stop === 'string'
|| !opts.isNumber;
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
if (opts.isPadded) {
opts.maxLength = Math.max(String(start).length, String(stop).length);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
// support legacy minimatch/fill-range options
if (typeof opts.optimize === 'boolean') opts.toRegex = opts.optimize;
if (typeof opts.makeRe === 'boolean') opts.toRegex = opts.makeRe;
return expand(start, stop, opts);
}
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
function expand(start, stop, options) {
var a = options.isNumber ? toNumber(start) : start.charCodeAt(0);
var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0);
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
var step = Math.abs(toNumber(options.step)) || 1;
if (options.toRegex && step === 1) {
return toRange(a, b, start, stop, options);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
var zero = {greater: [], lesser: []};
var asc = a < b;
var arr = new Array(Math.round((asc ? b - a : a - b) / step));
var idx = 0;
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
while (asc ? a <= b : a >= b) {
var val = options.isNumber ? a : String.fromCharCode(a);
if (options.toRegex && (val >= 0 || !options.isNumber)) {
zero.greater.push(val);
} else {
zero.lesser.push(Math.abs(val));
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (options.isPadded) {
val = zeros(val, options);
}
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
if (options.toString) {
val = String(val);
}
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
if (typeof options.transform === 'function') {
arr[idx++] = options.transform(val, a, b, step, idx, arr, options);
2016-10-10 03:43:44 +02:00
} else {
2018-09-20 02:56:13 +02:00
arr[idx++] = val;
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (asc) {
a += step;
2016-10-10 03:43:44 +02:00
} else {
2018-09-20 02:56:13 +02:00
a -= step;
2016-10-10 03:43:44 +02:00
}
}
2018-09-20 02:56:13 +02:00
if (options.toRegex === true) {
return toSequence(arr, zero, options);
2016-10-10 03:43:44 +02:00
}
return arr;
}
2018-09-20 02:56:13 +02:00
function toRange(a, b, start, stop, options) {
if (options.isPadded) {
return toRegex(start, stop, options);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (options.isNumber) {
return toRegex(Math.min(a, b), Math.max(a, b), options);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
var start = String.fromCharCode(Math.min(a, b));
var stop = String.fromCharCode(Math.max(a, b));
return '[' + start + '-' + stop + ']';
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function toSequence(arr, zeros, options) {
var greater = '', lesser = '';
if (zeros.greater.length) {
greater = zeros.greater.join('|');
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (zeros.lesser.length) {
lesser = '-(' + zeros.lesser.join('|') + ')';
}
var res = greater && lesser
? greater + '|' + lesser
: greater || lesser;
2016-10-10 03:43:44 +02:00
2018-09-20 02:56:13 +02:00
if (options.capture) {
return '(' + res + ')';
}
return res;
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function zeros(val, options) {
if (options.isPadded) {
var str = String(val);
var len = str.length;
var dash = '';
if (str.charAt(0) === '-') {
dash = '-';
str = str.slice(1);
}
var diff = options.maxLength - len;
var pad = repeat('0', diff);
val = (dash + pad + str);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
if (options.stringify) {
return String(val);
}
return val;
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function toNumber(val) {
return Number(val) || 0;
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function isPadded(str) {
return /^-?0\d/.test(str);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function isValid(min, max) {
return (isValidNumber(min) || isValidLetter(min))
&& (isValidNumber(max) || isValidLetter(max));
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function isValidLetter(ch) {
return typeof ch === 'string' && ch.length === 1 && /^\w+$/.test(ch);
2016-10-10 03:43:44 +02:00
}
2018-09-20 02:56:13 +02:00
function isValidNumber(n) {
return isNumber(n) && !/\./.test(n);
2016-10-10 03:43:44 +02:00
}
/**
2018-09-20 02:56:13 +02:00
* Expose `fillRange`
* @type {Function}
2016-10-10 03:43:44 +02:00
*/
2018-09-20 02:56:13 +02:00
module.exports = fillRange;