docs: function shuffle(a, b, toRemove) {
  	var newA = allocate(a.height, Math.min(_const.M, a.length + b.length - toRemove));
  	var newB = allocate(a.height, Math.max(0, newA.length - (a.length + b.length - toRemove)));
  
  	// Skip the slots with size M. More precise: copy the slot references
  	// to the new node
  	var read = 0;
  	let aLen = a.length;
  	let either, fromA;
  	let newALen = newA.length;
  	while (fromA = read < aLen, either = fromA ? a[read] : b[read - aLen], either.length % _const.M === 0) {
  		let fromNewA = read < newALen;
  		if (fromNewA) {
  			newA[read] = either;
  		} else {
  			newB[read - newALen] = either;
  		}
  		let size = fromNewA ? a.sizes[read] : b.sizes[read - newALen];
  		if (!size) {
  			size = newA.sizes[read - 1] + (0, _util.length)(either);
  		}
  		if (fromNewA) {
  			newA.sizes[read] = size;
  		} else {
  			newB.sizes[read - newALen] = size;
  		}
  		read++;
  	}
  
  	// Pulling items from left to right, caching in a slot before writing
  	// it into the new nodes.
  	var write = read;
  	var slot = allocate(a.height - 1, 0);
  	var from = 0;
  
  	// If the current slot is still containing data, then there will be at
  	// least one more write, so we do not break this loop yet.
  	while (read - write - (slot.length > 0 ? 1 : 0) < toRemove && read - a.length < b.length) {
  		// Find out the max possible items for copying.
  		var source = getEither(a, b, read);
  		var to = Math.min(_const.M - slot.length, source.length);
  
  		// Copy and adjust size table.
  		var height = slot.height,
  		    sizes = height === 0 ? null : slot.sizes.slice(0);
  		slot = slot.concat(source.slice(from, to));
  		slot.height = height;
  		if (slot.height > 0) {
  			slot.sizes = sizes;
  			var len = sizes.length;
  			for (var i = len; i < len + to - from; i++) {
  				sizes[i] = (0, _util.length)(slot[i]);
  				sizes[i] += i > 0 ? slot.sizes[i - 1] : 0;
  			}
  		}
  
  		from += to;
  
  		// Only proceed to next slots[i] if the current one was
  		// fully copied.
  		if (source.length <= to) {
  			read++;
  			from = 0;
  		}
  
  		// Only create a new slot if the current one is filled up.
  		if (slot.length === _const.M) {
  			saveSlot(newA, newB, write, slot);
  			slot = allocate(a.height - 1, 0);
  			write++;
  		}
  	}
  
  	// Cleanup after the loop. Copy the last slot into the new nodes.
  	if (slot.length > 0) {
  		saveSlot(newA, newB, write, slot);
  		write++;
  	}
  
  	// Shift the untouched slots to the left
  	while (read < a.length + b.length) {
  		saveSlot(newA, newB, write, getEither(a, b, read));
  		read++;
  		write++;
  	}
  
  	return [newA, newB];
  }