You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					388 lines
				
				8.9 KiB
			
		
		
			
		
	
	
					388 lines
				
				8.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Mnemonist StaticIntervalTree
							 | 
						||
| 
								 | 
							
								 * =============================
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * JavaScript implementation of a static interval tree. This tree is static in
							 | 
						||
| 
								 | 
							
								 * that you are required to know all its items beforehand and to built it
							 | 
						||
| 
								 | 
							
								 * from an iterable.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This implementation represents the interval tree as an augmented balanced
							 | 
						||
| 
								 | 
							
								 * binary search tree. It works by sorting the intervals by startpoint first
							 | 
						||
| 
								 | 
							
								 * then proceeds building the augmented balanced BST bottom-up from the
							 | 
						||
| 
								 | 
							
								 * sorted list.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Note that this implementation considers every given intervals as closed for
							 | 
						||
| 
								 | 
							
								 * simplicity's sake.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * For more information: https://en.wikipedia.org/wiki/Interval_tree
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var iterables = require('./utils/iterables.js'),
							 | 
						||
| 
								 | 
							
								    typed = require('./utils/typed-arrays.js');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var FixedStack = require('./fixed-stack.js');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// TODO: pass index to getters
							 | 
						||
| 
								 | 
							
								// TODO: custom comparison
							 | 
						||
| 
								 | 
							
								// TODO: possibility to pass offset buffer
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// TODO: intervals() => Symbol.iterator
							 | 
						||
| 
								 | 
							
								// TODO: dfs()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Helpers.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Recursive function building the BST from the sorted list of interval
							 | 
						||
| 
								 | 
							
								 * indices.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {array}    intervals     - Array of intervals to index.
							 | 
						||
| 
								 | 
							
								 * @param  {function} endGetter     - Getter function for end of intervals.
							 | 
						||
| 
								 | 
							
								 * @param  {array}    sortedIndices - Sorted indices of the intervals.
							 | 
						||
| 
								 | 
							
								 * @param  {array}    tree          - BST memory.
							 | 
						||
| 
								 | 
							
								 * @param  {array}    augmentations - Array of node augmentations.
							 | 
						||
| 
								 | 
							
								 * @param  {number}   i             - BST index of current node.
							 | 
						||
| 
								 | 
							
								 * @param  {number}   low           - Dichotomy low index.
							 | 
						||
| 
								 | 
							
								 * @param  {number}   high          - Dichotomy high index.
							 | 
						||
