aboutsummaryrefslogtreecommitdiff
path: root/node_modules/fill-range/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/fill-range/index.js')
-rw-r--r--node_modules/fill-range/index.js249
1 files changed, 249 insertions, 0 deletions
diff --git a/node_modules/fill-range/index.js b/node_modules/fill-range/index.js
new file mode 100644
index 0000000..97ce35a
--- /dev/null
+++ b/node_modules/fill-range/index.js
@@ -0,0 +1,249 @@
+/*!
+ * fill-range <https://github.com/jonschlinkert/fill-range>
+ *
+ * Copyright (c) 2014-present, Jon Schlinkert.
+ * Licensed under the MIT License.
+ */
+
+'use strict';
+
+const util = require('util');
+const toRegexRange = require('to-regex-range');
+
+const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
+
+const transform = toNumber => {
+ return value => toNumber === true ? Number(value) : String(value);
+};
+
+const isValidValue = value => {
+ return typeof value === 'number' || (typeof value === 'string' && value !== '');
+};
+
+const isNumber = num => Number.isInteger(+num);
+
+const zeros = input => {
+ let value = `${input}`;
+ let index = -1;
+ if (value[0] === '-') value = value.slice(1);
+ if (value === '0') return false;
+ while (value[++index] === '0');
+ return index > 0;
+};
+
+const stringify = (start, end, options) => {
+ if (typeof start === 'string' || typeof end === 'string') {
+ return true;
+ }
+ return options.stringify === true;
+};
+
+const pad = (input, maxLength, toNumber) => {
+ if (maxLength > 0) {
+ let dash = input[0] === '-' ? '-' : '';
+ if (dash) input = input.slice(1);
+ input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
+ }
+ if (toNumber === false) {
+ return String(input);
+ }
+ return input;
+};
+
+const toMaxLen = (input, maxLength) => {
+ let negative = input[0] === '-' ? '-' : '';
+ if (negative) {
+ input = input.slice(1);
+ maxLength--;
+ }
+ while (input.length < maxLength) input = '0' + input;
+ return negative ? ('-' + input) : input;
+};
+
+const toSequence = (parts, options) => {
+ parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
+ parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
+
+ let prefix = options.capture ? '' : '?:';
+ let positives = '';
+ let negatives = '';
+ let result;
+
+ if (parts.positives.length) {
+ positives = parts.positives.join('|');
+ }
+
+ if (parts.negatives.length) {
+ negatives = `-(${prefix}${parts.negatives.join('|')})`;
+ }
+
+ if (positives && negatives) {
+ result = `${positives}|${negatives}`;
+ } else {
+ result = positives || negatives;
+ }
+
+ if (options.wrap) {
+ return `(${prefix}${result})`;
+ }
+
+ return result;
+};
+
+const toRange = (a, b, isNumbers, options) => {
+ if (isNumbers) {
+ return toRegexRange(a, b, { wrap: false, ...options });
+ }
+
+ let start = String.fromCharCode(a);
+ if (a === b) return start;
+
+ let stop = String.fromCharCode(b);
+ return `[${start}-${stop}]`;
+};
+
+const toRegex = (start, end, options) => {
+ if (Array.isArray(start)) {
+ let wrap = options.wrap === true;
+ let prefix = options.capture ? '' : '?:';
+ return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
+ }
+ return toRegexRange(start, end, options);
+};
+
+const rangeError = (...args) => {
+ return new RangeError('Invalid range arguments: ' + util.inspect(...args));
+};
+
+const invalidRange = (start, end, options) => {
+ if (options.strictRanges === true) throw rangeError([start, end]);
+ return [];
+};
+
+const invalidStep = (step, options) => {
+ if (options.strictRanges === true) {
+ throw new TypeError(`Expected step "${step}" to be a number`);
+ }
+ return [];
+};
+
+const fillNumbers = (start, end, step = 1, options = {}) => {
+ let a = Number(start);
+ let b = Number(end);
+
+ if (!Number.isInteger(a) || !Number.isInteger(b)) {
+ if (options.strictRanges === true) throw rangeError([start, end]);
+ return [];
+ }
+
+ // fix negative zero
+ if (a === 0) a = 0;
+ if (b === 0) b = 0;
+
+ let descending = a > b;
+ let startString = String(start);
+ let endString = String(end);
+ let stepString = String(step);
+ step = Math.max(Math.abs(step), 1);
+
+ let padded = zeros(startString) || zeros(endString) || zeros(stepString);
+ let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
+ let toNumber = padded === false && stringify(start, end, options) === false;
+ let format = options.transform || transform(toNumber);
+
+ if (options.toRegex && step === 1) {
+ return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
+ }
+
+ let parts = { negatives: [], positives: [] };
+ let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
+ let range = [];
+ let index = 0;
+
+ while (descending ? a >= b : a <= b) {
+ if (options.toRegex === true && step > 1) {
+ push(a);
+ } else {
+ range.push(pad(format(a, index), maxLen, toNumber));
+ }
+ a = descending ? a - step : a + step;
+ index++;
+ }
+
+ if (options.toRegex === true) {
+ return step > 1
+ ? toSequence(parts, options)
+ : toRegex(range, null, { wrap: false, ...options });
+ }
+
+ return range;
+};
+
+const fillLetters = (start, end, step = 1, options = {}) => {
+ if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) {
+ return invalidRange(start, end, options);
+ }
+
+
+ let format = options.transform || (val => String.fromCharCode(val));
+ let a = `${start}`.charCodeAt(0);
+ let b = `${end}`.charCodeAt(0);
+
+ let descending = a > b;
+ let min = Math.min(a, b);
+ let max = Math.max(a, b);
+
+ if (options.toRegex && step === 1) {
+ return toRange(min, max, false, options);
+ }
+
+ let range = [];
+ let index = 0;
+
+ while (descending ? a >= b : a <= b) {
+ range.push(format(a, index));
+ a = descending ? a - step : a + step;
+ index++;
+ }
+
+ if (options.toRegex === true) {
+ return toRegex(range, null, { wrap: false, options });
+ }
+
+ return range;
+};
+
+const fill = (start, end, step, options = {}) => {
+ if (end == null && isValidValue(start)) {
+ return [start];
+ }
+
+ if (!isValidValue(start) || !isValidValue(end)) {
+ return invalidRange(start, end, options);
+ }
+
+ if (typeof step === 'function') {
+ return fill(start, end, 1, { transform: step });
+ }
+
+ if (isObject(step)) {
+ return fill(start, end, 0, step);
+ }
+
+ let opts = { ...options };
+ if (opts.capture === true) opts.wrap = true;
+ step = step || opts.step || 1;
+
+ if (!isNumber(step)) {
+ if (step != null && !isObject(step)) return invalidStep(step, opts);
+ return fill(start, end, 1, step);
+ }
+
+ if (isNumber(start) && isNumber(end)) {
+ return fillNumbers(start, end, step, opts);
+ }
+
+ return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
+};
+
+module.exports = fill;