text: 'use strict'
  
  module.exports = boxIntersectWrapper
  
  var pool = require('typedarray-pool')
  var sweep = require('./lib/sweep')
  var boxIntersectIter = require('./lib/intersect')
  
  function boxEmpty(d, box) {
    for(var j=0; j<d; ++j) {
      if(!(box[j] <= box[j+d])) {
        return true
      }
    }
    return false
  }
  
  //Unpack boxes into a flat typed array, remove empty boxes
  function convertBoxes(boxes, d, data, ids) {
    var ptr = 0
    var count = 0
    for(var i=0, n=boxes.length; i<n; ++i) {
      var b = boxes[i]
      if(boxEmpty(d, b)) {
        continue
      }
      for(var j=0; j<2*d; ++j) {
        data[ptr++] = b[j]
      }
      ids[count++] = i
    }
    return count
  }
  
  //Perform type conversions, check bounds
  function boxIntersect(red, blue, visit, full) {
    var n = red.length
    var m = blue.length
  
    //If either array is empty, then we can skip this whole thing
    if(n <= 0 || m <= 0) {
      return
    }
  
    //Compute dimension, if it is 0 then we skip
    var d = (red[0].length)>>>1
    if(d <= 0) {
      return
    }
  
    var retval
  
    //Convert red boxes
    var redList  = pool.mallocDouble(2*d*n)
    var redIds   = pool.mallocInt32(n)
    n = convertBoxes(red, d, redList, redIds)
  
    if(n > 0) {
      if(d === 1 && full) {
        //Special case: 1d complete
        sweep.init(n)
        retval = sweep.sweepComplete(
          d, visit, 
          0, n, redList, redIds,
          0, n, redList, redIds)
      } else {
  
        //Convert blue boxes
        var blueList = pool.mallocDouble(2*d*m)
        var blueIds  = pool.mallocInt32(m)
        m = convertBoxes(blue, d, blueList, blueIds)
  
        if(m > 0) {
          sweep.init(n+m)
  
          if(d === 1) {
            //Special case: 1d bipartite
            retval = sweep.sweepBipartite(
              d, visit, 
              0, n, redList,  redIds,
              0, m, blueList, blueIds)
          } else {
            //General case:  d>1
            retval = boxIntersectIter(
              d, visit,    full,
              n, redList,  redIds,
              m, blueList, blueIds)
          }
  
          pool.free(blueList)
          pool.free(blueIds)
        }
      }
  
      pool.free(redList)
      pool.free(redIds)
    }
  
    return retval
  }
  
  
  var RESULT
  
  function appendItem(i,j) {
    RESULT.push([i,j])
  }
  
  function intersectFullArray(x) {
    RESULT = []
    boxIntersect(x, x, appendItem, true)
    return RESULT
  }
  
  function intersectBipartiteArray(x, y) {
    RESULT = []
    boxIntersect(x, y, appendItem, false)
    return RESULT
  }
  
  //User-friendly wrapper, handle full input and no-visitor cases
  function boxIntersectWrapper(arg0, arg1, arg2) {
    var result
    switch(arguments.length) {
      case 1:
        return intersectFullArray(arg0)
      case 2:
        if(typeof arg1 === 'function') {
          return boxIntersect(arg0, arg0, arg1, true)
        } else {
          return intersectBipartiteArray(arg0, arg1)
        }
      case 3:
        return boxIntersect(arg0, arg1, arg2, false)
      default:
        throw new Error('box-intersect: Invalid arguments')
    }
  }