| 
									
										
										
										
											2020-10-04 04:10:08 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							| 
									
										
										
										
											2020-10-06 01:32:33 +03:00
										 |  |  | **********************************************/  /* c8 ignore next 2 */ | 
					
						
							| 
									
										
										
										
											2020-10-04 04:10:08 +03:00
										 |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 23:50:05 +03:00
										 |  |  | var object = require('ig-object') | 
					
						
							| 
									
										
										
										
											2022-08-22 15:32:13 +03:00
										 |  |  | var stoppable = require('ig-stoppable') | 
					
						
							| 
									
										
										
										
											2020-10-04 04:10:08 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 15:32:13 +03:00
										 |  |  | // Wrap .map(..) / .filter(..) / .reduce(..) / .. to support STOP...
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // NOTE: internally these are implemented as for-of loops (./generator.js)
 | 
					
						
							|  |  |  | var stoppableSet = function(iter){ | 
					
						
							|  |  |  | 	return function(func){ | 
					
						
							|  |  |  | 		return new Set([...this][iter](...arguments)) } } | 
					
						
							|  |  |  | var stoppableValue = function(iter, no_return=false){ | 
					
						
							|  |  |  | 	return function(func){ | 
					
						
							|  |  |  | 		var res = [...this][iter](...arguments)  | 
					
						
							|  |  |  | 		return no_return ? | 
					
						
							|  |  |  | 			undefined | 
					
						
							|  |  |  | 			: res } } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 23:50:05 +03:00
										 |  |  | var SetProtoMixin = | 
					
						
							|  |  |  | module.SetProtoMixin = | 
					
						
							|  |  |  | object.Mixin('SetMixin', 'soft', { | 
					
						
							| 
									
										
										
										
											2021-06-23 09:05:19 +03:00
										 |  |  | 	iter: function*(){ | 
					
						
							|  |  |  | 		for(var e of this){ | 
					
						
							|  |  |  | 			yield e } }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 23:50:05 +03:00
										 |  |  | 	// Set set operation shorthands...
 | 
					
						
							|  |  |  | 	unite: function(other=[]){  | 
					
						
							|  |  |  | 		return new Set([...this, ...other]) }, | 
					
						
							|  |  |  | 	intersect: function(other){ | 
					
						
							|  |  |  | 		var test = other.has ?   | 
					
						
							|  |  |  | 			'has'  | 
					
						
							|  |  |  | 			: 'includes' | 
					
						
							|  |  |  | 		return new Set([...this] | 
					
						
							|  |  |  | 			.filter(function(e){  | 
					
						
							|  |  |  | 				return other[test](e) })) }, | 
					
						
							|  |  |  | 	subtract: function(other=[]){ | 
					
						
							|  |  |  | 		other = new Set(other) | 
					
						
							|  |  |  | 		return new Set([...this] | 
					
						
							|  |  |  | 			.filter(function(e){  | 
					
						
							|  |  |  | 				return !other.has(e) })) }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-03 02:11:02 +03:00
										 |  |  | 	sort: function(values=[]){ | 
					
						
							|  |  |  | 		values = (typeof(values) == 'function'  | 
					
						
							|  |  |  | 				|| values === undefined) ? | 
					
						
							|  |  |  | 			[...this].sort(values) | 
					
						
							|  |  |  | 			: values | 
					
						
							| 
									
										
										
										
											2020-11-22 23:50:05 +03:00
										 |  |  | 		var del = this.delete.bind(this) | 
					
						
							|  |  |  | 		var add = this.add.bind(this) | 
					
						
							| 
									
										
										
										
											2021-04-03 02:11:02 +03:00
										 |  |  | 		new Set([...values, ...this]) | 
					
						
							| 
									
										
										
										
											2020-11-22 23:50:05 +03:00
										 |  |  | 			.forEach(function(e){ | 
					
						
							|  |  |  | 				if(this.has(e)){ | 
					
						
							|  |  |  | 					del(e) | 
					
						
							|  |  |  | 					add(e) } }.bind(this)) | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2021-06-08 16:44:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-08 16:49:11 +03:00
										 |  |  | 	replace: function(old, value, ordered=true){ | 
					
						
							| 
									
										
										
										
											2021-06-08 16:44:51 +03:00
										 |  |  | 		// nothing to do...
 | 
					
						
							|  |  |  | 		if(!this.has(old) || old === value){ | 
					
						
							|  |  |  | 			return this } | 
					
						
							| 
									
										
										
										
											2021-06-08 16:49:11 +03:00
										 |  |  | 		if(ordered){ | 
					
						
							|  |  |  | 			var order = [...this] | 
					
						
							|  |  |  | 			// XXX is this fast enough???
 | 
					
						
							|  |  |  | 			order[order.lastIndexOf(old)] = value } | 
					
						
							| 
									
										
										
										
											2021-06-08 17:00:55 +03:00
										 |  |  | 		// replace...
 | 
					
						
							|  |  |  | 		this.delete(old) | 
					
						
							|  |  |  | 		this.add(value) | 
					
						
							|  |  |  | 		ordered | 
					
						
							|  |  |  | 			&& this.sort(order) | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2021-06-09 12:17:42 +03:00
										 |  |  | 	// NOTE: if index is <0 then the value is prepended to the set, if 
 | 
					
						
							|  |  |  | 	// 		it's >=this.size then the value will be appended.
 | 
					
						
							|  |  |  | 	// 		if ordered is set to false in both cases the value is appended.
 | 
					
						
							| 
									
										
										
										
											2021-06-13 13:59:20 +03:00
										 |  |  | 	// XXX should this be implemented via .splice(..) ???
 | 
					
						
							| 
									
										
										
										
											2021-06-08 19:21:20 +03:00
										 |  |  | 	replaceAt: function(index, value, ordered=true){ | 
					
						
							| 
									
										
										
										
											2021-06-09 12:17:42 +03:00
										 |  |  | 		// append...
 | 
					
						
							|  |  |  | 		if(index >= this.size){ | 
					
						
							|  |  |  | 			this.add(value) | 
					
						
							| 
									
										
										
										
											2021-06-08 17:00:55 +03:00
										 |  |  | 			return this } | 
					
						
							| 
									
										
										
										
											2021-06-09 12:17:42 +03:00
										 |  |  | 		// prepend...
 | 
					
						
							|  |  |  | 		if(index < 0){ | 
					
						
							|  |  |  | 			index = 0 | 
					
						
							|  |  |  | 			var order = [, ...this] | 
					
						
							|  |  |  | 		// replace...
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			var order = [...this] | 
					
						
							|  |  |  | 			var old = order[index]  | 
					
						
							|  |  |  | 			// nothing to do...
 | 
					
						
							|  |  |  | 			if(old === value){ | 
					
						
							|  |  |  | 				return this } } | 
					
						
							| 
									
										
										
										
											2021-06-08 17:00:55 +03:00
										 |  |  | 		ordered | 
					
						
							|  |  |  | 			&& (order[index] = value) | 
					
						
							| 
									
										
										
										
											2021-06-09 12:17:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-08 17:00:55 +03:00
										 |  |  | 		// replace...
 | 
					
						
							| 
									
										
										
										
											2021-06-09 12:17:42 +03:00
										 |  |  | 		this.has(old) | 
					
						
							|  |  |  | 			&& this.delete(old) | 
					
						
							| 
									
										
										
										
											2021-06-08 16:44:51 +03:00
										 |  |  | 		this.add(value) | 
					
						
							| 
									
										
										
										
											2021-06-09 12:17:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-08 16:49:11 +03:00
										 |  |  | 		ordered | 
					
						
							|  |  |  | 			&& this.sort(order) | 
					
						
							| 
									
										
										
										
											2021-06-08 16:44:51 +03:00
										 |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2021-06-13 13:59:20 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 15:12:57 +03:00
										 |  |  | 	// XXX do we need this???
 | 
					
						
							|  |  |  | 	// 		...should this be enough???
 | 
					
						
							|  |  |  | 	// 			new Set([...set].splice(..))
 | 
					
						
							| 
									
										
										
										
											2021-06-13 13:59:20 +03:00
										 |  |  | 	splice: function(from, count, ...items){ | 
					
						
							|  |  |  | 		var that = this | 
					
						
							|  |  |  | 		var order = [...this] | 
					
						
							|  |  |  | 		var removed = order.splice(...arguments) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// update the set...
 | 
					
						
							|  |  |  | 		removed.forEach(this.delete.bind(this)) | 
					
						
							|  |  |  | 		items.forEach(this.add.bind(this)) | 
					
						
							|  |  |  | 		this.sort(order)  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return removed }, | 
					
						
							| 
									
										
										
										
											2022-08-22 15:32:13 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	filter: stoppableSet('filter'), | 
					
						
							|  |  |  | 	map: stoppableSet('map'), | 
					
						
							|  |  |  | 	reduce: stoppableValue('reduce'), | 
					
						
							|  |  |  | 	reduceRight: stoppableValue('reduceRight'), | 
					
						
							|  |  |  | 	forEach: stoppableValue('map', true), | 
					
						
							| 
									
										
										
										
											2020-11-22 23:50:05 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SetProtoMixin(Set.prototype) | 
					
						
							| 
									
										
										
										
											2020-10-07 16:46:59 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-04 04:10:08 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |