function weave(prefix = [], arrays1 = [[]], arrays2 = [[]]) {
  let result = [];

  // in case of two arguments let's asume it is for array 1 and 2 and that prefix is empty
  if(arguments.length === 2) {
    [arrays1, arrays2] = [prefix, arrays1];
    prefix = [];
  }

  // make sure arrays 1 and 2 are an array of arrays and prefix is an array
  prefix = Array.isArray(prefix) ? prefix : [prefix];
  arrays1 = Array.isArray(arrays1[0]) ? arrays1 : [arrays1];
  arrays2 = Array.isArray(arrays2[0]) ? arrays2 : [arrays2];

  // console.log('*weave (', prefix, arrays1, arrays2, ')');

  // process weaving recursively
  arrays1.forEach((array1) => {
    arrays2.forEach((array2) => {

      if(!array1.length || !array2.length) {
        result = result.concat([prefix.concat(array1, array2)]);

      } else {
        // weave the arrays
        result = result.concat(weave(prefix.concat(array1[0]), array1.slice(1), array2));
        result = result.concat(weave(prefix.concat(array2[0]), array1, array2.slice(1)));
      }
    });
  });

  // console.log('\tweave (', prefix, arrays1, arrays2, ')');
  // console.log('\t\t =>', result, '\n');

  return result;
}
Weave two arrays with a given prefix