| 
								 | 
							
								 * @return {number}                 - Created node augmentation value.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function buildBST(
							 | 
						||
| 
								 | 
							
								  intervals,
							 | 
						||
| 
								 | 
							
								  endGetter,
							 | 
						||
| 
								 | 
							
								  sortedIndices,
							 | 
						||
| 
								 | 
							
								  tree,
							 | 
						||
| 
								 | 
							
								  augmentations,
							 | 
						||
| 
								 | 
							
								  i,
							 | 
						||
| 
								 | 
							
								  low,
							 | 
						||
| 
								 | 
							
								  high
							 | 
						||
| 
								 | 
							
								) {
							 | 
						||
| 
								 | 
							
								  var mid = (low + (high - low) / 2) | 0,
							 | 
						||
| 
								 | 
							
								      midMinusOne = ~-mid,
							 | 
						||
| 
								 | 
							
								      midPlusOne = -~mid;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var current = sortedIndices[mid];
							 | 
						||
| 
								 | 
							
								  tree[i] = current + 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var end = endGetter ? endGetter(intervals[current]) : intervals[current][1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var left = i * 2 + 1,
							 | 
						||
| 
								 | 
							
								      right = i * 2 + 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var leftEnd = -Infinity,
							 | 
						||
| 
								 | 
							
								      rightEnd = -Infinity;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (low <= midMinusOne) {
							 | 
						||
| 
								 | 
							
								    leftEnd = buildBST(
							 | 
						||
| 
								 | 
							
								      intervals,
							 | 
						||
| 
								 | 
							
								      endGetter,
							 | 
						||
| 
								 | 
							
								      sortedIndices,
							 | 
						||
| 
								 | 
							
								      tree,
							 | 
						||
| 
								 | 
							
								      augmentations,
							 | 
						||
| 
								 | 
							
								      left,
							 | 
						||
| 
								 | 
							
								      low,
							 | 
						||
| 
								 | 
							
								      midMinusOne
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (midPlusOne <= high) {
							 | 
						||
| 
								 | 
							
								    rightEnd = buildBST(
							 | 
						||
| 
								 | 
							
								      intervals,
							 | 
						||
| 
								 | 
							
								      endGetter,
							 | 
						||
| 
								 | 
							
								      sortedIndices,
							 | 
						||
| 
								 | 
							
								      tree,
							 | 
						||
| 
								 | 
							
								      augmentations,
							 | 
						||
| 
								 | 
							
								      right,
							 | 
						||
| 
								 | 
							
								      midPlusOne,
							 | 
						||
| 
								 | 
							
								      high
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var augmentation = Math.max(end, leftEnd, rightEnd);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var augmentationPointer = current;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (augmentation === leftEnd)
							 | 
						||
| 
								 | 
							
								    augmentationPointer = augmentations[tree[left] - 1];
							 | 
						||
| 
								 | 
							
								  else if (augmentation === rightEnd)
							 | 
						||
| 
								 | 
							
								    augmentationPointer = augmentations[tree[right] - 1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  augmentations[current] = augmentationPointer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return augmentation;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * StaticIntervalTree.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {array}           intervals - Array of intervals to index.
							 | 
						||
| 
								 | 
							
								 * @param {array<function>} getters   - Optional getters.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function StaticIntervalTree(intervals, getters) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Properties
							 | 
						||
| 
								 | 
							
								  this.size = intervals.length;
							 | 
						||
| 
								 | 
							
								  this.intervals = intervals;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var startGetter = null,
							 | 
						||
| 
								 | 
							
								      endGetter = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (Array.isArray(getters)) {
							 | 
						||
| 
								 | 
							
								    startGetter = getters[0];
							 | 
						||
| 
								 | 
							
								    endGetter = getters[1];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Building the indices array
							 | 
						||
| 
								 | 
							
								  var length = intervals.length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var IndicesArray = typed.getPointerArray(length + 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var indices = new IndicesArray(length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i = 1; i < length; i++)
							 | 
						||
| 
								 | 
							
								    indices[i] = i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Sorting indices array
							 | 
						||
| 
								 | 
							
								  // TODO: check if some version of radix sort can outperform this part
							 | 
						||
| 
								 | 
							
								  indices.sort(function(a, b) {
							 | 
						||
| 
								 | 
							
								    a = intervals[a];
							 | 
						||
| 
								 | 
							
								    b = intervals[b];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (startGetter) {
							 | 
						||
| 
								 | 
							
								      a = startGetter(a);
							 | 
						||
| 
								 | 
							
								      b = startGetter(b);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								      a = a[0];
							 | 
						||
| 
								 | 
							
								      b = b[0];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (a < b)
							 | 
						||
| 
								 | 
							
								      return -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (a > b)
							 | 
						||
| 
								 | 
							
								      return 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // TODO: use getters
							 | 
						||
| 
								 | 
							
								    // TODO: this ordering has the following invariant: if query interval
							 | 
						||
| 
								 | 
							
								    // contains [nodeStart, max], then whole right subtree can be collected
							 | 
						||
| 
								 | 
							
								    // a = a[1];
							 | 
						||
| 
								 | 
							
								    // b = b[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // if (a < b)
							 | 
						||
| 
								 | 
							
								    //   return 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // if (a > b)
							 | 
						||
| 
								 | 
							
								    //   return -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Building the binary tree
							 | 
						||
| 
								 | 
							
								  var height = Math.ceil(Math.log2(length + 1)),
							 | 
						||
| 
								 | 
							
								      treeSize = Math.pow(2, height) - 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var tree = new IndicesArray(treeSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var augmentations = new IndicesArray(length);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  buildBST(
							 | 
						||
| 
								 | 
							
								    intervals,
							 | 
						||
| 
								 | 
							
								    endGetter,
							 | 
						||
| 
								 | 
							
								    indices,
							 | 
						||
| 
								 | 
							
								    tree,
							 | 
						||
| 
								 | 
							
								    augmentations,
							 | 
						||
| 
								 | 
							
								    0,
							 | 
						||
| 
								 | 
							
								    0,
							 | 
						||
| 
								 | 
							
								    length - 1
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Dropping indices
							 | 
						||
| 
								 | 
							
								  indices = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Storing necessary information
							 | 
						||
| 
								 | 
							
								  this.height = height;
							 | 
						||
| 
								 | 
							
								  this.tree = tree;
							 | 
						||
| 
								 | 
							
								  this.augmentations = augmentations;
							 | 
						||
| 
								 | 
							
								  this.startGetter = startGetter;
							 | 
						||
| 
								 | 
							
								  this.endGetter = endGetter;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Initializing DFS stack
							 | 
						||
| 
								 | 
							
								  this.stack = new FixedStack(IndicesArray, this.height);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning a list of intervals containing the given point.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}   point - Target point.
							 | 
						||
| 
								 | 
							
								 * @return {array}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								StaticIntervalTree.prototype.intervalsContainingPoint = function(point) {
							 | 
						||
| 
								 | 
							
								  var matches = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var stack = this.stack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  stack.clear();
							 | 
						||
| 
								 | 
							
								  stack.push(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var l = this.tree.length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var bstIndex,
							 | 
						||
| 
								 | 
							
								      intervalIndex,
							 | 
						||
| 
								 | 
							
								      interval,
							 | 
						||
| 
								 | 
							
								      maxInterval,
							 | 
						||
| 
								 | 
							
								      start,
							 | 
						||
| 
								 | 
							
								      end,
							 | 
						||
| 
								 | 
							
								      max,
							 | 
						||
| 
								 | 
							
								      left,
							 | 
						||
| 
								 | 
							
								      right;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (stack.size) {
							 | 
						||
| 
								 | 
							
								    bstIndex = stack.pop();
							 | 
						||
| 
								 | 
							
								    intervalIndex = this.tree[bstIndex] - 1;
							 | 
						||
| 
								 | 
							
								    interval = this.intervals[intervalIndex];
							 | 
						||
| 
								 | 
							
								    maxInterval = this.intervals[this.augmentations[intervalIndex]];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    max = this.endGetter ? this.endGetter(maxInterval) : maxInterval[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // No possible match, point is farther right than the max end value
							 | 
						||
| 
								 | 
							
								    if (point > max)
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Searching left
							 | 
						||
| 
								 | 
							
								    left = bstIndex * 2 + 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (left < l && this.tree[left] !== 0)
							 | 
						||
| 
								 | 
							
								      stack.push(left);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    start = this.startGetter ? this.startGetter(interval) : interval[0];
							 | 
						||
| 
								 | 
							
								    end = this.endGetter ? this.endGetter(interval) : interval[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Checking current node
							 | 
						||
| 
								 | 
							
								    if (point >= start && point <= end)
							 | 
						||
| 
								 | 
							
								      matches.push(interval);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // If the point is to the left of the start of the current interval,
							 | 
						||
| 
								 | 
							
								    // then it cannot be in the right child
							 | 
						||
| 
								 | 
							
								    if (point < start)
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Searching right
							 | 
						||
| 
								 | 
							
								    right = bstIndex * 2 + 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (right < l && this.tree[right] !== 0)
							 | 
						||
| 
								 | 
							
								      stack.push(right);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return matches;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning a list of intervals overlapping the given interval.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}   interval - Target interval.
							 | 
						||
| 
								 | 
							
								 * @return {array}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								StaticIntervalTree.prototype.intervalsOverlappingInterval = function(interval) {
							 | 
						||
| 
								 | 
							
								  var intervalStart = this.startGetter ? this.startGetter(interval) : interval[0],
							 | 
						||
| 
								 | 
							
								      intervalEnd = this.endGetter ? this.endGetter(interval) : interval[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var matches = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var stack = this.stack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  stack.clear();
							 | 
						||
| 
								 | 
							
								  stack.push(0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var l = this.tree.length;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var bstIndex,
							 | 
						||
| 
								 | 
							
								      intervalIndex,
							 | 
						||
| 
								 | 
							
								      currentInterval,
							 | 
						||
| 
								 | 
							
								      maxInterval,
							 | 
						||
| 
								 | 
							
								      start,
							 | 
						||
| 
								 | 
							
								      end,
							 | 
						||
| 
								 | 
							
								      max,
							 | 
						||
| 
								 | 
							
								      left,
							 | 
						||
| 
								 | 
							
								      right;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (stack.size) {
							 | 
						||
| 
								 | 
							
								    bstIndex = stack.pop();
							 | 
						||
| 
								 | 
							
								    intervalIndex = this.tree[bstIndex] - 1;
							 | 
						||
| 
								 | 
							
								    currentInterval = this.intervals[intervalIndex];
							 | 
						||
| 
								 | 
							
								    maxInterval = this.intervals[this.augmentations[intervalIndex]];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    max = this.endGetter ? this.endGetter(maxInterval) : maxInterval[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // No possible match, start is farther right than the max end value
							 | 
						||
| 
								 | 
							
								    if (intervalStart > max)
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Searching left
							 | 
						||
| 
								 | 
							
								    left = bstIndex * 2 + 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (left < l && this.tree[left] !== 0)
							 | 
						||
| 
								 | 
							
								      stack.push(left);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    start = this.startGetter ? this.startGetter(currentInterval) : currentInterval[0];
							 | 
						||
| 
								 | 
							
								    end = this.endGetter ? this.endGetter(currentInterval) : currentInterval[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Checking current node
							 | 
						||
| 
								 | 
							
								    if (intervalEnd >= start && intervalStart <= end)
							 | 
						||
| 
								 | 
							
								      matches.push(currentInterval);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // If the end is to the left of the start of the current interval,
							 | 
						||
| 
								 | 
							
								    // then it cannot be in the right child
							 | 
						||
| 
								 | 
							
								    if (intervalEnd < start)
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Searching right
							 | 
						||
| 
								 | 
							
								    right = bstIndex * 2 + 2;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (right < l && this.tree[right] !== 0)
							 | 
						||
| 
								 | 
							
								      stack.push(right);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return matches;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Convenience known methods.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								StaticIntervalTree.prototype.inspect = function() {
							 | 
						||
| 
								 | 
							
								  var proxy = this.intervals.slice();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Trick so that node displays the name of the constructor
							 | 
						||
| 
								 | 
							
								  Object.defineProperty(proxy, 'constructor', {
							 | 
						||
| 
								 | 
							
								    value: StaticIntervalTree,
							 | 
						||
| 
								 | 
							
								    enumerable: false
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return proxy;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (typeof Symbol !== 'undefined')
							 | 
						||
| 
								 | 
							
								  StaticIntervalTree.prototype[Symbol.for('nodejs.util.inspect.custom')] = StaticIntervalTree.prototype.inspect;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Static @.from function taking an arbitrary iterable & converting it into
							 | 
						||
| 
								 | 
							
								 * a structure.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {Iterable} iterable - Target iterable.
							 | 
						||
| 
								 | 
							
								 * @return {StaticIntervalTree}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								StaticIntervalTree.from = function(iterable, getters) {
							 | 
						||
| 
								 | 
							
								  if (iterables.isArrayLike(iterable))
							 | 
						||
| 
								 | 
							
								    return new StaticIntervalTree(iterable, getters);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return new StaticIntervalTree(Array.from(iterable), getters);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Exporting.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								module.exports = StaticIntervalTree;
							 |