Projekt

Obecné

Profil

Stáhnout (37.9 KB) Statistiky
| Větev: | Revize:
1
exports = module.exports = SemVer
2

    
3
var debug
4
/* istanbul ignore next */
5
if (typeof process === 'object' &&
6
    process.env &&
7
    process.env.NODE_DEBUG &&
8
    /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
9
  debug = function () {
10
    var args = Array.prototype.slice.call(arguments, 0)
11
    args.unshift('SEMVER')
12
    console.log.apply(console, args)
13
  }
14
} else {
15
  debug = function () {}
16
}
17

    
18
// Note: this is the semver.org version of the spec that it implements
19
// Not necessarily the package version of this code.
20
exports.SEMVER_SPEC_VERSION = '2.0.0'
21

    
22
var MAX_LENGTH = 256
23
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
24
  /* istanbul ignore next */ 9007199254740991
25

    
26
// Max safe segment length for coercion.
27
var MAX_SAFE_COMPONENT_LENGTH = 16
28

    
29
// The actual regexps go on exports.re
30
var re = exports.re = []
31
var src = exports.src = []
32
var R = 0
33

    
34
// The following Regular Expressions can be used for tokenizing,
35
// validating, and parsing SemVer version strings.
36

    
37
// ## Numeric Identifier
38
// A single `0`, or a non-zero digit followed by zero or more digits.
39

    
40
var NUMERICIDENTIFIER = R++
41
src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'
42
var NUMERICIDENTIFIERLOOSE = R++
43
src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'
44

    
45
// ## Non-numeric Identifier
46
// Zero or more digits, followed by a letter or hyphen, and then zero or
47
// more letters, digits, or hyphens.
48

    
49
var NONNUMERICIDENTIFIER = R++
50
src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'
51

    
52
// ## Main Version
53
// Three dot-separated numeric identifiers.
54

    
55
var MAINVERSION = R++
56
src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' +
57
                   '(' + src[NUMERICIDENTIFIER] + ')\\.' +
58
                   '(' + src[NUMERICIDENTIFIER] + ')'
59

    
60
var MAINVERSIONLOOSE = R++
61
src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
62
                        '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' +
63
                        '(' + src[NUMERICIDENTIFIERLOOSE] + ')'
64

    
65
// ## Pre-release Version Identifier
66
// A numeric identifier, or a non-numeric identifier.
67

    
68
var PRERELEASEIDENTIFIER = R++
69
src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] +
70
                            '|' + src[NONNUMERICIDENTIFIER] + ')'
71

    
72
var PRERELEASEIDENTIFIERLOOSE = R++
73
src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] +
74
                                 '|' + src[NONNUMERICIDENTIFIER] + ')'
75

    
76
// ## Pre-release Version
77
// Hyphen, followed by one or more dot-separated pre-release version
78
// identifiers.
79

    
80
var PRERELEASE = R++
81
src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] +
82
                  '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'
83

    
84
var PRERELEASELOOSE = R++
85
src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] +
86
                       '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'
87

    
88
// ## Build Metadata Identifier
89
// Any combination of digits, letters, or hyphens.
90

    
91
var BUILDIDENTIFIER = R++
92
src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'
93

    
94
// ## Build Metadata
95
// Plus sign, followed by one or more period-separated build metadata
96
// identifiers.
97

    
98
var BUILD = R++
99
src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] +
100
             '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'
101

    
102
// ## Full Version String
103
// A main version, followed optionally by a pre-release version and
104
// build metadata.
105

    
106
// Note that the only major, minor, patch, and pre-release sections of
107
// the version string are capturing groups.  The build metadata is not a
108
// capturing group, because it should not ever be used in version
109
// comparison.
110

    
111
var FULL = R++
112
var FULLPLAIN = 'v?' + src[MAINVERSION] +
113
                src[PRERELEASE] + '?' +
114
                src[BUILD] + '?'
115

    
116
src[FULL] = '^' + FULLPLAIN + '$'
117

    
118
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
119
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
120
// common in the npm registry.
121
var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] +
122
                 src[PRERELEASELOOSE] + '?' +
123
                 src[BUILD] + '?'
124

    
125
var LOOSE = R++
126
src[LOOSE] = '^' + LOOSEPLAIN + '$'
127

    
128
var GTLT = R++
129
src[GTLT] = '((?:<|>)?=?)'
130

    
131
// Something like "2.*" or "1.2.x".
132
// Note that "x.x" is a valid xRange identifer, meaning "any version"
133
// Only the first item is strictly required.
134
var XRANGEIDENTIFIERLOOSE = R++
135
src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'
136
var XRANGEIDENTIFIER = R++
137
src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'
138

    
139
var XRANGEPLAIN = R++
140
src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' +
141
                   '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
142
                   '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' +
143
                   '(?:' + src[PRERELEASE] + ')?' +
144
                   src[BUILD] + '?' +
145
                   ')?)?'
146

    
147
var XRANGEPLAINLOOSE = R++
148
src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
149
                        '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
150
                        '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' +
151
                        '(?:' + src[PRERELEASELOOSE] + ')?' +
152
                        src[BUILD] + '?' +
153
                        ')?)?'
154

    
155
var XRANGE = R++
156
src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'
157
var XRANGELOOSE = R++
158
src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'
159

    
160
// Coercion.
161
// Extract anything that could conceivably be a part of a valid semver
162
var COERCE = R++
163
src[COERCE] = '(?:^|[^\\d])' +
164
              '(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '})' +
165
              '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
166
              '(?:\\.(\\d{1,' + MAX_SAFE_COMPONENT_LENGTH + '}))?' +
167
              '(?:$|[^\\d])'
168

    
169
// Tilde ranges.
170
// Meaning is "reasonably at or greater than"
171
var LONETILDE = R++
172
src[LONETILDE] = '(?:~>?)'
173

    
174
var TILDETRIM = R++
175
src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'
176
re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g')
177
var tildeTrimReplace = '$1~'
178

    
179
var TILDE = R++
180
src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'
181
var TILDELOOSE = R++
182
src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'
183

    
184
// Caret ranges.
185
// Meaning is "at least and backwards compatible with"
186
var LONECARET = R++
187
src[LONECARET] = '(?:\\^)'
188

    
189
var CARETTRIM = R++
190
src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'
191
re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g')
192
var caretTrimReplace = '$1^'
193

    
194
var CARET = R++
195
src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'
196
var CARETLOOSE = R++
197
src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'
198

    
199
// A simple gt/lt/eq thing, or just "" to indicate "any version"
200
var COMPARATORLOOSE = R++
201
src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'
202
var COMPARATOR = R++
203
src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'
204

    
205
// An expression to strip any whitespace between the gtlt and the thing
206
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
207
var COMPARATORTRIM = R++
208
src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] +
209
                      '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'
210

    
211
// this one has to use the /g flag
212
re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g')
213
var comparatorTrimReplace = '$1$2$3'
214

    
215
// Something like `1.2.3 - 1.2.4`
216
// Note that these all use the loose form, because they'll be
217
// checked against either the strict or loose comparator form
218
// later.
219
var HYPHENRANGE = R++
220
src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' +
221
                   '\\s+-\\s+' +
222
                   '(' + src[XRANGEPLAIN] + ')' +
223
                   '\\s*$'
224

    
225
var HYPHENRANGELOOSE = R++
226
src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' +
227
                        '\\s+-\\s+' +
228
                        '(' + src[XRANGEPLAINLOOSE] + ')' +
229
                        '\\s*$'
230

    
231
// Star ranges basically just allow anything at all.
232
var STAR = R++
233
src[STAR] = '(<|>)?=?\\s*\\*'
234

    
235
// Compile to actual regexp objects.
236
// All are flag-free, unless they were created above with a flag.
237
for (var i = 0; i < R; i++) {
238
  debug(i, src[i])
239
  if (!re[i]) {
240
    re[i] = new RegExp(src[i])
241
  }
242
}
243

    
244
exports.parse = parse
245
function parse (version, options) {
246
  if (!options || typeof options !== 'object') {
247
    options = {
248
      loose: !!options,
249
      includePrerelease: false
250
    }
251
  }
252

    
253
  if (version instanceof SemVer) {
254
    return version
255
  }
256

    
257
  if (typeof version !== 'string') {
258
    return null
259
  }
260

    
261
  if (version.length > MAX_LENGTH) {
262
    return null
263
  }
264

    
265
  var r = options.loose ? re[LOOSE] : re[FULL]
266
  if (!r.test(version)) {
267
    return null
268
  }
269

    
270
  try {
271
    return new SemVer(version, options)
272
  } catch (er) {
273
    return null
274
  }
275
}
276

    
277
exports.valid = valid
278
function valid (version, options) {
279
  var v = parse(version, options)
280
  return v ? v.version : null
281
}
282

    
283
exports.clean = clean
284
function clean (version, options) {
285
  var s = parse(version.trim().replace(/^[=v]+/, ''), options)
286
  return s ? s.version : null
287
}
288

    
289
exports.SemVer = SemVer
290

    
291
function SemVer (version, options) {
292
  if (!options || typeof options !== 'object') {
293
    options = {
294
      loose: !!options,
295
      includePrerelease: false
296
    }
297
  }
298
  if (version instanceof SemVer) {
299
    if (version.loose === options.loose) {
300
      return version
301
    } else {
302
      version = version.version
303
    }
304
  } else if (typeof version !== 'string') {
305
    throw new TypeError('Invalid Version: ' + version)
306
  }
307

    
308
  if (version.length > MAX_LENGTH) {
309
    throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters')
310
  }
311

    
312
  if (!(this instanceof SemVer)) {
313
    return new SemVer(version, options)
314
  }
315

    
316
  debug('SemVer', version, options)
317
  this.options = options
318
  this.loose = !!options.loose
319

    
320
  var m = version.trim().match(options.loose ? re[LOOSE] : re[FULL])
321

    
322
  if (!m) {
323
    throw new TypeError('Invalid Version: ' + version)
324
  }
325

    
326
  this.raw = version
327

    
328
  // these are actually numbers
329
  this.major = +m[1]
330
  this.minor = +m[2]
331
  this.patch = +m[3]
332

    
333
  if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
334
    throw new TypeError('Invalid major version')
335
  }
336

    
337
  if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
338
    throw new TypeError('Invalid minor version')
339
  }
340

    
341
  if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
342
    throw new TypeError('Invalid patch version')
343
  }
344

    
345
  // numberify any prerelease numeric ids
346
  if (!m[4]) {
347
    this.prerelease = []
348
  } else {
349
    this.prerelease = m[4].split('.').map(function (id) {
350
      if (/^[0-9]+$/.test(id)) {
351
        var num = +id
352
        if (num >= 0 && num < MAX_SAFE_INTEGER) {
353
          return num
354
        }
355
      }
356
      return id
357
    })
358
  }
359

    
360
  this.build = m[5] ? m[5].split('.') : []
361
  this.format()
362
}
363

    
364
SemVer.prototype.format = function () {
365
  this.version = this.major + '.' + this.minor + '.' + this.patch
366
  if (this.prerelease.length) {
367
    this.version += '-' + this.prerelease.join('.')
368
  }
369
  return this.version
370
}
371

    
372
SemVer.prototype.toString = function () {
373
  return this.version
374
}
375

    
376
SemVer.prototype.compare = function (other) {
377
  debug('SemVer.compare', this.version, this.options, other)
378
  if (!(other instanceof SemVer)) {
379
    other = new SemVer(other, this.options)
380
  }
381

    
382
  return this.compareMain(other) || this.comparePre(other)
383
}
384

    
385
SemVer.prototype.compareMain = function (other) {
386
  if (!(other instanceof SemVer)) {
387
    other = new SemVer(other, this.options)
388
  }
389

    
390
  return compareIdentifiers(this.major, other.major) ||
391
         compareIdentifiers(this.minor, other.minor) ||
392
         compareIdentifiers(this.patch, other.patch)
393
}
394

    
395
SemVer.prototype.comparePre = function (other) {
396
  if (!(other instanceof SemVer)) {
397
    other = new SemVer(other, this.options)
398
  }
399

    
400
  // NOT having a prerelease is > having one
401
  if (this.prerelease.length && !other.prerelease.length) {
402
    return -1
403
  } else if (!this.prerelease.length && other.prerelease.length) {
404
    return 1
405
  } else if (!this.prerelease.length && !other.prerelease.length) {
406
    return 0
407
  }
408

    
409
  var i = 0
410
  do {
411
    var a = this.prerelease[i]
412
    var b = other.prerelease[i]
413
    debug('prerelease compare', i, a, b)
414
    if (a === undefined && b === undefined) {
415
      return 0
416
    } else if (b === undefined) {
417
      return 1
418
    } else if (a === undefined) {
419
      return -1
420
    } else if (a === b) {
421
      continue
422
    } else {
423
      return compareIdentifiers(a, b)
424
    }
425
  } while (++i)
426
}
427

    
428
// preminor will bump the version up to the next minor release, and immediately
429
// down to pre-release. premajor and prepatch work the same way.
430
SemVer.prototype.inc = function (release, identifier) {
431
  switch (release) {
432
    case 'premajor':
433
      this.prerelease.length = 0
434
      this.patch = 0
435
      this.minor = 0
436
      this.major++
437
      this.inc('pre', identifier)
438
      break
439
    case 'preminor':
440
      this.prerelease.length = 0
441
      this.patch = 0
442
      this.minor++
443
      this.inc('pre', identifier)
444
      break
445
    case 'prepatch':
446
      // If this is already a prerelease, it will bump to the next version
447
      // drop any prereleases that might already exist, since they are not
448
      // relevant at this point.
449
      this.prerelease.length = 0
450
      this.inc('patch', identifier)
451
      this.inc('pre', identifier)
452
      break
453
    // If the input is a non-prerelease version, this acts the same as
454
    // prepatch.
455
    case 'prerelease':
456
      if (this.prerelease.length === 0) {
457
        this.inc('patch', identifier)
458
      }
459
      this.inc('pre', identifier)
460
      break
461

    
462
    case 'major':
463
      // If this is a pre-major version, bump up to the same major version.
464
      // Otherwise increment major.
465
      // 1.0.0-5 bumps to 1.0.0
466
      // 1.1.0 bumps to 2.0.0
467
      if (this.minor !== 0 ||
468
          this.patch !== 0 ||
469
          this.prerelease.length === 0) {
470
        this.major++
471
      }
472
      this.minor = 0
473
      this.patch = 0
474
      this.prerelease = []
475
      break
476
    case 'minor':
477
      // If this is a pre-minor version, bump up to the same minor version.
478
      // Otherwise increment minor.
479
      // 1.2.0-5 bumps to 1.2.0
480
      // 1.2.1 bumps to 1.3.0
481
      if (this.patch !== 0 || this.prerelease.length === 0) {
482
        this.minor++
483
      }
484
      this.patch = 0
485
      this.prerelease = []
486
      break
487
    case 'patch':
488
      // If this is not a pre-release version, it will increment the patch.
489
      // If it is a pre-release it will bump up to the same patch version.
490
      // 1.2.0-5 patches to 1.2.0
491
      // 1.2.0 patches to 1.2.1
492
      if (this.prerelease.length === 0) {
493
        this.patch++
494
      }
495
      this.prerelease = []
496
      break
497
    // This probably shouldn't be used publicly.
498
    // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction.
499
    case 'pre':
500
      if (this.prerelease.length === 0) {
501
        this.prerelease = [0]
502
      } else {
503
        var i = this.prerelease.length
504
        while (--i >= 0) {
505
          if (typeof this.prerelease[i] === 'number') {
506
            this.prerelease[i]++
507
            i = -2
508
          }
509
        }
510
        if (i === -1) {
511
          // didn't increment anything
512
          this.prerelease.push(0)
513
        }
514
      }
515
      if (identifier) {
516
        // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
517
        // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
518
        if (this.prerelease[0] === identifier) {
519
          if (isNaN(this.prerelease[1])) {
520
            this.prerelease = [identifier, 0]
521
          }
522
        } else {
523
          this.prerelease = [identifier, 0]
524
        }
525
      }
526
      break
527

    
528
    default:
529
      throw new Error('invalid increment argument: ' + release)
530
  }
531
  this.format()
532
  this.raw = this.version
533
  return this
534
}
535

    
536
exports.inc = inc
537
function inc (version, release, loose, identifier) {
538
  if (typeof (loose) === 'string') {
539
    identifier = loose
540
    loose = undefined
541
  }
542

    
543
  try {
544
    return new SemVer(version, loose).inc(release, identifier).version
545
  } catch (er) {
546
    return null
547
  }
548
}
549

    
550
exports.diff = diff
551
function diff (version1, version2) {
552
  if (eq(version1, version2)) {
553
    return null
554
  } else {
555
    var v1 = parse(version1)
556
    var v2 = parse(version2)
557
    var prefix = ''
558
    if (v1.prerelease.length || v2.prerelease.length) {
559
      prefix = 'pre'
560
      var defaultResult = 'prerelease'
561
    }
562
    for (var key in v1) {
563
      if (key === 'major' || key === 'minor' || key === 'patch') {
564
        if (v1[key] !== v2[key]) {
565
          return prefix + key
566
        }
567
      }
568
    }
569
    return defaultResult // may be undefined
570
  }
571
}
572

    
573
exports.compareIdentifiers = compareIdentifiers
574

    
575
var numeric = /^[0-9]+$/
576
function compareIdentifiers (a, b) {
577
  var anum = numeric.test(a)
578
  var bnum = numeric.test(b)
579

    
580
  if (anum && bnum) {
581
    a = +a
582
    b = +b
583
  }
584

    
585
  return a === b ? 0
586
    : (anum && !bnum) ? -1
587
    : (bnum && !anum) ? 1
588
    : a < b ? -1
589
    : 1
590
}
591

    
592
exports.rcompareIdentifiers = rcompareIdentifiers
593
function rcompareIdentifiers (a, b) {
594
  return compareIdentifiers(b, a)
595
}
596

    
597
exports.major = major
598
function major (a, loose) {
599
  return new SemVer(a, loose).major
600
}
601

    
602
exports.minor = minor
603
function minor (a, loose) {
604
  return new SemVer(a, loose).minor
605
}
606

    
607
exports.patch = patch
608
function patch (a, loose) {
609
  return new SemVer(a, loose).patch
610
}
611

    
612
exports.compare = compare
613
function compare (a, b, loose) {
614
  return new SemVer(a, loose).compare(new SemVer(b, loose))
615
}
616

    
617
exports.compareLoose = compareLoose
618
function compareLoose (a, b) {
619
  return compare(a, b, true)
620
}
621

    
622
exports.rcompare = rcompare
623
function rcompare (a, b, loose) {
624
  return compare(b, a, loose)
625
}
626

    
627
exports.sort = sort
628
function sort (list, loose) {
629
  return list.sort(function (a, b) {
630
    return exports.compare(a, b, loose)
631
  })
632
}
633

    
634
exports.rsort = rsort
635
function rsort (list, loose) {
636
  return list.sort(function (a, b) {
637
    return exports.rcompare(a, b, loose)
638
  })
639
}
640

    
641
exports.gt = gt
642
function gt (a, b, loose) {
643
  return compare(a, b, loose) > 0
644
}
645

    
646
exports.lt = lt
647
function lt (a, b, loose) {
648
  return compare(a, b, loose) < 0
649
}
650

    
651
exports.eq = eq
652
function eq (a, b, loose) {
653
  return compare(a, b, loose) === 0
654
}
655

    
656
exports.neq = neq
657
function neq (a, b, loose) {
658
  return compare(a, b, loose) !== 0
659
}
660

    
661
exports.gte = gte
662
function gte (a, b, loose) {
663
  return compare(a, b, loose) >= 0
664
}
665

    
666
exports.lte = lte
667
function lte (a, b, loose) {
668
  return compare(a, b, loose) <= 0
669
}
670

    
671
exports.cmp = cmp
672
function cmp (a, op, b, loose) {
673
  switch (op) {
674
    case '===':
675
      if (typeof a === 'object')
676
        a = a.version
677
      if (typeof b === 'object')
678
        b = b.version
679
      return a === b
680

    
681
    case '!==':
682
      if (typeof a === 'object')
683
        a = a.version
684
      if (typeof b === 'object')
685
        b = b.version
686
      return a !== b
687

    
688
    case '':
689
    case '=':
690
    case '==':
691
      return eq(a, b, loose)
692

    
693
    case '!=':
694
      return neq(a, b, loose)
695

    
696
    case '>':
697
      return gt(a, b, loose)
698

    
699
    case '>=':
700
      return gte(a, b, loose)
701

    
702
    case '<':
703
      return lt(a, b, loose)
704

    
705
    case '<=':
706
      return lte(a, b, loose)
707

    
708
    default:
709
      throw new TypeError('Invalid operator: ' + op)
710
  }
711
}
712

    
713
exports.Comparator = Comparator
714
function Comparator (comp, options) {
715
  if (!options || typeof options !== 'object') {
716
    options = {
717
      loose: !!options,
718
      includePrerelease: false
719
    }
720
  }
721

    
722
  if (comp instanceof Comparator) {
723
    if (comp.loose === !!options.loose) {
724
      return comp
725
    } else {
726
      comp = comp.value
727
    }
728
  }
729

    
730
  if (!(this instanceof Comparator)) {
731
    return new Comparator(comp, options)
732
  }
733

    
734
  debug('comparator', comp, options)
735
  this.options = options
736
  this.loose = !!options.loose
737
  this.parse(comp)
738

    
739
  if (this.semver === ANY) {
740
    this.value = ''
741
  } else {
742
    this.value = this.operator + this.semver.version
743
  }
744

    
745
  debug('comp', this)
746
}
747

    
748
var ANY = {}
749
Comparator.prototype.parse = function (comp) {
750
  var r = this.options.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]
751
  var m = comp.match(r)
752

    
753
  if (!m) {
754
    throw new TypeError('Invalid comparator: ' + comp)
755
  }
756

    
757
  this.operator = m[1]
758
  if (this.operator === '=') {
759
    this.operator = ''
760
  }
761

    
762
  // if it literally is just '>' or '' then allow anything.
763
  if (!m[2]) {
764
    this.semver = ANY
765
  } else {
766
    this.semver = new SemVer(m[2], this.options.loose)
767
  }
768
}
769

    
770
Comparator.prototype.toString = function () {
771
  return this.value
772
}
773

    
774
Comparator.prototype.test = function (version) {
775
  debug('Comparator.test', version, this.options.loose)
776

    
777
  if (this.semver === ANY) {
778
    return true
779
  }
780

    
781
  if (typeof version === 'string') {
782
    version = new SemVer(version, this.options)
783
  }
784

    
785
  return cmp(version, this.operator, this.semver, this.options)
786
}
787

    
788
Comparator.prototype.intersects = function (comp, options) {
789
  if (!(comp instanceof Comparator)) {
790
    throw new TypeError('a Comparator is required')
791
  }
792

    
793
  if (!options || typeof options !== 'object') {
794
    options = {
795
      loose: !!options,
796
      includePrerelease: false
797
    }
798
  }
799

    
800
  var rangeTmp
801

    
802
  if (this.operator === '') {
803
    rangeTmp = new Range(comp.value, options)
804
    return satisfies(this.value, rangeTmp, options)
805
  } else if (comp.operator === '') {
806
    rangeTmp = new Range(this.value, options)
807
    return satisfies(comp.semver, rangeTmp, options)
808
  }
809

    
810
  var sameDirectionIncreasing =
811
    (this.operator === '>=' || this.operator === '>') &&
812
    (comp.operator === '>=' || comp.operator === '>')
813
  var sameDirectionDecreasing =
814
    (this.operator === '<=' || this.operator === '<') &&
815
    (comp.operator === '<=' || comp.operator === '<')
816
  var sameSemVer = this.semver.version === comp.semver.version
817
  var differentDirectionsInclusive =
818
    (this.operator === '>=' || this.operator === '<=') &&
819
    (comp.operator === '>=' || comp.operator === '<=')
820
  var oppositeDirectionsLessThan =
821
    cmp(this.semver, '<', comp.semver, options) &&
822
    ((this.operator === '>=' || this.operator === '>') &&
823
    (comp.operator === '<=' || comp.operator === '<'))
824
  var oppositeDirectionsGreaterThan =
825
    cmp(this.semver, '>', comp.semver, options) &&
826
    ((this.operator === '<=' || this.operator === '<') &&
827
    (comp.operator === '>=' || comp.operator === '>'))
828

    
829
  return sameDirectionIncreasing || sameDirectionDecreasing ||
830
    (sameSemVer && differentDirectionsInclusive) ||
831
    oppositeDirectionsLessThan || oppositeDirectionsGreaterThan
832
}
833

    
834
exports.Range = Range
835
function Range (range, options) {
836
  if (!options || typeof options !== 'object') {
837
    options = {
838
      loose: !!options,
839
      includePrerelease: false
840
    }
841
  }
842

    
843
  if (range instanceof Range) {
844
    if (range.loose === !!options.loose &&
845
        range.includePrerelease === !!options.includePrerelease) {
846
      return range
847
    } else {
848
      return new Range(range.raw, options)
849
    }
850
  }
851

    
852
  if (range instanceof Comparator) {
853
    return new Range(range.value, options)
854
  }
855

    
856
  if (!(this instanceof Range)) {
857
    return new Range(range, options)
858
  }
859

    
860
  this.options = options
861
  this.loose = !!options.loose
862
  this.includePrerelease = !!options.includePrerelease
863

    
864
  // First, split based on boolean or ||
865
  this.raw = range
866
  this.set = range.split(/\s*\|\|\s*/).map(function (range) {
867
    return this.parseRange(range.trim())
868
  }, this).filter(function (c) {
869
    // throw out any that are not relevant for whatever reason
870
    return c.length
871
  })
872

    
873
  if (!this.set.length) {
874
    throw new TypeError('Invalid SemVer Range: ' + range)
875
  }
876

    
877
  this.format()
878
}
879

    
880
Range.prototype.format = function () {
881
  this.range = this.set.map(function (comps) {
882
    return comps.join(' ').trim()
883
  }).join('||').trim()
884
  return this.range
885
}
886

    
887
Range.prototype.toString = function () {
888
  return this.range
889
}
890

    
891
Range.prototype.parseRange = function (range) {
892
  var loose = this.options.loose
893
  range = range.trim()
894
  // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4`
895
  var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]
