function _parse(str) {
    var args = str.split(':'); // number

    var nums = args.map(function (arg) {
      // use Number and not parseFloat as Number returns NaN on invalid garbage in the string
      return Number(arg);
    });
    var invalid = nums.some(function (num) {
      return isNaN(num);
    });

    if (invalid) {
      return null;
    }

    switch (nums.length) {
      case 2:
        return {
          start: nums[0],
          end: nums[1],
          step: 1
        };

      case 3:
        return {
          start: nums[0],
          end: nums[2],
          step: nums[1]
        };

      default:
        return null;
    }
  }
Parse a string into a range,
The string contains the start, optional step, and end, separated by a colon.
If the string does not contain a valid range, null is returned.
For example str='0:2:11'.
@param {string} str
@return {{start: number, end: number, step: number} | null} range Object containing properties start, end, step
@private