| 'use strict'; |
| module.exports = { |
| wrap: wrapRange, |
| limit: limitRange, |
| validate: validateRange, |
| test: testRange, |
| curry: curry, |
| name: name |
| }; |
| |
| function wrapRange(min, max, value) { |
| var maxLessMin = max - min; |
| return ((value - min) % maxLessMin + maxLessMin) % maxLessMin + min; |
| } |
| |
| function limitRange(min, max, value) { |
| return Math.max(min, Math.min(max, value)); |
| } |
| |
| function validateRange(min, max, value, minExclusive, maxExclusive) { |
| if (!testRange(min, max, value, minExclusive, maxExclusive)) { |
| throw new Error(value + ' is outside of range [' + min + ',' + max + ')'); |
| } |
| return value; |
| } |
| |
| function testRange(min, max, value, minExclusive, maxExclusive) { |
| return !( |
| value < min || |
| value > max || |
| (maxExclusive && (value === max)) || |
| (minExclusive && (value === min)) |
| ); |
| } |
| |
| function name(min, max, minExcl, maxExcl) { |
| return (minExcl ? '(' : '[') + min + ',' + max + (maxExcl ? ')' : ']'); |
| } |
| |
| function curry(min, max, minExclusive, maxExclusive) { |
| var boundNameFn = name.bind(null, min, max, minExclusive, maxExclusive); |
| return { |
| wrap: wrapRange.bind(null, min, max), |
| limit: limitRange.bind(null, min, max), |
| validate: function(value) { |
| return validateRange(min, max, value, minExclusive, maxExclusive); |
| }, |
| test: function(value) { |
| return testRange(min, max, value, minExclusive, maxExclusive); |
| }, |
| toString: boundNameFn, |
| name: boundNameFn |
| }; |
| } |