896
  range = range.replace(hr, hyphenReplace)
897
  debug('hyphen replace', range)
898
  // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
899
  range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace)
900
  debug('comparator trim', range, re[COMPARATORTRIM])
901

    
902
  // `~ 1.2.3` => `~1.2.3`
903
  range = range.replace(re[TILDETRIM], tildeTrimReplace)
904

    
905
  // `^ 1.2.3` => `^1.2.3`
906
  range = range.replace(re[CARETTRIM], caretTrimReplace)
907

    
908
  // normalize spaces
909
  range = range.split(/\s+/).join(' ')
910

    
911
  // At this point, the range is completely trimmed and
912
  // ready to be split into comparators.
913

    
914
  var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]
915
  var set = range.split(' ').map(function (comp) {
916
    return parseComparator(comp, this.options)
917
  }, this).join(' ').split(/\s+/)
918
  if (this.options.loose) {
919
    // in loose mode, throw out any that are not valid comparators
920
    set = set.filter(function (comp) {
921
      return !!comp.match(compRe)
922
    })
923
  }
924
  set = set.map(function (comp) {
925
    return new Comparator(comp, this.options)
926
  }, this)
927

    
928
  return set
929
}
930

    
931
Range.prototype.intersects = function (range, options) {
932
  if (!(range instanceof Range)) {
933
    throw new TypeError('a Range is required')
934
  }
935

    
936
  return this.set.some(function (thisComparators) {
937
    return thisComparators.every(function (thisComparator) {
938
      return range.set.some(function (rangeComparators) {
939
        return rangeComparators.every(function (rangeComparator) {
940
          return thisComparator.intersects(rangeComparator, options)
941
        })
942
      })
943
    })
944
  })
945
}
946

    
947
// Mostly just for testing and legacy API reasons
948
exports.toComparators = toComparators
949
function toComparators (range, options) {
950
  return new Range(range, options).set.map(function (comp) {
951
    return comp.map(function (c) {
952
      return c.value
953
    }).join(' ').trim().split(' ')
954
  })
955
}
956

    
957
// comprised of xranges, tildes, stars, and gtlt's at this point.
958
// already replaced the hyphen ranges
959
// turn into a set of JUST comparators.
960
function parseComparator (comp, options) {
961
  debug('comp', comp, options)
962
  comp = replaceCarets(comp, options)
963
  debug('caret', comp)
964
  comp = replaceTildes(comp, options)
965
  debug('tildes', comp)
966
  comp = replaceXRanges(comp, options)
967
  debug('xrange', comp)
968
  comp = replaceStars(comp, options)
969
  debug('stars', comp)
970
  return comp
971
}
972

    
973
function isX (id) {
974
  return !id || id.toLowerCase() === 'x' || id === '*'
975
}
976

    
977
// ~, ~> --> * (any, kinda silly)
978
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0
979
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0
980
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0
981
// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0
982
// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0
983
function replaceTildes (comp, options) {
984
  return comp.trim().split(/\s+/).map(function (comp) {
985
    return replaceTilde(comp, options)
986
  }).join(' ')
987
}
988

    
989
function replaceTilde (comp, options) {
990
  var r = options.loose ? re[TILDELOOSE] : re[TILDE]
991
  return comp.replace(r, function (_, M, m, p, pr) {
992
    debug('tilde', comp, _, M, m, p, pr)
993
    var ret
994

    
995
    if (isX(M)) {
996
      ret = ''
997
    } else if (isX(m)) {
998
      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
999
    } else if (isX(p)) {
1000
      // ~1.2 == >=1.2.0 <1.3.0
1001
      ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
1002
    } else if (pr) {
1003
      debug('replaceTilde pr', pr)
1004
      ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
1005
            ' <' + M + '.' + (+m + 1) + '.0'
1006
    } else {
1007
      // ~1.2.3 == >=1.2.3 <1.3.0
1008
      ret = '>=' + M + '.' + m + '.' + p +
1009
            ' <' + M + '.' + (+m + 1) + '.0'
1010
    }
1011

    
1012
    debug('tilde return', ret)
1013
    return ret
1014
  })
1015
}
1016

    
1017
// ^ --> * (any, kinda silly)
1018
// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0
1019
// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0
1020
// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0
1021
// ^1.2.3 --> >=1.2.3 <2.0.0
1022
// ^1.2.0 --> >=1.2.0 <2.0.0
1023
function replaceCarets (comp, options) {
1024
  return comp.trim().split(/\s+/).map(function (comp) {
1025
    return replaceCaret(comp, options)
1026
  }).join(' ')
1027
}
1028

    
1029
function replaceCaret (comp, options) {
1030
  debug('caret', comp, options)
1031
  var r = options.loose ? re[CARETLOOSE] : re[CARET]
1032
  return comp.replace(r, function (_, M, m, p, pr) {
1033
    debug('caret', comp, _, M, m, p, pr)
1034
    var ret
1035

    
1036
    if (isX(M)) {
1037
      ret = ''
1038
    } else if (isX(m)) {
1039
      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
1040
    } else if (isX(p)) {
1041
      if (M === '0') {
1042
        ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
1043
      } else {
1044
        ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'
1045
      }
1046
    } else if (pr) {
1047
      debug('replaceCaret pr', pr)
1048
      if (M === '0') {
1049
        if (m === '0') {
1050
          ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
1051
                ' <' + M + '.' + m + '.' + (+p + 1)
1052
        } else {
1053
          ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
1054
                ' <' + M + '.' + (+m + 1) + '.0'
1055
        }
1056
      } else {
1057
        ret = '>=' + M + '.' + m + '.' + p + '-' + pr +
1058
              ' <' + (+M + 1) + '.0.0'
1059
      }
1060
    } else {
1061
      debug('no pr')
1062
      if (M === '0') {
1063
        if (m === '0') {
1064
          ret = '>=' + M + '.' + m + '.' + p +
1065
                ' <' + M + '.' + m + '.' + (+p + 1)
1066
        } else {
1067
          ret = '>=' + M + '.' + m + '.' + p +
1068
                ' <' + M + '.' + (+m + 1) + '.0'
1069
        }
1070
      } else {
1071
        ret = '>=' + M + '.' + m + '.' + p +
1072
              ' <' + (+M + 1) + '.0.0'
1073
      }
1074
    }
1075

    
1076
    debug('caret return', ret)
1077
    return ret
1078
  })
1079
}
1080

    
1081
function replaceXRanges (comp, options) {
1082
  debug('replaceXRanges', comp, options)
1083
  return comp.split(/\s+/).map(function (comp) {
1084
    return replaceXRange(comp, options)
1085
  }).join(' ')
1086
}
1087

    
1088
function replaceXRange (comp, options) {
1089
  comp = comp.trim()
1090
  var r = options.loose ? re[XRANGELOOSE] : re[XRANGE]
1091
  return comp.replace(r, function (ret, gtlt, M, m, p, pr) {
1092
    debug('xRange', comp, ret, gtlt, M, m, p, pr)
1093
    var xM = isX(M)
1094
    var xm = xM || isX(m)
1095
    var xp = xm || isX(p)
1096
    var anyX = xp
1097

    
1098
    if (gtlt === '=' && anyX) {
1099
      gtlt = ''
1100
    }
1101

    
1102
    if (xM) {
1103
      if (gtlt === '>' || gtlt === '<') {
1104
        // nothing is allowed
1105
        ret = '<0.0.0'
1106
      } else {
1107
        // nothing is forbidden
1108
        ret = '*'
1109
      }
1110
    } else if (gtlt && anyX) {
1111
      // we know patch is an x, because we have any x at all.
1112
      // replace X with 0
1113
      if (xm) {
1114
        m = 0
1115
      }
1116
      p = 0
1117

    
1118
      if (gtlt === '>') {
1119
        // >1 => >=2.0.0
1120
        // >1.2 => >=1.3.0
1121
        // >1.2.3 => >= 1.2.4
1122
        gtlt = '>='
1123
        if (xm) {
1124
          M = +M + 1
1125
          m = 0
1126
          p = 0
1127
        } else {
1128
          m = +m + 1
1129
          p = 0
1130
        }
1131
      } else if (gtlt === '<=') {
1132
        // <=0.7.x is actually <0.8.0, since any 0.7.x should
1133
        // pass.  Similarly, <=7.x is actually <8.0.0, etc.
1134
        gtlt = '<'
1135
        if (xm) {
1136
          M = +M + 1
1137
        } else {
1138
          m = +m + 1
1139
        }
1140
      }
1141

    
1142
      ret = gtlt + M + '.' + m + '.' + p
1143
    } else if (xm) {
1144
      ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'
1145
    } else if (xp) {
1146
      ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'
1147
    }
1148

    
1149
    debug('xRange return', ret)
1150

    
1151
    return ret
1152
  })
1153
}
1154

    
1155
// Because * is AND-ed with everything else in the comparator,
1156
// and '' means "any version", just remove the *s entirely.
1157
function replaceStars (comp, options) {
1158
  debug('replaceStars', comp, options)
1159
  // Looseness is ignored here.  star is always as loose as it gets!
1160
  return comp.trim().replace(re[STAR], '')
1161
}
1162

    
1163
// This function is passed to string.replace(re[HYPHENRANGE])
1164
// M, m, patch, prerelease, build
1165
// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
1166
// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
1167
// 1.2 - 3.4 => >=1.2.0 <3.5.0
1168
function hyphenReplace ($0,
1169
  from, fM, fm, fp, fpr, fb,
1170
  to, tM, tm, tp, tpr, tb) {
1171
  if (isX(fM)) {
1172
    from = ''
1173
  } else if (isX(fm)) {
1174
    from = '>=' + fM + '.0.0'
1175
  } else if (isX(fp)) {
1176
    from = '>=' + fM + '.' + fm + '.0'
1177
  } else {
1178
    from = '>=' + from
1179
  }
1180

    
1181
  if (isX(tM)) {
1182
    to = ''
1183
  } else if (isX(tm)) {
1184
    to = '<' + (+tM + 1) + '.0.0'
1185
  } else if (isX(tp)) {
1186
    to = '<' + tM + '.' + (+tm + 1) + '.0'
1187
  } else if (tpr) {
1188
    to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr
1189
  } else {
1190
    to = '<=' + to
1191
  }
1192

    
1193
  return (from + ' ' + to).trim()
1194
}
1195

    
1196
// if ANY of the sets match ALL of its comparators, then pass
1197
Range.prototype.test = function (version) {
1198
  if (!version) {
1199
    return false
1200
  }
1201

    
1202
  if (typeof version === 'string') {
1203
    version = new SemVer(version, this.options)
1204
  }
1205

    
1206
  for (var i = 0; i < this.set.length; i++) {
1207
    if (testSet(this.set[i], version, this.options)) {
1208
      return true
1209
    }
1210
  }
1211
  return false
1212
}
1213

    
1214
function testSet (set, version, options) {
1215
  for (var i = 0; i < set.length; i++) {
1216
    if (!set[i].test(version)) {
1217
      return false
1218
    }
1219
  }
1220

    
1221
  if (version.prerelease.length && !options.includePrerelease) {
1222
    // Find the set of versions that are allowed to have prereleases
1223
    // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0
1224
    // That should allow `1.2.3-pr.2` to pass.
1225
    // However, `1.2.4-alpha.notready` should NOT be allowed,
1226
    // even though it's within the range set by the comparators.
1227
    for (i = 0; i < set.length; i++) {
1228
      debug(set[i].semver)
1229
      if (set[i].semver === ANY) {
1230
        continue
1231
      }
1232

    
1233
      if (set[i].semver.prerelease.length > 0) {
1234
        var allowed = set[i].semver
1235
        if (allowed.major === version.major &&
1236
            allowed.minor === version.minor &&
1237
            allowed.patch === version.patch) {
1238
          return true
1239
        }
1240
      }
1241
    }
1242

    
1243
    // Version has a -pre, but it's not one of the ones we like.
1244
    return false
1245
  }
1246

    
1247
  return true
1248
}
1249

    
1250
exports.satisfies = satisfies
1251
function satisfies (version, range, options) {
1252
  try {
1253
    range = new Range(range, options)
1254
  } catch (er) {
1255
    return false
1256
  }
1257
  return range.test(version)
1258
}
1259

    
1260
exports.maxSatisfying = maxSatisfying
1261
function maxSatisfying (versions, range, options) {
1262
  var max = null
1263
  var maxSV = null
1264
  try {
1265
    var rangeObj = new Range(range, options)
1266
  } catch (er) {
1267
    return null
1268
  }
1269
  versions.forEach(function (v) {
1270
    if (rangeObj.test(v)) {
1271
      // satisfies(v, range, options)
1272
      if (!max || maxSV.compare(v) === -1) {
1273
        // compare(max, v, true)
1274
        max = v
1275
        maxSV = new SemVer(max, options)
1276
      }
1277
    }
1278
  })
1279
  return max
1280
}
1281

    
1282
exports.minSatisfying = minSatisfying
1283
function minSatisfying (versions, range, options) {
1284
  var min = null
1285
  var minSV = null
1286
  try {
1287
    var rangeObj = new Range(range, options)
1288
  } catch (er) {
1289
    return null
1290
  }
1291
  versions.forEach(function (v) {
1292
    if (rangeObj.test(v)) {
1293
      // satisfies(v, range, options)
1294
      if (!min || minSV.compare(v) === 1) {
1295
        // compare(min, v, true)
1296
        min = v
1297
        minSV = new SemVer(min, options)
1298
      }
1299
    }
1300
  })
1301
  return min
1302
}
1303

    
1304
exports.minVersion = minVersion
1305
function minVersion (range, loose) {
1306
  range = new Range(range, loose)
1307

    
1308
  var minver = new SemVer('0.0.0')
1309
  if (range.test(minver)) {
1310
    return minver
1311
  }
1312

    
1313
  minver = new SemVer('0.0.0-0')
1314
  if (range.test(minver)) {
1315
    return minver
1316
  }
1317

    
1318
  minver = null
1319
  for (var i = 0; i < range.set.length; ++i) {
1320
    var comparators = range.set[i]
1321

    
1322
    comparators.forEach(function (comparator) {
1323
      // Clone to avoid manipulating the comparator's semver object.
1324
      var compver = new SemVer(comparator.semver.version)
1325
      switch (comparator.operator) {
1326
        case '>':
1327
          if (compver.prerelease.length === 0) {
1328
            compver.patch++
1329
          } else {
1330
            compver.prerelease.push(0)
1331
          }
1332
          compver.raw = compver.format()
1333
          /* fallthrough */
1334
        case '':
1335
        case '>=':
1336
          if (!minver || gt(minver, compver)) {
1337
            minver = compver
1338
          }
1339
          break
1340
        case '<':
1341
        case '<=':
1342
          /* Ignore maximum versions */
1343
          break
1344
        /* istanbul ignore next */
1345
        default:
1346
          throw new Error('Unexpected operation: ' + comparator.operator)
1347
      }
1348
    })
1349
  }
1350

    
1351
  if (minver && range.test(minver)) {
1352
    return minver
1353
  }
1354

    
1355
  return null
1356
}
1357

    
1358
exports.validRange = validRange
1359
function validRange (range, options) {
1360
  try {
1361
    // Return '*' instead of '' so that truthiness works.
1362
    // This will throw if it's invalid anyway
1363
    return new Range(range, options).range || '*'
1364
  } catch (er) {
1365
    return null
1366
  }
1367
}
1368

    
1369
// Determine if version is less than all the versions possible in the range
1370
exports.ltr = ltr
1371
function ltr (version, range, options) {
1372
  return outside(version, range, '<', options)
1373
}
1374

    
1375
// Determine if version is greater than all the versions possible in the range.
1376
exports.gtr = gtr
1377
function gtr (version, range, options) {
1378
  return outside(version, range, '>', options)
1379
}
1380

    
1381
exports.outside = outside
1382
function outside (version, range, hilo, options) {
1383
  version = new SemVer(version, options)
1384
  range = new Range(range, options)
1385

    
1386
  var gtfn, ltefn, ltfn, comp, ecomp
1387
  switch (hilo) {
1388
    case '>':
1389
      gtfn = gt
1390
      ltefn = lte
1391
      ltfn = lt
1392
      comp = '>'
1393
      ecomp = '>='
1394
      break
1395
    case '<':
1396
      gtfn = lt
1397
      ltefn = gte
1398
      ltfn = gt
1399
      comp = '<'
1400
      ecomp = '<='
1401
      break
1402
    default:
1403
      throw new TypeError('Must provide a hilo val of "<" or ">"')
1404
  }
1405

    
1406
  // If it satisifes the range it is not outside
1407
  if (satisfies(version, range, options)) {
1408
    return false
1409
  }
1410

    
1411
  // From now on, variable terms are as if we're in "gtr" mode.
1412
  // but note that everything is flipped for the "ltr" function.
1413

    
1414
  for (var i = 0; i < range.set.length; ++i) {
1415
    var comparators = range.set[i]
1416

    
1417
    var high = null
1418
    var low = null
1419

    
1420
    comparators.forEach(function (comparator) {
1421
      if (comparator.semver === ANY) {
1422
        comparator = new Comparator('>=0.0.0')
1423
      }
1424
      high = high || comparator
1425
      low = low || comparator
1426
      if (gtfn(comparator.semver, high.semver, options)) {
1427
        high = comparator
1428
      } else if (ltfn(comparator.semver, low.semver, options)) {
1429
        low = comparator
1430
      }
1431
    })
1432

    
1433
    // If the edge version comparator has a operator then our version
1434
    // isn't outside it
1435
    if (high.operator === comp || high.operator === ecomp) {
1436
      return false
1437
    }
1438

    
1439
    // If the lowest version comparator has an operator and our version
1440
    // is less than it then it isn't higher than the range
1441
    if ((!low.operator || low.operator === comp) &&
1442
        ltefn(version, low.semver)) {
1443
      return false
1444
    } else if (low.operator === ecomp && ltfn(version, low.semver)) {
1445
      return false
1446
    }
1447
  }
1448
  return true
1449
}
1450

    
1451
exports.prerelease = prerelease
1452
function prerelease (version, options) {
1453
  var parsed = parse(version, options)
1454
  return (parsed && parsed.prerelease.length) ? parsed.prerelease : null
1455
}
1456

    
1457
exports.intersects = intersects
1458
function intersects (r1, r2, options) {
1459
  r1 = new Range(r1, options)
1460
  r2 = new Range(r2, options)
1461
  return r1.intersects(r2)
1462
}
1463

    
1464
exports.coerce = coerce
1465
function coerce (version) {
1466
  if (version instanceof SemVer) {
1467
    return version
1468
  }
1469

    
1470
  if (typeof version !== 'string') {
1471
    return null
1472
  }
1473

    
1474
  var match = version.match(re[COERCE])
1475

    
1476
  if (match == null) {
1477
    return null
1478
  }
1479

    
1480
  return parse(match[1] +
1481
    '.' + (match[2] || '0') +
1482
    '.' + (match[3] || '0'))
1483
}
(6-6/6)