text: /**
   * [![npm version](https://img.shields.io/npm/v/tonal-array.svg?style=flat-square)](https://www.npmjs.com/package/tonal-array)
   *
   * Tonal array utilities. Create ranges, sort notes, ...
   *
   * @example
   * import * as Array;
   * Array.sort(["f", "a", "c"]) // => ["C", "F", "A"]
   *
   * @example
   * const Array = require("tonal-array)
   * Array.range(1, 4) // => [1, 2, 3, 4]
   *
   * @module Array
   */
  import { midi, name } from "tonal-note";
  
  // ascending range
  function ascR(b, n) {
    for (var a = []; n--; a[n] = n + b){ ; }
    return a;
  }
  // descending range
  function descR(b, n) {
    for (var a = []; n--; a[n] = b - n){ ; }
    return a;
  }
  
  /**
   * Create a numeric range
   *
   * @param {Number} from
   * @param {Number} to
   * @return {Array}
   *
   * @example
   * Array.range(-2, 2) // => [-2, -1, 0, 1, 2]
   * Array.range(2, -2) // => [2, 1, 0, -1, -2]
   */
  export function range(a, b) {
    return a === null || b === null
      ? []
      : a < b ? ascR(a, b - a + 1) : descR(a, a - b + 1);
  }
  /**
   *
   * Rotates a list a number of times. It"s completly agnostic about the
   * contents of the list.
   *
   * @param {Integer} times - the number of rotations
   * @param {Array} array
   * @return {Array} the rotated array
   * @example
   * Array.rotate(1, [1, 2, 3]) // => [2, 3, 1]
   */
  export function rotate(times, arr) {
    var len = arr.length;
    var n = (times % len + len) % len;
    return arr.slice(n, len).concat(arr.slice(0, n));
  }
  
  /**
   * Return a copy of the array with the null values removed
   * @function
   * @param {Array} array
   * @return {Array}
   *
   * @example
   * Array.compact(["a", "b", null, "c"]) // => ["a", "b", "c"]
   */
  export var compact = function (arr) { return arr.filter(function (n) { return n === 0 || n; }); };
  
  // a function that get note heights (with negative number for pitch classes)
  var height = function (n) {
    var m = midi(n);
    return m !== null ? m : midi(n + "-100");
  };
  
  /**
   * Sort an array of notes in ascending order
   *
   * @param {String|Array} notes
   * @return {Array} sorted array of notes
   */
  export function sort(src) {
    return compact(src.map(name)).sort(function (a, b) { return height(a) > height(b); });
  }
  
  /**
   * Get sorted notes with duplicates removed
   *
   * @function
   * @param {Array} notes
   */
  export function unique(arr) {
    return sort(arr).filter(function (n, i, a) { return i === 0 || n !== a[i - 1]; });
  }
  
  /**
   * Randomizes the order of the specified array in-place, using the Fisher–Yates shuffle.
   *
   * @private
   * @function
   * @param {Array|String} arr - the array
   * @return {Array} the shuffled array
   *
   * @example
   * Array.shuffle(["C", "D", "E", "F"])
   */
  export var shuffle = function (arr, rnd) {
    if ( rnd === void 0 ) rnd = Math.random;
  
    var i, t;
    var m = arr.length;
    while (m) {
      i = (rnd() * m--) | 0;
      t = arr[m];
      arr[m] = arr[i];
      arr[i] = t;
    }
    return arr;
  };
  
  /**
   * Get all permutations of an array
   * http://stackoverflow.com/questions/9960908/permutations-in-javascript
   *
   * @param {Array} array - the array
   * @return {Array<Array>} an array with all the permutations
   */
  export var permutations = function (arr) {
    if (arr.length === 0) { return [[]]; }
    return permutations(arr.slice(1)).reduce(function(acc, perm) {
      return acc.concat(
        arr.map(function(e, pos) {
          var newPerm = perm.slice();
          newPerm.splice(pos, 0, arr[0]);
          return newPerm;
        })
      );
    }, []);
  };
  