(function(root,factory) {
	if (typeof define === "function" && define.amd) {
	define([], factory);
	} else if (typeof exports === "object") {
		module.exports = factory();
	} else {
		root.rafx = factory();
	}
}(this, function(){
	/*
	###############################
	###########INTERNALS###########
	###############################
	*/
	function Rafx(){
		this._processes = {};
		Object.defineProperty(
			this,
			"gcChance",
			{
				enumerable: false,
				configurable: false,
				set: function(v){gcChance = v;}
			}
		);
	};
	var window = this,
		prt = Rafx.prototype,
		rAF = window.requestAnimationFrame || function(f){return setTimeout(f, 17);},
		generateRandomString = function(){
			return (Math.random()*1e9 | 0).toString(16);
		},
		generateRandomID = function(){
			return generateRandomString() + generateRandomString();
		},
		randomSeed = generateRandomID(),
		noOP = function(){},
		fDel = function(prop){delete this[prop];},
		identity = function(v){return v;},
		boolRev = function(v){return !v;},
		empO = {},
		breaker = null,
		gcChance = 0.01,
		max = Math.max,
		getDonePointer = function(thenable,options){
			var status = options && options.done !== undefined 
					? options.done 
					: thenable.status,
				thenable = status.thenable;
			if(!thenable._child){
				thenable.then(noOP);
			}
			return status;
		},
		checkErrorTree = function(thenable){
			var lastError = null;
			while(thenable){
				if(thenable._isErrored){
					lastError = thenable._lastError;
					if(lastError){
						return lastError;
					} else {
						throw (prt._missingErrorError);
					}
				}
				thenable = thenable && thenable._child;
			}
			return null;
		},
		poke = function(thenable){
			thenable.isCompleted || thenable.then(noOP).catch(noOP);
			return thenable;
		},
		assign = function(target,sources){
			sources = Array.prototype.slice.call(arguments).slice(1);
			var d,
				i,
				l = sources.length,
				a,
				lA,
				j,
				k;
			for (i = 0; i < l; ++i){
				d = Object(sources[i]);
				a = Object.getOwnPropertyNames(d);
				lA = a.length;
				for (j = 0; j < lA; ++j) {
					k = a[j];
					target[k] = d[k];
				}
			}
			return target;
		},
		cancelTask = function(task){
			task.processed = true;
		},
		garbage = function(ngin){
			if(Math.random() > gcChance) {
				return;
			}
			var tasks = ngin.tasks,
				oLength = tasks.length,
				nTasks = Array(oLength),
				i = -1,
				j = 0,
				task = null;
			while (++i !== oLength) {
				task = tasks[i];
				if(!task.processed){
					nTasks[j++] = task;
				}
			}
			nTasks.length = j;
			ngin.tasks = nTasks;
		},
		Controller = function(id,instance){
			this.id = id;
			this.instance = instance;
		},
		Status = function(thenable,instance){
			this.thenable = thenable;
			this.instance = instance;
			this.isCompleted = false;
		},
		Duration = function(str){
			str += "";
			var match;
			this.unit = "f";
			this.val = 1;
			if(match = str && str.match(this.rgx)){
				this.set.unit(match[2] || "").val(match[1]);
			}
		},
		Ngin = function(){
			var that = this;
			this.tasks = [];
			this.frame = null;
			this.stroke = function(t){
				that.process(t);
			};
			this.cancelFrame = function(){
				window.cancelAnimationFrame(that.frame);
			};
		},
	/*
	###############################
	#############WATCH#############
	###############################
	*/
	//copied from Mutaframe.com - modified
		watch = function(obj,test,action,options){
			ngin.push({
				obj: obj,
				test: test,
				action: action,
				options: options,
				processed: false
			});
		},
		watchImmediate = function(obj,test,action,options){
			var task = {
				obj: obj,
				test: test,
				action: action,
				options: options,
				processed: false
			};
			if(test.call(obj,options,task)) {
				action.call(obj,options);
				return;
			}
			ngin.push(task);
		};
	/*
	###############################
	############WATCH##############
	###############################
	*/
	Object.defineProperties(
		Controller.prototype,
		{
			kill: {
				enumerable: false,
				configurable: false,
				get: function(){delete this.instance._processes[this.id];}
			},
			pause: {
				enumerable: false,
				configurable: false,
				get: function(){this.instance._processes[this.id] = false;}
			},
			resume: {
				enumerable: false,
				configurable: false,
				get: function(){this.instance._processes[this.id] = true;}
			}
		}
	);
	Object.defineProperties(
		Status.prototype,
		{
			code: {
				enumerable: false,
				configurable: false,
				get: function(){return this.isCompleted ? 1 : 0;}
			},
			string: {
				enumerable: false,
				configurable: false,
				get: function(){return this.text;}
			},
			text: {
				enumerable: false,
				configurable: false,
				get: function(){return this.isCompleted ? "completed" : this.thenable._invoked ? "pending" : "idle";}
			},
			valueOf: {
				enumerable: false,
				configurable: false,
				writable:false,
				value: function(){return this.code;}
			}
		}
	);
	Object.defineProperty(
		Duration.prototype,
		"set",
		{
			configurable:false,
			enumerable:false,
			get: function(){
				var that = this,
					value = function(v){return that.setVal.call(that,v);},
					unit = function(v){return that.setUnit.call(that,v);},
					valueOf = function(){return +that;}
				return {
					value: value,
					val: value,
					setVal: value,
					v: value,
					unit: unit,
					setUnit: unit,
					u: unit,
					back: that,
					b: that,
					parent: that,
					p: that,
					self: that,
					s:that,
					valueOf: valueOf
				};
			}
		}
	);
	Duration.prototype.rgx = /\s*([0-9]+|Infinity)\s*([a-z]+)?\s*/;
	Duration.prototype.trimRgx = /^\s*|\s*$/gi;
	Duration.prototype.keywords = {
		"": "f",
		f: "f",
		frames : "f",
		frame: "f",
		ms: "ms",
		milliseconds: "ms",
		millisecond: "ms",
		s: "s",
		second: "s",
		seconds: "s",
		min : "min",
		mins : "min",
		minute: "min",
		minutes: "min"		
	};
	Duration.prototype.unitToFrames = {
		f: 1,
		ms: 1/16.67,
		s: 60,
		min: 3600
	};
	Duration.prototype.setVal = function(v){
		this.val = max(+v,1) || 1;
		return this.set;
	};
	Duration.prototype.setUnit = function(v){
		v = ("" + v.replace(this.trimRgx,"")).toLowerCase();
		if(~Object.keys(this.keywords).indexOf(v)){
			return this.setVal(+this/this.unitToFrames[this.keywords[this.unit = v]]);
		} else {
			throw new SyntaxError(
				"Unit is not one of allowed keywords. "
				+ "For a list of allowed keywords, " 
				+ "inspect 'rafx.Duration.prototype.keywords'. "
			)
		}
	};
	Duration.prototype.step = function(v,step){
		var unit = this.unit,
			diff = +this + step * +(new Duration(v));
		return this.set.unit("frame").val(diff).unit(unit).self;
	};
	Duration.prototype.decrement = function(v){
		return this.step(v, -1);
	};
	Duration.prototype.increment = function(v){
		return this.step(v, 1);
	};
	Duration.prototype.valueOf = function(){
		return this.unitToFrames[this.keywords[this.unit]] * this.val;
	};
	Object.defineProperties(
		Ngin.prototype,
		{
			push: {
				enumerable: false,
				configurable: false,
				writable: false,
				value: function(taskObj){
					var tasks = this.tasks,
						length = tasks.length;
					tasks[length] = taskObj;
					if (!length) {
						rAF(this.stroke);
					} 
				}
			},
			process: {
				enumerable: false,
				configurable: false,
				writable: false,
				value: function(timestamp){
					var i = -1,
						processed = 0,
						isEmpty = true,
						task = null,
						tasks = this.tasks,
						obj = null,
						options = null,
						oLength = tasks.length;
					while (++i !== oLength) {
						task = tasks[i];
						isEmpty && (isEmpty = false);
						if (task.processed) {
							processed++;
							continue;
						}
						obj = task.obj;
						options = task.options;
						if (task.test.call(obj,options,task)) {
							task.action.call(obj,options);
							task.processed = true;
							processed++;
						}
					}
					if(!isEmpty){
						if(processed < i || tasks.length !== oLength) {
							this.frame = rAF(this.stroke);
							garbage(this);
						} else {
							this.tasks = [];
						}
					}
				}
			}
		}
	);
	/*
	###############################
	###########ENGINES#############
	###############################
	*/
	var ngin = new Ngin;
	/*
	###############################
	############ASYNC##############
	###############################
	*/
	prt.version = "0.0.20";
	prt.skipFrames = function(nFrames,argObj,parent,catcher,_breaker){
		_breaker = breaker || _breaker || {value:false};
		nFrames = nFrames instanceof this.skipFrames.Timer ? nFrames : new this.skipFrames.Timer(nFrames);
		var that = this,
			argObj = typeof argObj !== "object" 
				? {value:argObj,done:true} 
				: that.skipFrames.isExtractable(argObj)
					? argObj
					: {value:argObj,done:true};
					
		return new this.Thenable(this,nFrames,argObj,catcher,_breaker);
	};
	prt.Thenable = function(instance,nFrames,argObj,catcher,_breaker){
		this._breaker = _breaker;
		this._that = instance;
		this._nFrames = nFrames;
		this._argObj = argObj;
		this._instance = instance.skipFrames;
		this._invoked = false;
		this._child = null;
		this._isErrored = false;
		this._catch = catcher || null;
		this._lastError = null;
		this.status = new Status(this,instance);
	};
	prt.Thenable.prototype.valueOf = function(){
		return +this._invoked * +!this._isErrored * this.status.code;
	};
	prt.Thenable.prototype.then = function(f, rest){
		this._invoked = true;
		var _breaker = this._breaker,
			that = this._that,
			retVal = this._retVal = {value:undefined,done:false};
		watch(
			that,
			watchTest,
			watchAction,
			{
				f: f,
				rest: rest,
				nFrames: this._nFrames,
				_breaker: _breaker,
				argObj: this._argObj,
				that: that,
				thenable: this,
				retVal: retVal
			}
		);
		return this._child = that.skipFrames(new that.skipFrames.Timer(1),retVal,this,this._catch,_breaker);
	};
	prt.Thenable.prototype.break = function(){
		this._breaker.value = true;
		return this;
	};
	prt.Thenable.prototype.fThen 
	= prt.Thenable.prototype.forceThen
	= prt.Thenable.prototype.force
	= function(f, rest, options){
		var thenable = this,
			that = this._that,
			argObj = this._argObj,
			_breaker = this._breaker;
		poke(thenable);
		return that.async(
			{
				value:argObj,
				done:getDonePointer(thenable,options)
			},
			null,
			null,
			_breaker
		).then(function(v){
			var isError = v.value instanceof Error,
				result = {value: null, done: false};
			if(!isError){
				thenable.then(function(v){
					return (f || identity).call(this,v,rest);
				}).then(function(v){
					result.value = {value:v};
					result.done = true;
				}).catch(function(e){
					result.value = {value:e};
					result.done = true;
				});
			} else {
				result.value = {value: (options && options.throw) || v.value};
				result.done = true;
			}
			return result;
		}).catch(this._catch);
	};
	prt.Thenable.prototype.skipFrames = function(_nFrames){
		var that = this._that,
			argObj = this._argObj,
			_breaker = this._breaker;
		return this.then(function(){return that.skipFrames(new that.skipFrames.Timer(_nFrames),argObj,this,this._catch,_breaker);});
	};
	prt.Thenable.prototype.toBool = function(f, rest, options){
		var thenable = this,
			that = this._that,
			argObj = this._argObj,
			_breaker = this._breaker;
		poke(thenable);
		return that
		.async(
			{
				value:argObj,
				done:getDonePointer(thenable,options)
			},
			null,
			null,
			_breaker
		).then(function(v){
			var isError = v.value instanceof Error,
				error = null;
			if(!isError){
				return thenable.then(function(v){return (f || identity).call(this,!!v,rest);});
			} else {
				error = (options && options.throw) || that._nonBooleanCovertibleError;
				options && (options.error = error);
				throw(error);
			}
		}).catch(this._catch); 
	};
	
	prt.Thenable.prototype.filter = function(f, rest, options){
		var thenable = this,
			that = this._that,
			argObj = this._argObj,
			_breaker = this._breaker;
		poke(thenable);
		return that
		.async(
			{
				value:argObj,
				done: getDonePointer(thenable,options)
			},
			null,
			null,
			_breaker
		).then(function(v){
			if(v.value && v.value._instance === that.skipFrames) {
				return v.value.then(function(v){return {value:v};});
			} else {
				return {value:v,done:true};
			}
		}).then(function(v){
			var isError = v.value instanceof Error,
				error = isError ? v.value : null;
			if(!isError && (f || identity).call(thenable,v.value,rest)){
				return that.async(v.value,null,null,_breaker);
			} else {
				error = (options && options.throw) || error || that._validityError;
				options && (options.error = error);
				throw(error);
			}
		}).catch(noOP);
	};
	
	prt.Thenable.prototype.ifTruthy = function(f, rest, options){
		return this.filter(
				identity,
				null,
				assign(
					{throw:this._that._nonTruthyError},
					options
				)
			).then(f || identity, rest);
	};
	prt.Thenable.prototype.ifFalsey = function(f, rest, options){
		return this.filter(
				boolRev,
				null,
				assign(
					{throw:this._that._nonFalseyError},
					options
				)
			).then(f || identity, rest);
	};
	
	function thenableRecurse(f,rest,validator,_finally){
		var that = this._that,
			thenable = this,
			error = null,
			options = {};
		if(error = checkErrorTree(thenable)){
			_finally && _finally.call(thenable,"__fail",rest,{error:error}); 
			return;
		}
		thenable
			.then(function(v){return f.call(this,v,rest);})
			.filter(validator,rest,options)
			.then(function(v){_finally && _finally.call(thenable,v,rest);})
			.catch(function(v){
				if(v instanceof Error && v !== options.error){
					thenable._isErrored = true;
					thenable._lastError = v;
				}
				thenableRecurse.call(thenable,f,rest,validator,_finally);
			});
	};
	prt.Thenable.prototype.Untillable = function(that,thenable,state,f,rest){
		this.that = that;
		this.thenable = thenable;
		this.state = state;
		this.f = f;
		this.rest = rest;
		this._breaker = thenable._breaker;
	};
	prt.Thenable.prototype.Untillable.prototype.until = function(validator){
		var that = this.that,
			state = this.state,
			_breaker = this._breaker,
			error;
		thenableRecurse.call(this.thenable,this.f,this.rest,validator,function(v,rest,options){error = options && options.error; state.value = v; state.done = true;});
		return that.async(state,null,null,_breaker).then(function(v){if(v === "__fail"){throw error || that._recursionError;}else{return v;}});
	};
	prt.Thenable.prototype.Untillable.prototype.while = function(validator){
		var negValidator = function(v, rest){return !(validator || identity).call(this,v,rest);};
		return this.until(negValidator);
	};			
	prt.Thenable.prototype.recurse = prt.Thenable.prototype.loop = prt.Thenable.prototype.do = function(f, rest){
		var that = this._that,
			thenable = this,
			o = {value:undefined,done:false};
		return new thenable.Untillable(that,thenable,o,f,rest);
	};
	prt.Thenable.prototype.animateUntillable = function(that,thenable,state,f,rest){
		this.that = that;
		this.thenable = thenable;
		this.state = state;
		this.f = f;
		this.rest = rest;
		this._breaker = thenable._breaker;
	};
	prt.Thenable.prototype.animateUntillable.prototype.until = function(validator){
		return this.thenable.then(function(v, untillable){
			watch(
				this,
				untillable.test,
				untillable.action,
				{
					fFrame: untillable.f,
					v: v,
					rest: untillable.rest,
					validator: validator,
					state: untillable.state
				}
			);
			return untillable.state;
		}, this)
		.catch(noOP); 
	};
	prt.Thenable.prototype.animateUntillable.prototype.while = prt.Thenable.prototype.Untillable.prototype.while;
	prt.Thenable.prototype.animateUntillable.prototype.test  = function(opts){
		var state = opts.state,
			rest  = opts.rest;
		try {
			state.value = opts.fFrame.call(this, opts.v, rest);
			return this._breaker.value || opts.validator.call(this, state.value, rest);
		} catch (e) {
			return state.value = e;
		}
	};
	prt.Thenable.prototype.animateUntillable.prototype.action = function(opts){
		opts.state.done = true;
	};
	prt.Thenable.prototype.animate = prt.Thenable.prototype.recurseShallow = function(f, rest){
		var that = this._that,
			thenable = this,
			state = {value: void(0),done: false};
		return new thenable.animateUntillable(that,thenable,state,f,rest);
	};
	prt.ifInView = function(node, framesToKeep){
		return this.async(this.isInView(node, framesToKeep)).ifTruthy();
	};
	prt.ifNotInView = function(node, framesToKeep){
		return this.async(this.isInView(node, framesToKeep)).ifFalsey();
	};
	prt.Thenable.prototype.catch = function(f){
		if (typeof f === "function") {
			this._catch = f;
		}
		return this;
	};
	prt.skipFrames.Catcher = function(e){throw e;};
	prt.skipFrames.PerformCatch = function(instance,thenable,retVal){
		var child = thenable._child,
			value = retVal.value,
			isError = value instanceof Error,
			isHandled = isError && value._isHandled,
			defaultCatcher = prt.skipFrames.Catcher,
			catcher = (child && child._catch) || thenable._catch || defaultCatcher,
			mustCall = catcher !== defaultCatcher;
		if (!(child && child._invoked) && thenable._isErrored){
			if((isError && !isHandled) || !isError || mustCall) {
				value._isHandled = true;
				catcher.call(thenable,value);
			}
		}
	};
	prt.skipFrames.Extractor = function(instance,thenable,retVal,placeholder){
		retVal.value = placeholder.value; 
		retVal.done = placeholder.done;
		if (retVal.value instanceof Error) {
			thenable._isErrored = true;
			thenable._lastError = retVal.value;
		}
		return instance.skipFrames;
	};
	prt.skipFrames.isExtractable = function(o){
		return o 
			&& typeof o === "object" 
			&& o.hasOwnProperty("done") 
			&& o.hasOwnProperty("value");
	};
	prt.skipFrames.Timer = function (counter){
		this.counter = +counter || 1;
	};
	prt.skipFrames.Timer.prototype.valueOf = function(){
		return this.counter;
	};
	prt.skipFrames.Timer.prototype.decrement = function(){
		--this.counter;
		return this;
	};
	prt.async = function(o, rest, thisArg, _breaker){
		return this.skipFrames(1,typeof o === "function" ? o.call(thisArg || null, rest) : o,undefined,undefined,_breaker);
	};
	prt.repeat = function(f, rest, options){
		var that = this._that,
			id = generateRandomID(),
			controller = new Controller(id,this),
			thisArg = (options && options.thisArg) || null,
			handler = typeof (options && options.handler) === "function" 
				? options.handler
				: null,
			fR = function(){
				return f.call(
					thisArg,
					rest,
					controller
				);
			},
			fC = function(errorArg){
				controller.kill;
				if(errorArg){
					var error = (options && options.throw) 
						|| errorArg
						|| that._repetitionError;
					options && (options.error = errorArg);
					if(handler){
						handler.call(thisArg,error,rest);
					} else {
						throw(error);
					}
				} else if (handler) {
					handler.call(thisArg,null,rest);
				}
			};
		this._repeat(
			fR,
			rest,
			options,
			id,
			randomSeed,
			controller,
			fC
		);
		this._processes[id] = true;
		return id;
	};
	prt._repeat = function(fR,rest,options,id,seed,controller,fC){
		if(seed !== randomSeed){
			throw ( new Error("Cannot be manually called."));
		}
		this.async()
		.then(function(){return fR();})
		.catch(fC)
		.then(function(){
			var res = {value:true,done:false},
				thenable = this,
				that = this._that;
			if(that._processes.hasOwnProperty(id)) {
				if(that._processes[id]){
					res.done = true;
				} else {
					watch(
						that,
						function(options,task){
							if (this._processes[id] === undefined){
								cancelTask(task);
								res.value = false;
								res.done = true;
								fC.call(thenable);
							}
							return this._processes[id];
						},
						function(){res.done = true;},
						null
					);
				}
			} else {
				res.value = false;
				res.done = true;
				fC.call(thenable);
			}
			return res;
		}).then(function(value){
			value && this._that._repeat(fR,rest,options,id,seed,controller,fC);
		});
	};
	/*
	###############################
	############ASYNC##############
	###############################
	*/
	/*
	###############################
	###########UTILITY#############
	###############################
	*/
	prt.isInView = function(node,framesToKeep) {
		if(!!node){
			if(node.nodeType !== 1){
				return false;
			} else if (node.hasOwnProperty("_isInView")) {
				return node._isInView;
			}
		} else {
			return false;
		};
		var rect = node.getBoundingClientRect(),
			clH = Math.max(document.documentElement.clientHeight,window.innerHeight);
		this.skipFrames(+framesToKeep || 3).then(function(){delete node._isInView;});
		return node._isInView = !(rect.top > clH || rect.bottom < 0);
	};
	prt.throttle = function(f, rest, nFrames){
		nFrames = +nFrames || 0;
		var that = this,
			recurse = function(rest, args){f.call(this,args[0],rest,args);recurse.busy = false;};
		recurse.busy = false;
		return function(){
			if(recurse.busy){return}
			recurse.busy = true;
			that.skipFrames(+nFrames,rest).then(recurse, arguments);
		}
	};
	prt.duration = function(str){return new Duration(str);};
	/*
	###############################
	###########UTILITY#############
	###############################
	*/
	/*
	###############################
	###########INLINES#############
	###############################
	*/
	var watchTest = function(opts,task){
		var that = opts.that,
			thenable = opts.thenable,
			nFrames = opts.nFrames,
			_breaker = opts._breaker,
			argObj = opts.argObj,
			value = argObj.value;
		if(_breaker.value) {
			cancelTask(task);
			return false;
		}
		if(value && value._instance === that.skipFrames) {
			if(!value._invoked) {
				value.then(function(x){
					argObj.value = x;
				});
			} else if (value._isErrored){
				argObj.value = value._lastError;
				return true && (thenable.status.isCompleted = true);
			}
			return false;
		}
		return +argObj.done && nFrames.decrement() <= 0 && (thenable.status.isCompleted = true);
	},
	watchAction = function(opts){
		var that = opts.that,
			thenable = opts.thenable,
			_breaker = opts._breaker,
			argObj = opts.argObj,
			value = argObj.value,
			retVal = opts.retVal,
			placeholder = null,
			isExtractable = false;
		if(value instanceof Error){
			retVal.value = thenable._lastError = value;
			thenable._isErrored = true;
		} else {
			try {
				breaker = _breaker;
				placeholder = opts.f.call(thenable, value, opts.rest);
				if(!(isExtractable = that.skipFrames.isExtractable(placeholder))) {
					if ((retVal.value = placeholder) instanceof Error ){
						throw retVal.value;
					};
				}
			} catch (e) {
				retVal.value = thenable._lastError = e;
				thenable._isErrored = true;
			} finally {
				breaker = null;
			}
		}
		opts.placeholder = placeholder;
		if(isExtractable) {
			watchImmediate(
				null,
				watchImmediateTest,
				watchImmediateAction,
				opts
			);
		} else {
			retVal.done = true;
			that.skipFrames.PerformCatch(that,thenable,retVal);
		}
	},
	watchImmediateTest = function(opts,task){
		if(opts._breaker.value){
			cancelTask(task);
			return false;
		}
		return opts.placeholder.done;
	},
	watchImmediateAction = function(opts){
		var that = opts.that,
			thenable = opts.thenable,
			retVal = opts.retVal;
		that
		.skipFrames
		.Extractor(that,thenable,retVal,opts.placeholder)
		.PerformCatch(that,thenable,retVal);
	};
	/*
	###############################
	###########INLINES#############
	###############################
	*/
	/*
	################################
	############ERRORS##############
	################################
	*/
	Object.defineProperties(
		prt,
		{
			_recursionError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("An error has occured during recursion");}
			},
			_validityError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("Value Is Not Validated By Specified Function");}
			},
			_visibilityError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("Not In View Of Viewport");}
			},
			_nonTruthyError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("Value Cannot Be Converted To Truthy");}
			},
			_nonFalseyError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("Value Cannot Be Converted To Falsey");}
			},
			_nonBooleanCovertibleError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("Value Cannot Be Converted To Boolean");}
			},
			_missingErrorError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("Thenable marked as errored, but there is no error object attached");}
			},
			_repetitionError: {
				enumerable: false,
				configurable: false,
				get: function(){return new Error("An error has occured during repetition");}
			}
		}
	);
	/*
	################################
	############ERRORS##############
	################################
	*/
	return new Rafx();
}));