.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / fast-glob / node_modules / fill-range / index.js
1 /*!
2  * fill-range <https://github.com/jonschlinkert/fill-range>
3  *
4  * Copyright (c) 2014-2015, 2017, Jon Schlinkert.
5  * Released under the MIT License.
6  */
7
8 'use strict';
9
10 var util = require('util');
11 var isNumber = require('is-number');
12 var extend = require('extend-shallow');
13 var repeat = require('repeat-string');
14 var toRegex = require('to-regex-range');
15
16 /**
17  * Return a range of numbers or letters.
18  *
19  * @param  {String} `start` Start of the range
20  * @param  {String} `stop` End of the range
21  * @param  {String} `step` Increment or decrement to use.
22  * @param  {Function} `fn` Custom function to modify each element in the range.
23  * @return {Array}
24  */
25
26 function fillRange(start, stop, step, options) {
27   if (typeof start === 'undefined') {
28     return [];
29   }
30
31   if (typeof stop === 'undefined' || start === stop) {
32     // special case, for handling negative zero
33     var isString = typeof start === 'string';
34     if (isNumber(start) && !toNumber(start)) {
35       return [isString ? '0' : 0];
36     }
37     return [start];
38   }
39
40   if (typeof step !== 'number' && typeof step !== 'string') {
41     options = step;
42     step = undefined;
43   }
44
45   if (typeof options === 'function') {
46     options = { transform: options };
47   }
48
49   var opts = extend({step: step}, options);
50   if (opts.step && !isValidNumber(opts.step)) {
51     if (opts.strictRanges === true) {
52       throw new TypeError('expected options.step to be a number');
53     }
54     return [];
55   }
56
57   opts.isNumber = isValidNumber(start) && isValidNumber(stop);
58   if (!opts.isNumber && !isValid(start, stop)) {
59     if (opts.strictRanges === true) {
60       throw new RangeError('invalid range arguments: ' + util.inspect([start, stop]));
61     }
62     return [];
63   }
64
65   opts.isPadded = isPadded(start) || isPadded(stop);
66   opts.toString = opts.stringify
67     || typeof opts.step === 'string'
68     || typeof start === 'string'
69     || typeof stop === 'string'
70     || !opts.isNumber;
71
72   if (opts.isPadded) {
73     opts.maxLength = Math.max(String(start).length, String(stop).length);
74   }
75
76   // support legacy minimatch/fill-range options
77   if (typeof opts.optimize === 'boolean') opts.toRegex = opts.optimize;
78   if (typeof opts.makeRe === 'boolean') opts.toRegex = opts.makeRe;
79   return expand(start, stop, opts);
80 }
81
82 function expand(start, stop, options) {
83   var a = options.isNumber ? toNumber(start) : start.charCodeAt(0);
84   var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0);
85
86   var step = Math.abs(toNumber(options.step)) || 1;
87   if (options.toRegex && step === 1) {
88     return toRange(a, b, start, stop, options);
89   }
90
91   var zero = {greater: [], lesser: []};
92   var asc = a < b;
93   var arr = new Array(Math.round((asc ? b - a : a - b) / step));
94   var idx = 0;
95
96   while (asc ? a <= b : a >= b) {
97     var val = options.isNumber ? a : String.fromCharCode(a);
98     if (options.toRegex && (val >= 0 || !options.isNumber)) {
99       zero.greater.push(val);
100     } else {
101       zero.lesser.push(Math.abs(val));
102     }
103
104     if (options.isPadded) {
105       val = zeros(val, options);
106     }
107
108     if (options.toString) {
109       val = String(val);
110     }
111
112     if (typeof options.transform === 'function') {
113       arr[idx++] = options.transform(val, a, b, step, idx, arr, options);
114     } else {
115       arr[idx++] = val;
116     }
117
118     if (asc) {
119       a += step;
120     } else {
121       a -= step;
122     }
123   }
124
125   if (options.toRegex === true) {
126     return toSequence(arr, zero, options);
127   }
128   return arr;
129 }
130
131 function toRange(a, b, start, stop, options) {
132   if (options.isPadded) {
133     return toRegex(start, stop, options);
134   }
135
136   if (options.isNumber) {
137     return toRegex(Math.min(a, b), Math.max(a, b), options);
138   }
139
140   var start = String.fromCharCode(Math.min(a, b));
141   var stop = String.fromCharCode(Math.max(a, b));
142   return '[' + start + '-' + stop + ']';
143 }
144
145 function toSequence(arr, zeros, options) {
146   var greater = '', lesser = '';
147   if (zeros.greater.length) {
148     greater = zeros.greater.join('|');
149   }
150   if (zeros.lesser.length) {
151     lesser = '-(' + zeros.lesser.join('|') + ')';
152   }
153   var res = greater && lesser
154     ? greater + '|' + lesser
155     : greater || lesser;
156
157   if (options.capture) {
158     return '(' + res + ')';
159   }
160   return res;
161 }
162
163 function zeros(val, options) {
164   if (options.isPadded) {
165     var str = String(val);
166     var len = str.length;
167     var dash = '';
168     if (str.charAt(0) === '-') {
169       dash = '-';
170       str = str.slice(1);
171     }
172     var diff = options.maxLength - len;
173     var pad = repeat('0', diff);
174     val = (dash + pad + str);
175   }
176   if (options.stringify) {
177     return String(val);
178   }
179   return val;
180 }
181
182 function toNumber(val) {
183   return Number(val) || 0;
184 }
185
186 function isPadded(str) {
187   return /^-?0\d/.test(str);
188 }
189
190 function isValid(min, max) {
191   return (isValidNumber(min) || isValidLetter(min))
192       && (isValidNumber(max) || isValidLetter(max));
193 }
194
195 function isValidLetter(ch) {
196   return typeof ch === 'string' && ch.length === 1 && /^\w+$/.test(ch);
197 }
198
199 function isValidNumber(n) {
200   return isNumber(n) && !/\./.test(n);
201 }
202
203 /**
204  * Expose `fillRange`
205  * @type {Function}
206  */
207
208 module.exports = fillRange;