3 // export the class if we are in a Node-like system.
4 if (typeof module === 'object' && module.exports === exports)
5 exports = module.exports = SemVer;
7 // The debug function is excluded entirely from the minified version.
9 // Note: this is the semver.org version of the spec that it implements
10 // Not necessarily the package version of this code.
11 exports.SEMVER_SPEC_VERSION = '2.0.0';
13 // The actual regexps go on exports.re
14 var re = exports.re = [];
15 var src = exports.src = [];
18 // The following Regular Expressions can be used for tokenizing,
19 // validating, and parsing SemVer version strings.
21 // ## Numeric Identifier
22 // A single `0`, or a non-zero digit followed by zero or more digits.
24 var NUMERICIDENTIFIER = R++;
25 src[NUMERICIDENTIFIER] = '0|[1-9]\\d*';
26 var NUMERICIDENTIFIERLOOSE = R++;
27 src[NUMERICIDENTIFIERLOOSE] = '[0-9]+';
30 // ## Non-numeric Identifier
31 // Zero or more digits, followed by a letter or hyphen, and then zero or
32 // more letters, digits, or hyphens.
34 var NONNUMERICIDENTIFIER = R++;
35 src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';
39 // Three dot-separated numeric identifiers.
41 var MAINVERSION = R++;
42 src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
43 '(' + src[NUMERICIDENTIFIER] + ')\\.' +
44 '(' + src[NUMERICIDENTIFIER] + ')';
46 var MAINVERSIONLOOSE = R++;
47 src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
48 '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
49 '(' + src[NUMERICIDENTIFIERLOOSE] + ')';
51 // ## Pre-release Version Identifier
52 // A numeric identifier, or a non-numeric identifier.
54 var PRERELEASEIDENTIFIER = R++;
55 src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
56 '|' + src[NONNUMERICIDENTIFIER] + ')';
58 var PRERELEASEIDENTIFIERLOOSE = R++;
59 src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
60 '|' + src[NONNUMERICIDENTIFIER] + ')';
63 // ## Pre-release Version
64 // Hyphen, followed by one or more dot-separated pre-release version
68 src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
69 '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))';
71 var PRERELEASELOOSE = R++;
72 src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
73 '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))';
75 // ## Build Metadata Identifier
76 // Any combination of digits, letters, or hyphens.
78 var BUILDIDENTIFIER = R++;
79 src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+';
82 // Plus sign, followed by one or more period-separated build metadata
86 src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
87 '(?:\\.' + src[BUILDIDENTIFIER] + ')*))';
90 // ## Full Version String
91 // A main version, followed optionally by a pre-release version and
94 // Note that the only major, minor, patch, and pre-release sections of
95 // the version string are capturing groups. The build metadata is not a
96 // capturing group, because it should not ever be used in version
100 var FULLPLAIN = 'v?' + src[MAINVERSION] +
101 src[PRERELEASE] + '?' +
104 src[FULL] = '^' + FULLPLAIN + '$';
106 // like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
107 // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
108 // common in the npm registry.
109 var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
110 src[PRERELEASELOOSE] + '?' +
114 src[LOOSE] = '^' + LOOSEPLAIN + '$';
117 src[GTLT] = '((?:<|>)?=?)';
119 // Something like "2.*" or "1.2.x".
120 // Note that "x.x" is a valid xRange identifer, meaning "any version"
121 // Only the first item is strictly required.
122 var XRANGEIDENTIFIERLOOSE = R++;
123 src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*';
124 var XRANGEIDENTIFIER = R++;
125 src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*';
127 var XRANGEPLAIN = R++;
128 src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
129 '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
130 '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
131 '(?:(' + src[PRERELEASE] + ')' +
134 var XRANGEPLAINLOOSE = R++;
135 src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
136 '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
137 '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
138 '(?:(' + src[PRERELEASELOOSE] + ')' +
141 // >=2.x, for example, means >=2.0.0-0
142 // <1.x would be the same as "<1.0.0-0", though.
144 src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$';
145 var XRANGELOOSE = R++;
146 src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$';
149 // Meaning is "reasonably at or greater than"
151 src[LONETILDE] = '(?:~>?)';
154 src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+';
155 re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g');
156 var tildeTrimReplace = '$1~';
159 src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$';
160 var TILDELOOSE = R++;
161 src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$';
164 // Meaning is "at least and backwards compatible with"
166 src[LONECARET] = '(?:\\^)';
169 src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+';
170 re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g');
171 var caretTrimReplace = '$1^';
174 src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$';
175 var CARETLOOSE = R++;
176 src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$';
178 // A simple gt/lt/eq thing, or just "" to indicate "any version"
179 var COMPARATORLOOSE = R++;
180 src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$';
181 var COMPARATOR = R++;
182 src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$';
185 // An expression to strip any whitespace between the gtlt and the thing
186 // it modifies, so that `> 1.2.3` ==> `>1.2.3`
187 var COMPARATORTRIM = R++;
188 src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
189 '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')';
191 // this one has to use the /g flag
192 re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g');
193 var comparatorTrimReplace = '$1$2$3';
196 // Something like `1.2.3 - 1.2.4`
197 // Note that these all use the loose form, because they'll be
198 // checked against either the strict or loose comparator form
200 var HYPHENRANGE = R++;
201 src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
203 '(' + src[XRANGEPLAIN] + ')' +
206 var HYPHENRANGELOOSE = R++;
207 src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
209 '(' + src[XRANGEPLAINLOOSE] + ')' +
212 // Star ranges basically just allow anything at all.
214 src[STAR] = '(<|>)?=?\\s*\\*';
216 // Compile to actual regexp objects.
217 // All are flag-free, unless they were created above with a flag.
218 for (var i = 0; i < R; i++) {
221 re[i] = new RegExp(src[i]);
224 exports.parse = parse;
225 function parse(version, loose) {
226 var r = loose ? re[LOOSE] : re[FULL];
227 return (r.test(version)) ? new SemVer(version, loose) : null;
230 exports.valid = valid;
231 function valid(version, loose) {
232 var v = parse(version, loose);
233 return v ? v.version : null;
237 exports.clean = clean;
238 function clean(version, loose) {
239 var s = parse(version, loose);
240 return s ? s.version : null;
243 exports.SemVer = SemVer;
245 function SemVer(version, loose) {
246 if (version instanceof SemVer) {
247 if (version.loose === loose)
250 version = version.version;
251 } else if (typeof version !== 'string') {
252 throw new TypeError('Invalid Version: ' + version);
255 if (!(this instanceof SemVer))
256 return new SemVer(version, loose);
260 var m = version.trim().match(loose ? re[LOOSE] : re[FULL]);
263 throw new TypeError('Invalid Version: ' + version);
267 // these are actually numbers
272 // numberify any prerelease numeric ids
274 this.prerelease = [];
276 this.prerelease = m[4].split('.').map(function(id) {
277 return (/^[0-9]+$/.test(id)) ? +id : id;
280 this.build = m[5] ? m[5].split('.') : [];
284 SemVer.prototype.format = function() {
285 this.version = this.major + '.' + this.minor + '.' + this.patch;
286 if (this.prerelease.length)
287 this.version += '-' + this.prerelease.join('.');
291 SemVer.prototype.inspect = function() {
292 return '<SemVer "' + this + '">';
295 SemVer.prototype.toString = function() {
299 SemVer.prototype.compare = function(other) {
301 if (!(other instanceof SemVer))
302 other = new SemVer(other, this.loose);
304 return this.compareMain(other) || this.comparePre(other);
307 SemVer.prototype.compareMain = function(other) {
308 if (!(other instanceof SemVer))
309 other = new SemVer(other, this.loose);
311 return compareIdentifiers(this.major, other.major) ||
312 compareIdentifiers(this.minor, other.minor) ||
313 compareIdentifiers(this.patch, other.patch);
316 SemVer.prototype.comparePre = function(other) {
317 if (!(other instanceof SemVer))
318 other = new SemVer(other, this.loose);
320 // NOT having a prerelease is > having one
321 if (this.prerelease.length && !other.prerelease.length)
323 else if (!this.prerelease.length && other.prerelease.length)
325 else if (!this.prerelease.length && !other.prerelease.length)
330 var a = this.prerelease[i];
331 var b = other.prerelease[i];
333 if (a === undefined && b === undefined)
335 else if (b === undefined)
337 else if (a === undefined)
342 return compareIdentifiers(a, b);
346 // preminor will bump the version up to the next minor release, and immediately
347 // down to pre-release. premajor and prepatch work the same way.
348 SemVer.prototype.inc = function(release) {
362 // If the input is a non-prerelease version, this acts the same as
365 if (this.prerelease.length === 0)
375 this.prerelease = [];
378 // If this is not a pre-release version, it will increment the patch.
379 // If it is a pre-release it will bump up to the same patch version.
380 // 1.2.0-5 patches to 1.2.0
381 // 1.2.0 patches to 1.2.1
382 if (this.prerelease.length === 0)
384 this.prerelease = [];
386 // This probably shouldn't be used publically.
387 // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
389 if (this.prerelease.length === 0)
390 this.prerelease = [0];
392 var i = this.prerelease.length;
394 if (typeof this.prerelease[i] === 'number') {
395 this.prerelease[i]++;
399 if (i === -1) // didn't increment anything
400 this.prerelease.push(0);
405 throw new Error('invalid increment argument: ' + release);
412 function inc(version, release, loose) {
414 return new SemVer(version, loose).inc(release).version;
420 exports.compareIdentifiers = compareIdentifiers;
422 var numeric = /^[0-9]+$/;
423 function compareIdentifiers(a, b) {
424 var anum = numeric.test(a);
425 var bnum = numeric.test(b);
432 return (anum && !bnum) ? -1 :
433 (bnum && !anum) ? 1 :
439 exports.rcompareIdentifiers = rcompareIdentifiers;
440 function rcompareIdentifiers(a, b) {
441 return compareIdentifiers(b, a);
444 exports.compare = compare;
445 function compare(a, b, loose) {
446 return new SemVer(a, loose).compare(b);
449 exports.compareLoose = compareLoose;
450 function compareLoose(a, b) {
451 return compare(a, b, true);
454 exports.rcompare = rcompare;
455 function rcompare(a, b, loose) {
456 return compare(b, a, loose);
460 function sort(list, loose) {
461 return list.sort(function(a, b) {
462 return exports.compare(a, b, loose);
466 exports.rsort = rsort;
467 function rsort(list, loose) {
468 return list.sort(function(a, b) {
469 return exports.rcompare(a, b, loose);
474 function gt(a, b, loose) {
475 return compare(a, b, loose) > 0;
479 function lt(a, b, loose) {
480 return compare(a, b, loose) < 0;
484 function eq(a, b, loose) {
485 return compare(a, b, loose) === 0;
489 function neq(a, b, loose) {
490 return compare(a, b, loose) !== 0;
494 function gte(a, b, loose) {
495 return compare(a, b, loose) >= 0;
499 function lte(a, b, loose) {
500 return compare(a, b, loose) <= 0;
504 function cmp(a, op, b, loose) {
507 case '===': ret = a === b; break;
508 case '!==': ret = a !== b; break;
509 case '': case '=': case '==': ret = eq(a, b, loose); break;
510 case '!=': ret = neq(a, b, loose); break;
511 case '>': ret = gt(a, b, loose); break;
512 case '>=': ret = gte(a, b, loose); break;
513 case '<': ret = lt(a, b, loose); break;
514 case '<=': ret = lte(a, b, loose); break;
515 default: throw new TypeError('Invalid operator: ' + op);
520 exports.Comparator = Comparator;
521 function Comparator(comp, loose) {
522 if (comp instanceof Comparator) {
523 if (comp.loose === loose)
529 if (!(this instanceof Comparator))
530 return new Comparator(comp, loose);
536 if (this.semver === ANY)
539 this.value = this.operator + this.semver.version;
543 Comparator.prototype.parse = function(comp) {
544 var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
545 var m = comp.match(r);
548 throw new TypeError('Invalid comparator: ' + comp);
550 this.operator = m[1];
551 // if it literally is just '>' or '' then allow anything.
555 this.semver = new SemVer(m[2], this.loose);
557 // <1.2.3-rc DOES allow 1.2.3-beta (has prerelease)
558 // >=1.2.3 DOES NOT allow 1.2.3-beta
559 // <=1.2.3 DOES allow 1.2.3-beta
560 // However, <1.2.3 does NOT allow 1.2.3-beta,
561 // even though `1.2.3-beta < 1.2.3`
562 // The assumption is that the 1.2.3 version has something you
563 // *don't* want, so we push the prerelease down to the minimum.
564 if (this.operator === '<' && !this.semver.prerelease.length) {
565 this.semver.prerelease = ['0'];
566 this.semver.format();
571 Comparator.prototype.inspect = function() {
572 return '<SemVer Comparator "' + this + '">';
575 Comparator.prototype.toString = function() {
579 Comparator.prototype.test = function(version) {
581 return (this.semver === ANY) ? true :
582 cmp(version, this.operator, this.semver, this.loose);
586 exports.Range = Range;
587 function Range(range, loose) {
588 if ((range instanceof Range) && range.loose === loose)
591 if (!(this instanceof Range))
592 return new Range(range, loose);
596 // First, split based on boolean or ||
598 this.set = range.split(/\s*\|\|\s*/).map(function(range) {
599 return this.parseRange(range.trim());
600 }, this).filter(function(c) {
601 // throw out any that are not relevant for whatever reason
605 if (!this.set.length) {
606 throw new TypeError('Invalid SemVer Range: ' + range);
612 Range.prototype.inspect = function() {
613 return '<SemVer Range "' + this.range + '">';
616 Range.prototype.format = function() {
617 this.range = this.set.map(function(comps) {
618 return comps.join(' ').trim();
619 }).join('||').trim();
623 Range.prototype.toString = function() {
627 Range.prototype.parseRange = function(range) {
628 var loose = this.loose;
629 range = range.trim();
631 // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
632 var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE];
633 range = range.replace(hr, hyphenReplace);
635 // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
636 range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace);
639 // `~ 1.2.3` => `~1.2.3`
640 range = range.replace(re[TILDETRIM], tildeTrimReplace);
642 // `^ 1.2.3` => `^1.2.3`
643 range = range.replace(re[CARETTRIM], caretTrimReplace);
646 range = range.split(/\s+/).join(' ');
648 // At this point, the range is completely trimmed and
649 // ready to be split into comparators.
651 var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
652 var set = range.split(' ').map(function(comp) {
653 return parseComparator(comp, loose);
654 }).join(' ').split(/\s+/);
656 // in loose mode, throw out any that are not valid comparators
657 set = set.filter(function(comp) {
658 return !!comp.match(compRe);
661 set = set.map(function(comp) {
662 return new Comparator(comp, loose);
668 // Mostly just for testing and legacy API reasons
669 exports.toComparators = toComparators;
670 function toComparators(range, loose) {
671 return new Range(range, loose).set.map(function(comp) {
672 return comp.map(function(c) {
674 }).join(' ').trim().split(' ');
678 // comprised of xranges, tildes, stars, and gtlt's at this point.
679 // already replaced the hyphen ranges
680 // turn into a set of JUST comparators.
681 function parseComparator(comp, loose) {
683 comp = replaceCarets(comp, loose);
685 comp = replaceTildes(comp, loose);
687 comp = replaceXRanges(comp, loose);
689 comp = replaceStars(comp, loose);
695 return !id || id.toLowerCase() === 'x' || id === '*';
698 // ~, ~> --> * (any, kinda silly)
699 // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
700 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
701 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
702 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
703 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
704 function replaceTildes(comp, loose) {
705 return comp.trim().split(/\s+/).map(function(comp) {
706 return replaceTilde(comp, loose);
710 function replaceTilde(comp, loose) {
711 var r = loose ? re[TILDELOOSE] : re[TILDE];
712 return comp.replace(r, function(_, M, m, p, pr) {
719 ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0';
721 // ~1.2 == >=1.2.0- <1.3.0-
722 ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0';
725 if (pr.charAt(0) !== '-')
727 ret = '>=' + M + '.' + m + '.' + p + pr +
728 ' <' + M + '.' + (+m + 1) + '.0-0';
730 // ~1.2.3 == >=1.2.3-0 <1.3.0-0
731 ret = '>=' + M + '.' + m + '.' + p + '-0' +
732 ' <' + M + '.' + (+m + 1) + '.0-0';
739 // ^ --> * (any, kinda silly)
740 // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
741 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
742 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
743 // ^1.2.3 --> >=1.2.3 <2.0.0
744 // ^1.2.0 --> >=1.2.0 <2.0.0
745 function replaceCarets(comp, loose) {
746 return comp.trim().split(/\s+/).map(function(comp) {
747 return replaceCaret(comp, loose);
751 function replaceCaret(comp, loose) {
752 var r = loose ? re[CARETLOOSE] : re[CARET];
753 return comp.replace(r, function(_, M, m, p, pr) {
760 ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0';
763 ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0';
765 ret = '>=' + M + '.' + m + '.0-0 <' + (+M + 1) + '.0.0-0';
768 if (pr.charAt(0) !== '-')
772 ret = '=' + M + '.' + m + '.' + p + pr;
774 ret = '>=' + M + '.' + m + '.' + p + pr +
775 ' <' + M + '.' + (+m + 1) + '.0-0';
777 ret = '>=' + M + '.' + m + '.' + p + pr +
778 ' <' + (+M + 1) + '.0.0-0';
782 ret = '=' + M + '.' + m + '.' + p;
784 ret = '>=' + M + '.' + m + '.' + p + '-0' +
785 ' <' + M + '.' + (+m + 1) + '.0-0';
787 ret = '>=' + M + '.' + m + '.' + p + '-0' +
788 ' <' + (+M + 1) + '.0.0-0';
796 function replaceXRanges(comp, loose) {
798 return comp.split(/\s+/).map(function(comp) {
799 return replaceXRange(comp, loose);
803 function replaceXRange(comp, loose) {
805 var r = loose ? re[XRANGELOOSE] : re[XRANGE];
806 return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
809 var xm = xM || isX(m);
810 var xp = xm || isX(p);
813 if (gtlt === '=' && anyX)
817 // replace X with 0, and then append the -0 min-prerelease
828 // >1.2.3 => >= 1.2.4-0
843 ret = gtlt + M + '.' + m + '.' + p + '-0';
848 // append '-0' onto the version, otherwise
849 // '1.x.x' matches '2.0.0-beta', since the tag
850 // *lowers* the version value
851 ret = '>=' + M + '.0.0-0 <' + (+M + 1) + '.0.0-0';
853 ret = '>=' + M + '.' + m + '.0-0 <' + M + '.' + (+m + 1) + '.0-0';
862 // Because * is AND-ed with everything else in the comparator,
863 // and '' means "any version", just remove the *s entirely.
864 function replaceStars(comp, loose) {
866 // Looseness is ignored here. star is always as loose as it gets!
867 return comp.trim().replace(re[STAR], '');
870 // This function is passed to string.replace(re[HYPHENRANGE])
871 // M, m, patch, prerelease, build
872 // 1.2 - 3.4.5 => >=1.2.0-0 <=3.4.5
873 // 1.2.3 - 3.4 => >=1.2.0-0 <3.5.0-0 Any 3.4.x will do
874 // 1.2 - 3.4 => >=1.2.0-0 <3.5.0-0
875 function hyphenReplace($0,
876 from, fM, fm, fp, fpr, fb,
877 to, tM, tm, tp, tpr, tb) {
882 from = '>=' + fM + '.0.0-0';
884 from = '>=' + fM + '.' + fm + '.0-0';
891 to = '<' + (+tM + 1) + '.0.0-0';
893 to = '<' + tM + '.' + (+tm + 1) + '.0-0';
895 to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr;
899 return (from + ' ' + to).trim();
903 // if ANY of the sets match ALL of its comparators, then pass
904 Range.prototype.test = function(version) {
907 for (var i = 0; i < this.set.length; i++) {
908 if (testSet(this.set[i], version))
914 function testSet(set, version) {
915 for (var i = 0; i < set.length; i++) {
916 if (!set[i].test(version))
922 exports.satisfies = satisfies;
923 function satisfies(version, range, loose) {
925 range = new Range(range, loose);
929 return range.test(version);
932 exports.maxSatisfying = maxSatisfying;
933 function maxSatisfying(versions, range, loose) {
934 return versions.filter(function(version) {
935 return satisfies(version, range, loose);
936 }).sort(function(a, b) {
937 return rcompare(a, b, loose);
941 exports.validRange = validRange;
942 function validRange(range, loose) {
944 // Return '*' instead of '' so that truthiness works.
945 // This will throw if it's invalid anyway
946 return new Range(range, loose).range || '*';
952 // Determine if version is less than all the versions possible in the range
954 function ltr(version, range, loose) {
955 return outside(version, range, '<', loose);
958 // Determine if version is greater than all the versions possible in the range.
960 function gtr(version, range, loose) {
961 return outside(version, range, '>', loose);
964 exports.outside = outside;
965 function outside(version, range, hilo, loose) {
966 version = new SemVer(version, loose);
967 range = new Range(range, loose);
969 var gtfn, ltefn, ltfn, comp, ecomp;
986 throw new TypeError('Must provide a hilo val of "<" or ">"');
989 // If it satisifes the range it is not outside
990 if (satisfies(version, range, loose)) {
994 // From now on, variable terms are as if we're in "gtr" mode.
995 // but note that everything is flipped for the "ltr" function.
997 for (var i = 0; i < range.set.length; ++i) {
998 var comparators = range.set[i];
1003 comparators.forEach(function(comparator) {
1004 high = high || comparator;
1005 low = low || comparator;
1006 if (gtfn(comparator.semver, high.semver, loose)) {
1008 } else if (ltfn(comparator.semver, low.semver, loose)) {
1013 // If the edge version comparator has a operator then our version
1015 if (high.operator === comp || high.operator === ecomp) {
1019 // If the lowest version comparator has an operator and our version
1020 // is less than it then it isn't higher than the range
1021 if ((!low.operator || low.operator === comp) &&
1022 ltefn(version, low.semver)) {
1024 } else if (low.operator === ecomp && ltfn(version, low.semver)) {
1031 // Use the define() function if we're in AMD land
1032 if (typeof define === 'function' && define.amd)
1036 typeof exports === 'object' ? exports :
1037 typeof define === 'function' && define.amd ? {} :