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.
		
		
		
		
		
			
		
			
				
					409 lines
				
				7.9 KiB
			
		
		
			
		
	
	
					409 lines
				
				7.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Mnemonist MultiMap
							 | 
						||
| 
								 | 
							
								 * ===================
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Implementation of a MultiMap with custom container.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var Iterator = require('obliterator/iterator'),
							 | 
						||
| 
								 | 
							
								    forEach = require('obliterator/foreach');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * MultiMap.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function MultiMap(Container) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.Container = Container || Array;
							 | 
						||
| 
								 | 
							
								  this.items = new Map();
							 | 
						||
| 
								 | 
							
								  this.clear();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  Object.defineProperty(this.items, 'constructor', {
							 | 
						||
| 
								 | 
							
								    value: MultiMap,
							 | 
						||
| 
								 | 
							
								    enumerable: false
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to clear the structure.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return {undefined}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.clear = function() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Properties
							 | 
						||
| 
								 | 
							
								  this.size = 0;
							 | 
						||
| 
								 | 
							
								  this.dimension = 0;
							 | 
						||
| 
								 | 
							
								  this.items.clear();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to set a value.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}      key   - Key.
							 | 
						||
| 
								 | 
							
								 * @param  {any}      value - Value to add.
							 | 
						||
| 
								 | 
							
								 * @return {MultiMap}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.set = function(key, value) {
							 | 
						||
| 
								 | 
							
								  var container = this.items.get(key),
							 | 
						||
| 
								 | 
							
								      sizeBefore;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!container) {
							 | 
						||
| 
								 | 
							
								    this.dimension++;
							 | 
						||
| 
								 | 
							
								    container = new this.Container();
							 | 
						||
| 
								 | 
							
								    this.items.set(key, container);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this.Container === Set) {
							 | 
						||
| 
								 | 
							
								    sizeBefore = container.size;
							 | 
						||
| 
								 | 
							
								    container.add(value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (sizeBefore < container.size)
							 | 
						||
| 
								 | 
							
								      this.size++;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else {
							 | 
						||
| 
								 | 
							
								    container.push(value);
							 | 
						||
| 
								 | 
							
								    this.size++;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return this;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to delete the given key.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}     key - Key to delete.
							 | 
						||
| 
								 | 
							
								 * @return {boolean}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.delete = function(key) {
							 | 
						||
| 
								 | 
							
								  var container = this.items.get(key);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!container)
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.size -= (this.Container === Set ? container.size : container.length);
							 | 
						||
| 
								 | 
							
								  this.dimension--;
							 | 
						||
| 
								 | 
							
								  this.items.delete(key);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to delete the remove an item in the container stored at the
							 | 
						||
| 
								 | 
							
								 * given key.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}     key - Key to delete.
							 | 
						||
| 
								 | 
							
								 * @return {boolean}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.remove = function(key, value) {
							 | 
						||
| 
								 | 
							
								  var container = this.items.get(key),
							 | 
						||
| 
								 | 
							
								      wasDeleted,
							 | 
						||
| 
								 | 
							
								      index;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!container)
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this.Container === Set) {
							 | 
						||
| 
								 | 
							
								    wasDeleted = container.delete(value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (wasDeleted)
							 | 
						||
| 
								 | 
							
								      this.size--;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (container.size === 0) {
							 | 
						||
| 
								 | 
							
								      this.items.delete(key);
							 | 
						||
| 
								 | 
							
								      this.dimension--;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return wasDeleted;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  else {
							 | 
						||
| 
								 | 
							
								    index = container.indexOf(value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (index === -1)
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.size--;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (container.length === 1) {
							 | 
						||
| 
								 | 
							
								      this.items.delete(key);
							 | 
						||
| 
								 | 
							
								      this.dimension--;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    container.splice(index, 1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to return whether the given keys exists in the map.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}     key - Key to check.
							 | 
						||
| 
								 | 
							
								 * @return {boolean}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.has = function(key) {
							 | 
						||
| 
								 | 
							
								  return this.items.has(key);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to return the container stored at the given key or `undefined`.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}     key - Key to get.
							 | 
						||
| 
								 | 
							
								 * @return {boolean}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.get = function(key) {
							 | 
						||
| 
								 | 
							
								  return this.items.get(key);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to return the multiplicity of the given key, meaning the number
							 | 
						||
| 
								 | 
							
								 * of times it is set, or, more trivially, the size of the attached container.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {any}     key - Key to check.
							 | 
						||
| 
								 | 
							
								 * @return {number}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.multiplicity = function(key) {
							 | 
						||
| 
								 | 
							
								  var container = this.items.get(key);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (typeof container === 'undefined')
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return this.Container === Set ? container.size : container.length;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.count = MultiMap.prototype.multiplicity;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to iterate over each of the key/value pairs.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {function}  callback - Function to call for each item.
							 | 
						||
| 
								 | 
							
								 * @param  {object}    scope    - Optional scope.
							 | 
						||
| 
								 | 
							
								 * @return {undefined}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.forEach = function(callback, scope) {
							 | 
						||
| 
								 | 
							
								  scope = arguments.length > 1 ? scope : this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Inner iteration function is created here to avoid creating it in the loop
							 | 
						||
| 
								 | 
							
								  var key;
							 | 
						||
| 
								 | 
							
								  function inner(value) {
							 | 
						||
| 
								 | 
							
								    callback.call(scope, value, key);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.items.forEach(function(container, k) {
							 | 
						||
| 
								 | 
							
								    key = k;
							 | 
						||
| 
								 | 
							
								    container.forEach(inner);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method used to iterate over each of the associations.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {function}  callback - Function to call for each item.
							 | 
						||
| 
								 | 
							
								 * @param  {object}    scope    - Optional scope.
							 | 
						||
| 
								 | 
							
								 * @return {undefined}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.forEachAssociation = function(callback, scope) {
							 | 
						||
| 
								 | 
							
								  scope = arguments.length > 1 ? scope : this;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.items.forEach(callback, scope);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning an iterator over the map's keys.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return {Iterator}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.keys = function() {
							 | 
						||
| 
								 | 
							
								  return this.items.keys();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning an iterator over the map's keys.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return {Iterator}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.values = function() {
							 | 
						||
| 
								 | 
							
								  var iterator = this.items.values(),
							 | 
						||
| 
								 | 
							
								      inContainer = false,
							 | 
						||
| 
								 | 
							
								      countainer,
							 | 
						||
| 
								 | 
							
								      step,
							 | 
						||
| 
								 | 
							
								      i,
							 | 
						||
| 
								 | 
							
								      l;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this.Container === Set)
							 | 
						||
| 
								 | 
							
								    return new Iterator(function next() {
							 | 
						||
| 
								 | 
							
								      if (!inContainer) {
							 | 
						||
| 
								 | 
							
								        step = iterator.next();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (step.done)
							 | 
						||
| 
								 | 
							
								          return {done: true};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        inContainer = true;
							 | 
						||
| 
								 | 
							
								        countainer = step.value.values();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      step = countainer.next();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (step.done) {
							 | 
						||
| 
								 | 
							
								        inContainer = false;
							 | 
						||
| 
								 | 
							
								        return next();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return {
							 | 
						||
| 
								 | 
							
								        done: false,
							 | 
						||
| 
								 | 
							
								        value: step.value
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return new Iterator(function next() {
							 | 
						||
| 
								 | 
							
								    if (!inContainer) {
							 | 
						||
| 
								 | 
							
								      step = iterator.next();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (step.done)
							 | 
						||
| 
								 | 
							
								        return {done: true};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      inContainer = true;
							 | 
						||
| 
								 | 
							
								      countainer = step.value;
							 | 
						||
| 
								 | 
							
								      i = 0;
							 | 
						||
| 
								 | 
							
								      l = countainer.length;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (i >= l) {
							 | 
						||
| 
								 | 
							
								      inContainer = false;
							 | 
						||
| 
								 | 
							
								      return next();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      done: false,
							 | 
						||
| 
								 | 
							
								      value: countainer[i++]
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning an iterator over the map's entries.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return {Iterator}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.entries = function() {
							 | 
						||
| 
								 | 
							
								  var iterator = this.items.entries(),
							 | 
						||
| 
								 | 
							
								      inContainer = false,
							 | 
						||
| 
								 | 
							
								      countainer,
							 | 
						||
| 
								 | 
							
								      step,
							 | 
						||
| 
								 | 
							
								      key,
							 | 
						||
| 
								 | 
							
								      i,
							 | 
						||
| 
								 | 
							
								      l;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (this.Container === Set)
							 | 
						||
| 
								 | 
							
								    return new Iterator(function next() {
							 | 
						||
| 
								 | 
							
								      if (!inContainer) {
							 | 
						||
| 
								 | 
							
								        step = iterator.next();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (step.done)
							 | 
						||
| 
								 | 
							
								          return {done: true};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        inContainer = true;
							 | 
						||
| 
								 | 
							
								        key = step.value[0];
							 | 
						||
| 
								 | 
							
								        countainer = step.value[1].values();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      step = countainer.next();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (step.done) {
							 | 
						||
| 
								 | 
							
								        inContainer = false;
							 | 
						||
| 
								 | 
							
								        return next();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return {
							 | 
						||
| 
								 | 
							
								        done: false,
							 | 
						||
| 
								 | 
							
								        value: [key, step.value]
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return new Iterator(function next() {
							 | 
						||
| 
								 | 
							
								    if (!inContainer) {
							 | 
						||
| 
								 | 
							
								      step = iterator.next();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (step.done)
							 | 
						||
| 
								 | 
							
								        return {done: true};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      inContainer = true;
							 | 
						||
| 
								 | 
							
								      key = step.value[0];
							 | 
						||
| 
								 | 
							
								      countainer = step.value[1];
							 | 
						||
| 
								 | 
							
								      i = 0;
							 | 
						||
| 
								 | 
							
								      l = countainer.length;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (i >= l) {
							 | 
						||
| 
								 | 
							
								      inContainer = false;
							 | 
						||
| 
								 | 
							
								      return next();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      done: false,
							 | 
						||
| 
								 | 
							
								      value: [key, countainer[i++]]
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning an iterator over the map's containers.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return {Iterator}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.containers = function() {
							 | 
						||
| 
								 | 
							
								  return this.items.values();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Method returning an iterator over the map's associations.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @return {Iterator}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.associations = function() {
							 | 
						||
| 
								 | 
							
								  return this.items.entries();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Attaching the #.entries method to Symbol.iterator if possible.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								if (typeof Symbol !== 'undefined')
							 | 
						||
| 
								 | 
							
								  MultiMap.prototype[Symbol.iterator] = MultiMap.prototype.entries;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Convenience known methods.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.inspect = function() {
							 | 
						||
| 
								 | 
							
								  return this.items;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if (typeof Symbol !== 'undefined')
							 | 
						||
| 
								 | 
							
								  MultiMap.prototype[Symbol.for('nodejs.util.inspect.custom')] = MultiMap.prototype.inspect;
							 | 
						||
| 
								 | 
							
								MultiMap.prototype.toJSON = function() {
							 | 
						||
| 
								 | 
							
								  return this.items;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Static @.from function taking an arbitrary iterable & converting it into
							 | 
						||
| 
								 | 
							
								 * a structure.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param  {Iterable} iterable  - Target iterable.
							 | 
						||
| 
								 | 
							
								 * @param  {Class}    Container - Container.
							 | 
						||
| 
								 | 
							
								 * @return {MultiMap}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								MultiMap.from = function(iterable, Container) {
							 | 
						||
| 
								 | 
							
								  var map = new MultiMap(Container);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  forEach(iterable, function(value, key) {
							 | 
						||
| 
								 | 
							
								    map.set(key, value);
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return map;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Exporting.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								module.exports = MultiMap;
							 |