whole_func_string: function compileCycle(key, p) {
  	const isMapSet = _types.mapSet[p.type];
  
  	const cantModI = !(p.type === 'array' || p.reverse || p.type === 'object' && p.notOwn && _hacks.OBJECT_KEYS_NATIVE_SUPPORT);
  
  	const cbArgs = cbArgsList.slice(0, p.length ? p.cbArgs : cbArgsList.length),
  	      filterArgs = [];
  
  	const maxArgsLength = p.length ? Math.max.apply(null, [].concat(p.cbArgs, p.filterArgs)) : cbArgsList.length,
  	      needParallel = p.parallel || p.race,
  	      parallelFn = p.parallel ? 'wait' : 'race',
  	      needCtx = maxArgsLength > 3 || needParallel || p.thread,
  	      fLength = p.filter.length;
  
  	for (let i = 0; i < fLength; i++) {
  		filterArgs.push(filterArgsList.slice(0, p.length ? p.filterArgs[i] : filterArgsList.length));
  	}
  
  	const resolveFilterVal = `f = ${p.inverseFilter ? '!' : ''}f && f !== FALSE || f === TRUE;`,
  	      callCycleFilter = `filters[fI](${filterArgsList.slice(0, p.length ? maxArgsLength : filterArgsList.length)})`;
  
  	let iFn = _string.ws`
  		var
  			data = o.data,
  			cb = o.cb,
  			baseCb = cb,
  			filters = o.filters;
  
  		var
  			count = o.count,
  			from = o.from,
  			startIndex = o.startIndex || 0,
  			endIndex = o.endIndex !== false ? o.endIndex + 1 : 0;
  
  		var
  			onIterationEnd = o.onIterationEnd,
  			onComplete = o.onComplete,
  			onError = o.onError;
  
  		var
  			TRUE = o.TRUE,
  			FALSE = o.FALSE,
  			IGNORE = o.IGNORE;
  
  		var
  			i = -1,
  			j = 0,
  			n = -1,
  			id = 0,
  			fI = -1;
  
  		var
  			breaker = false,
  			brkIf = false;
  
  		var
  			limit = 1,
  			looper = 0,
  			childResult;
  
  		var
  			fLength = filters.length,
  			length,
  			r,
  			f;
  
  		var
  			el,
  			key;
  	`;
  
  	if (p.withDescriptor) {
  		if (p.withProto) {
  			iFn += _string.ws`
  				var 
  					_getProto = Object.getPrototypeOf,
  					_getDescriptor = Object.getOwnPropertyDescriptor;
  
  				function getDescriptor(obj, key) {
  					while (obj) {
  						var 
  							desc = _getDescriptor(obj, key);
  
  						if (desc) {
  							return desc;
  						}
  
  						obj = _getProto(obj);
  					}
  				}
  			`;
  		} else {
  			iFn += 'var getDescriptor = Object.getOwnPropertyDescriptor;';
  		}
  	}
  
  	//#if iterators.async
  
  	if (p.async) {
  		iFn += _string.ws`
  			var
  				priority = o.priority,
  				maxParallel = o.maxParallel,
  				maxParallelIsNumber = typeof maxParallel === 'number';
  
  			var
  				done,
  				timeStart,
  				timeEnd,
  				time = 0;
  
  			var
  				thread = o.self,
  				thread = o.self,
  				yielder = false,
  				yieldVal;
  
  			function isPromise(obj) {
  				return obj && typeof obj.then === 'function' && typeof obj.catch === 'function';
  			}
  
  			var
  				rCbSet = new Set(),
  				rElSet = new Set();
  
  			function resolveCb(res) {
  				rCbSet.delete(r);
  				r = res;
  				thread.next();
  			}
  
  			function resolveEl(res) {
  				rElSet.delete(r);
  				el = res;
  				thread.next();
  			}
  
  			cb = function (${cbArgs}) {
  				var
  					f = ${fLength ? undefined : true},
  					fIsPromise = !done && isPromise(el),
  					res;
  
  				if (el === IGNORE || done) {
  					f = FALSE;
  					return;
  				}
  
  				if (fIsPromise) {
  					f = el.then(function (val) {
  						if (val === IGNORE) {
  							return FALSE;
  						}
  
  						if (brkIf && val === null) {
  							breaker = true;
  							return FALSE;
  						}
  
  						el = val;
  						return TRUE;
  					}, onError);
  				}
  		`;
  
  		if (fLength) {
  			if (fLength < 5) {
  				for (let i = 0; i < fLength; i++) {
  					const callFilter = `filters[${i}](${filterArgs[i]})`;
  
  					iFn += _string.ws`
  						if (${i ? 'f' : 'f === undefined || f'}) {
  							if (fIsPromise) {
  								f = f.then(function (f) {
  									${resolveFilterVal};
  
  									if (f) {
  										return ${callFilter};
  									}
  
  									return FALSE;
  								}, onError);
  
  							} else {
  								f = ${callFilter};
  								fIsPromise = isPromise(f);
  
  								if (!fIsPromise) {
  									${resolveFilterVal}
  								}
  							}
  						}
  					`;
  				}
  			} else {
  				iFn += _string.ws`
  					for (fI = -1; ++fI < fLength;) {
  						if (fIsPromise) {
  							f = f.then((function (fI) {
  								return function (f) {
  									${resolveFilterVal}
  
  									if (f) {
  										return ${callCycleFilter};
  
  									} else {
  										return FALSE;
  									}
  								};
  							})(fI), onError);
  
  						} else {
  							f = ${callCycleFilter};
  							fIsPromise = isPromise(f);
  
  							if (!fIsPromise) {
  								${resolveFilterVal}
  							}
  
  							if (!f) {
  								break;
  							}
  						}
  					}
  				`;
  			}
  		}
  
  		let fnCountHelper = '';
  
  		if (p.from) {
  			fnCountHelper += _string.ws`
  				if (from === 0) {
  					return;
  				}
  
  				from--;
  			`;
  		}
  
  		if (p.count) {
  			fnCountHelper += _string.ws`
  				if (j === count) {
  					return;
  				}
  
  				j++;
  			`;
  		}
  
  		iFn += _string.ws`
  			if (fIsPromise) {
  				f = f.then(function (f) {
  					${resolveFilterVal}
  
  					if (f) {
  						${fnCountHelper}
  						return baseCb(${cbArgs});
  					}
  				});
  
  				res = f;
  
  			} else if (f) {
  				${fnCountHelper}
  				res = baseCb(${cbArgs});
  			}
  		`;
  
  		if (needParallel) {
  			//#if iterators.async
  
  			iFn += _string.ws`
  				if (maxParallelIsNumber) {
  					ctx['${parallelFn}'](maxParallel, null, new Promise(function (r) { r(res); }));
  
  				} else {
  					ctx['${parallelFn}'](new Promise((r) => r(res)));
  				}
  			`;
  
  			//#endif
  		} else {
  			iFn += 'return res;';
  		}
  
  		iFn += '};';
  	}
  
  	//#endif
  
  	if (needCtx) {
  		iFn += _string.ws`
  			var ctx = {
  				$: {},
  				info: {
  					filters: filters.slice(0),
  					mult: ${p.mult},
  					startIndex: startIndex,
  					endIndex: endIndex,
  					from: from,
  					count: count,
  					live: ${p.live},
  					reverse: ${p.reverse},
  					withDescriptor: ${p.withDescriptor},
  					notOwn: ${p.notOwn},
  					inverseFilter: ${p.inverseFilter},
  					type: '${p.type}',
  					async: ${p.async},
  					thread: ${p.thread},
  					priority: ${p.thread} && '${p.priority}',
  					length: ${p.length}
  				},
  
  				true: TRUE,
  				false: FALSE,
  
  				cursor: o.cursor,
  				length: o.cbLength,
  				childResult: childResult,
  				onError: onError,
  
  				get result() {
  					return p.result;
  				},
  
  				set result(value) {
  					p.result = value;
  				},
  
  				get value() {
  					return yieldVal;
  				},
  
  				jump: function (val) {
  					if (${cantModI}) {
  						return false;
  					}
  
  					var diff = i - n;
  					n = val - 1;
  					i = n + diff;
  
  					return i;
  				},
  
  				i: function (val) {
  					if (val === undefined) {
  						return i;
  					}
  
  					if (${cantModI}) {
  						return false;
  					}
  
  					n += val;
  					i += val;
  
  					return i;
  				},
  
  				get id() {
  					return id;
  				},
  
  				get reset() {
  					breaker = true;
  					limit++;
  					return FALSE;
  				},
  
  				get break() {
  					breaker = true;
  					return FALSE;
  				}
  			};
  
  			var fCtx = Object.create(ctx);
  			fCtx.length = o.fLength;
  		`;
  
  		if (p.async) {
  			//#if iterators.async
  
  			iFn += _string.ws`
  				ctx.thread = thread;
  				thread.ctx = ctx;
  
  				var
  					parallelI = {null: {i: 0}},
  					raceI = {null: {i: 0}},
  					waiting = false;
  
  				var
  					waitStore = new Set(),
  					raceStore = new Set();
  
  				childResult = [];
  				function waitFactory(store, max, label, promise) {
  					if (!promise && label) {
  						promise = label;
  						label = null;
  					}
  
  					label = label || null;
  					var parallel = parallelI[label] = parallelI[label] || {i: 0};
  					parallel.max = max;
  
  					function end(err) {
  						parallel.i && parallel.i--;
  						var canNext = true;
  
  						for (var key in parallelI) {
  							if (!parallelI.hasOwnProperty(key)) {
  								break;
  							}
  
  							if (parallelI[key].i >= parallelI[key].max) {
  								canNext = false;
  								break;
  							}
  						}
  
  						canNext && thread.pause && ctx.next();
  					}
  
  					if (promise) {
  						parallel.i++;
  
  						if (parallel.i >= parallel.max) {
  							ctx.yield();
  						}
  
  						waitFactory(store, promise).then(end, function (err) {
  							if (err && err.type === 'CollectionThreadDestroy') {
  								end();
  							}
  						});
  
  						return promise;
  					}
  
  					if (!isPromise(promise = max)) {
  						promise = typeof promise.next === 'function' ? promise.next() : promise();
  					}
  
  					ctx.child(promise);
  					store.add(promise);
  
  					promise.then(
  						function (res) {
  							if (store.has(promise)) {
  								childResult.push(res);
  								store.delete(promise);
  							}
  
  							if (waiting) {
  								ctx.next();
  							}
  						},
  
  						function (err) {
  							if (err && err.type === 'CollectionThreadDestroy') {
  								store.delete(promise);
  								return;
  							}
  
  							onError(err);
  						}
  					);
  
  					return promise;
  				}
  
  				ctx.yield = function (opt_val) {
  					yielder = true;
  					yieldVal = opt_val;
  					return true;
  				};
  
  				ctx.next = function (opt_val) {
  					thread.next(opt_val);
  					return true;
  				};
  
  				ctx.child = function (obj) {
  					if (!obj.thread) {
  						return false;
  					}
  
  					thread.children.push(obj.thread);
  					return true;
  				};
  
  				ctx.race = function (max, label, promise) {
  					if (!promise) {
  						promise = label || max;
  						max = label != null ? max : 1;
  						label = null;
  					}
  
  					label = label || null;
  					var race = raceI[label] = raceI[label] || {i: 0};
  					race.max = max;
  
  					waitFactory(raceStore, promise).then(function () {
  						if (race.i < race.max) {
  							race.i++;
  
  							if (race.i === race.max) {
  								race.i = 0;
  								raceStore.clear();
  								done = true;
  							}
  						}
  					});
  
  					return promise;
  				};
  
  				ctx.wait = function (max, label, promise) {
  					return waitFactory(waitStore, max, label, promise);
  				};
  
  				ctx.sleep = function (time, opt_test, opt_interval) {
  					ctx.yield();
  					return new Promise(function (resolve, reject) {
  						var
  							sleep = thread.sleep;
  
  						if (sleep != null) {
  							sleep.resume();
  						}
  
  						sleep = thread.sleep = {
  							resume: function () {
  								clearTimeout(sleep.id);
  								thread.sleep = null;
  								resolve();
  							},
  
  							id: setTimeout(function () {
  								if (opt_test) {
  									try {
  										thread.sleep = null;
  										var test = opt_test(ctx);
  
  										if (test) {
  											resolve();
  											ctx.next();
  
  										} else if (opt_interval !== false) {
  											ctx.sleep(time, opt_test, opt_interval).then(resolve, reject);
  										}
  
  									} catch (err) {
  										reject(err);
  										onError(err);
  									}
  
  								} else {
  									resolve();
  									ctx.next();
  								}
  							}, time)
  						};
  					});
  				};
  			`;
  
  			//#endif
  		} else {
  			iFn += _string.ws`
  				ctx.yield = ctx.next = ctx.child = ctx.race = ctx.wait = ctx.sleep = o.notAsync;
  			`;
  		}
  	}
  
  	let threadStart = '',
  	    threadEnd = '';
  
  	//#if iterators.async
  	//#if iterators.thread
  
  	if (p.async && p.thread) {
  		threadStart = _string.ws`
  			if (timeStart == null) {
  				timeStart = new Date().valueOf();
  			}
  		`;
  
  		threadEnd = _string.ws`
  			timeEnd = new Date().valueOf();
  			time += timeEnd - timeStart;
  			timeStart = timeEnd;
  
  			if (time > priority[thread.priority]) {
  				yield;
  				time = 0;
  				timeStart = null;
  			}
  		`;
  	}
  
  	//#endif
  	//#endif
  
  	iFn += 'while (limit !== looper) {';
  
  	let yielder = '',
  	    asyncWait = '';
  
  	//#if iterators.async
  
  	if (p.async) {
  		iFn += 'done = false;';
  		yielder = _string.ws`
  			if (yielder) {
  				yielder = false;
  				thread.pause = true;
  				yieldVal = yield yieldVal;
  			}
  		`;
  
  		if (needCtx) {
  			asyncWait = _string.ws`
  				waiting = true;
  
  				while (waitStore.size) {
  					thread.pause = true;
  					yield;
  				}
  
  				while (raceStore.size) {
  					thread.pause = true;
  					yield;
  				}
  			`;
  		}
  	}
  
  	//#endif
  
  	let indexLimits = '';
  
  	if (p.startIndex) {
  		indexLimits = _string.ws`
  			if (n < startIndex) {
  				${threadEnd}
  				continue;
  			}
  		`;
  	}
  
  	if (p.endIndex) {
  		indexLimits += _string.ws`
  			if (n > endIndex) {
  				${threadEnd}
  				break;
  			};
  		`;
  	}
  
  	const defArgs = maxArgsLength || p.async;
  
  	switch (p.type) {
  		case 'array':
  			iFn += _string.ws`
  				var
  					clone = data,
  					dLength = data.length - 1,
  					slice = IGNORE.slice;
  			`;
  
  			if (p.reverse) {
  				iFn += 'clone = slice.call(clone).reverse();';
  			}
  
  			if ((p.reverse || !p.live) && (p.startIndex || p.endIndex)) {
  				iFn += _string.ws`
  					clone = slice.call(clone, startIndex, endIndex || data.length);
  				`;
  			}
  
  			if (!p.reverse && p.live) {
  				iFn += _string.ws`
  					for (n = startIndex - 1; ++n < clone.length;) {
  						${threadStart}
  						i = n;
  						${indexLimits}
  				`;
  			} else {
  				iFn += _string.ws`
  					length = clone.length;
  					for (n = -1; ++n < length;) {
  						${threadStart}
  						i = n + startIndex;
  				`;
  			}
  
  			if (defArgs) {
  				if (maxArgsLength > 1) {
  					if (p.startIndex) {
  						iFn += `key = ${p.reverse ? 'dLength - (' : ''} n + startIndex ${p.reverse ? ')' : ''};`;
  					} else {
  						iFn += `key = ${p.reverse ? 'dLength - ' : ''} n;`;
  					}
  				}
  
  				if (p.withDescriptor) {
  					iFn += 'el = getDescriptor(clone, n);';
  				} else {
  					iFn += 'el = clone[n];';
  				}
  			}
  
  			break;
  
  		case 'object':
  			iFn += _string.ws`
  				var
  					selfHasOwn = data.hasOwnProperty,
  					hasOwnProperty = IGNORE.hasOwnProperty;
  			`;
  
  			if (p.reverse || _hacks.OBJECT_KEYS_NATIVE_SUPPORT && !p.notOwn) {
  				iFn += 'var tmpArray;';
  
  				if (!p.notOwn && _hacks.OBJECT_KEYS_NATIVE_SUPPORT && !p.async) {
  					iFn += 'tmpArray = Object.keys(data);';
  				} else {
  					iFn += 'tmpArray = [];';
  
  					if (p.notOwn) {
  						if (p.notOwn === -1) {
  							iFn += _string.ws`
  								for (key in data) {
  									${threadStart}
  									if (selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key)) {
  										continue;
  									}
  
  									tmpArray.push(key);
  									${threadEnd}
  								}
  							`;
  						} else {
  							iFn += _string.ws`
  								for (key in data) {
  									${threadStart}
  									tmpArray.push(key);
  									${threadEnd}
  								}
  							`;
  						}
  					} else {
  						iFn += _string.ws`
  							for (key in data) {
  								${threadStart}
  								if (!(selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key))) {
  									break;
  								}
  
  								tmpArray.push(key);
  								${threadEnd}
  							}
  						`;
  					}
  				}
  
  				if (p.reverse) {
  					iFn += 'tmpArray.reverse();';
  				}
  
  				if (p.startIndex || p.endIndex) {
  					iFn += `tmpArray = tmpArray.slice(startIndex, endIndex || tmpArray.length);`;
  				}
  
  				iFn += _string.ws`
  					length = tmpArray.length;
  					for (n = -1; ++n < length;) {
  						${threadStart}
  						key = tmpArray[n];
  
  						if (key in data === false) {
  							${threadEnd}
  							continue;
  						}
  
  						i = n + startIndex;
  				`;
  			} else {
  				iFn += _string.ws`
  					for (key in data) {
  						${threadStart}
  				`;
  
  				if (p.notOwn === false) {
  					iFn += _string.ws`
  						if (!(selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key))) {
  							${threadEnd}
  							break;
  						}`;
  				} else if (p.notOwn === -1) {
  					iFn += _string.ws`
  						if (selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key)) {
  							${threadEnd}
  							continue;
  						}`;
  				}
  
  				iFn += _string.ws`
  					n++;
  					i = n;
  					${indexLimits}
  				`;
  			}
  
  			if (defArgs) {
  				if (p.withDescriptor) {
  					iFn += 'el = getDescriptor(data, key);';
  				} else {
  					iFn += 'el = data[key];';
  				}
  			}
  
  			break;
  
  		case 'map':
  		case 'set':
  		case 'generator':
  		case 'iterator':
  		case 'asyncIterator':
  			if (isMapSet) {
  				iFn += 'var cursor = data.keys();';
  
  				if (!p.live && !p.reverse) {
  					iFn += 'var size = data.size;';
  				}
  			} else if (p.type === 'generator') {
  				iFn += 'var cursor = data();';
  			} else {
  				iFn += _string.ws`
  					var
  						iteratorKey = typeof Symbol !== 'undefined' && Symbol.iterator,
  						cursor;
  
  					if (typeof data.next === 'function') {
  						cursor = data;
  
  					} else {
  						cursor = (iteratorKey ? data[iteratorKey]() : data['@@iterator'] && data['@@iterator']()) || data;
  					}
  				`;
  			}
  
  			iFn += _string.ws`
  				${p.reverse ? 'var tmpArray = [];' : ''}
  
  				for (
  					key = cursor.next(), brkIf = ('done' in key === false);
  					'done' in key ? !key.done : key;
  					key = cursor.next()
  				) {
  					${threadStart}
  			`;
  
  			let asyncIterator = '';
  
  			//#if iterators.async
  
  			if (p.type === 'asyncIterator') {
  				asyncIterator = _string.ws`
  					while (isPromise(el)) {
  						if (!rElSet.has(el)) {
  							rElSet.add(el);
  							el.then(resolveEl, onError);
  						}
  
  						thread.pause = true;
  						yield;
  					}
  				`;
  			}
  
  			//#endif
  
  			if (p.reverse) {
  				iFn += `el = 'value' in key ? key.value : key; ${asyncIterator}`;
  
  				//#if iterators.async
  
  				if (needParallel) {
  					iFn += _string.ws`
  						if (maxParallelIsNumber) {
  							if (isPromise(el)) {
  								ctx['${parallelFn}'](maxParallel, null, el);
  							}
  
  							${yielder}
  						}
  					`;
  				}
  
  				//#endif
  
  				iFn += _string.ws`
  						if (el !== IGNORE) {
  							if (brkIf && el === null) {
  								${threadEnd}
  								break;
  							}
  
  							tmpArray.push(el);
  						}
  
  						${threadEnd}
  					}
  
  					${asyncWait}
  					tmpArray.reverse();
  					var size = tmpArray.length;
  				`;
  
  				if (p.startIndex || p.endIndex) {
  					iFn += `tmpArray = tmpArray.slice(startIndex, endIndex || tmpArray.length);`;
  				}
  
  				iFn += _string.ws`
  					length = size;
  					for (n = -1; ++n < length;) {
  						${threadStart}
  						${defArgs ? 'key = tmpArray[n];' : ''}
  						i = n + startIndex;
  				`;
  			} else {
  				iFn += _string.ws`
  					${defArgs ? `key = 'value' in key ? key.value : key;` : ''}
  					n++;
  					i = n;
  					${indexLimits}
  				`;
  			}
  
  			if (defArgs) {
  				if (p.type === 'map') {
  					iFn += 'el = data.get(key);';
  				} else {
  					iFn += `el = key; ${asyncIterator}`;
  
  					if (maxArgsLength > 1) {
  						if (p.type === 'set') {
  							iFn += 'key = null;';
  						} else if (p.reverse) {
  							iFn += 'key = size - i - 1;';
  						} else {
  							iFn += 'key = i;';
  						}
  					}
  				}
  			}
  
  			break;
  	}
  
  	if (needCtx) {
  		iFn += 'id++;';
  	}
  
  	if (p.count) {
  		iFn += _string.ws`
  			if (j === count) {
  				${threadEnd}
  				break;
  			}
  		`;
  	}
  
  	let tmp = '';
  
  	if (!p.async) {
  		if (fLength) {
  			if (fLength < 5) {
  				for (let i = 0; i < fLength; i++) {
  					iFn += _string.ws`
  						if (${i ? 'f' : 'true'}) {
  							f = filters[${i}](${filterArgs[i]});
  							${resolveFilterVal}
  						}
  					`;
  				}
  			} else {
  				iFn += _string.ws`
  					for (fI = -1; ++fI < fLength;) {
  						f = ${callCycleFilter};
  						${resolveFilterVal}
  
  						if (!f) {
  							break;
  						}
  					}
  				`;
  			}
  
  			iFn += 'if (f) {';
  		}
  
  		if (p.count) {
  			tmp += 'j++;';
  		}
  	}
  
  	tmp += `r = cb(${cbArgs});`;
  
  	if (!p.mult) {
  		tmp += 'breaker = true;';
  	}
  
  	//#if iterators.async
  
  	if (p.async) {
  		tmp += _string.ws`
  			while (isPromise(r)) {
  				if (!rCbSet.has(r)) {
  					rCbSet.add(r);
  					r.then(resolveCb, onError);
  				}
  
  				thread.pause = true;
  				yield;
  			}
  		`;
  	}
  
  	//#endif
  
  	if (!p.async && p.from) {
  		iFn += _string.ws`
  			if (from !== 0) {
  				from--;
  
  			} else {
  				${tmp}
  			}
  		`;
  	} else {
  		iFn += tmp;
  	}
  
  	if (!p.async && fLength) {
  		iFn += '}';
  	}
  
  	iFn += yielder;
  	if (!p.live && !p.reverse && isMapSet) {
  		iFn += _string.ws`
  			size--;
  
  			if (!size) {
  				${threadEnd}
  				break;
  			}
  		`;
  	}
  
  	iFn += _string.ws`
  			${threadEnd}
  
  			if (breaker${p.async ? '|| done' : ''}) {
  				break;
  			}
  		}
  
  		breaker = false;
  		looper++;
  
  		if (onIterationEnd) {
  			onIterationEnd(${needCtx ? 'ctx' : ''});
  		}
  	`;
  
  	iFn += _string.ws`
  			${yielder}
  		}
  
  		${asyncWait}
  
  		if (onComplete) {
  			${p.async ? 'done = true;' : ''}
  			onComplete(p.result);
  		}
  
  		return p.result;
  	`;
  
  	if (p.async) {
  		//#if iterators.async
  		_cache.tmpCycle[key] = new Function(`return function *(o, p) { ${iFn} };`)();
  		//#endif
  	} else {
  		_cache.tmpCycle[key] = new Function('o', 'p', iFn);
  	}
  
  	if (_core2.default.ready) {
  		const delay = 5e3;
  
  		const text = `${_base.NAMESPACE}.cache.cycle["${key}"] = ${_cache.tmpCycle[key].toString()};`;
  		cache[key] = text;
  
  		if (_hacks.IS_BROWSER && _hacks.LOCAL_STORAGE_SUPPORT) {
  			clearTimeout(timeout);
  			timeout = setTimeout(() => {
  				try {
  					localStorage.setItem(_base.CACHE_KEY, JSON.stringify(cache));
  					localStorage.setItem(_base.CACHE_VERSION_KEY, _base.CACHE_VERSION);
  
  					if (_hacks.BLOB_SUPPORT) {
  						const script = document.createElement('script');
  						script.src = URL.createObjectURL(new Blob([text], { type: 'application/javascript' }));
  						document.head.appendChild(script);
  					}
  				} catch (_) {}
  			}, delay);
  		} else if (_hacks.IS_NODE) {
  			//#if isNode
  			clearTimeout(timeout);
  			timeout = setTimeout(() => {
  				require('fs').writeFile(require('path').join(__dirname, 'collection.tmp.js'), `
  						exports.version = ${_base.CACHE_VERSION};
  						exports.cache = ${JSON.stringify(cache)};
  						exports.exec = function () { ${returnCache(cache)} };
  					`, () => {});
  			}, delay);
  
  			timeout['unref']();
  			//#endif
  		}
  	}
  
  	return _cache.tmpCycle[key];
  }
func_code_string: function compileCycle(key, p) {
  	const isMapSet = _types.mapSet[p.type];
  
  	const cantModI = !(p.type === 'array' || p.reverse || p.type === 'object' && p.notOwn && _hacks.OBJECT_KEYS_NATIVE_SUPPORT);
  
  	const cbArgs = cbArgsList.slice(0, p.length ? p.cbArgs : cbArgsList.length),
  	      filterArgs = [];
  
  	const maxArgsLength = p.length ? Math.max.apply(null, [].concat(p.cbArgs, p.filterArgs)) : cbArgsList.length,
  	      needParallel = p.parallel || p.race,
  	      parallelFn = p.parallel ? 'wait' : 'race',
  	      needCtx = maxArgsLength > 3 || needParallel || p.thread,
  	      fLength = p.filter.length;
  
  	for (let i = 0; i < fLength; i++) {
  		filterArgs.push(filterArgsList.slice(0, p.length ? p.filterArgs[i] : filterArgsList.length));
  	}
  
  	const resolveFilterVal = `f = ${p.inverseFilter ? '!' : ''}f && f !== FALSE || f === TRUE;`,
  	      callCycleFilter = `filters[fI](${filterArgsList.slice(0, p.length ? maxArgsLength : filterArgsList.length)})`;
  
  	let iFn = _string.ws`
  		var
  			data = o.data,
  			cb = o.cb,
  			baseCb = cb,
  			filters = o.filters;
  
  		var
  			count = o.count,
  			from = o.from,
  			startIndex = o.startIndex || 0,
  			endIndex = o.endIndex !== false ? o.endIndex + 1 : 0;
  
  		var
  			onIterationEnd = o.onIterationEnd,
  			onComplete = o.onComplete,
  			onError = o.onError;
  
  		var
  			TRUE = o.TRUE,
  			FALSE = o.FALSE,
  			IGNORE = o.IGNORE;
  
  		var
  			i = -1,
  			j = 0,
  			n = -1,
  			id = 0,
  			fI = -1;
  
  		var
  			breaker = false,
  			brkIf = false;
  
  		var
  			limit = 1,
  			looper = 0,
  			childResult;
  
  		var
  			fLength = filters.length,
  			length,
  			r,
  			f;
  
  		var
  			el,
  			key;
  	`;
  
  	if (p.withDescriptor) {
  		if (p.withProto) {
  			iFn += _string.ws`
  				var 
  					_getProto = Object.getPrototypeOf,
  					_getDescriptor = Object.getOwnPropertyDescriptor;
  
  				function getDescriptor(obj, key) {
  					while (obj) {
  						var 
  							desc = _getDescriptor(obj, key);
  
  						if (desc) {
  							return desc;
  						}
  
  						obj = _getProto(obj);
  					}
  				}
  			`;
  		} else {
  			iFn += 'var getDescriptor = Object.getOwnPropertyDescriptor;';
  		}
  	}
  
  	//#if iterators.async
  
  	if (p.async) {
  		iFn += _string.ws`
  			var
  				priority = o.priority,
  				maxParallel = o.maxParallel,
  				maxParallelIsNumber = typeof maxParallel === 'number';
  
  			var
  				done,
  				timeStart,
  				timeEnd,
  				time = 0;
  
  			var
  				thread = o.self,
  				thread = o.self,
  				yielder = false,
  				yieldVal;
  
  			function isPromise(obj) {
  				return obj && typeof obj.then === 'function' && typeof obj.catch === 'function';
  			}
  
  			var
  				rCbSet = new Set(),
  				rElSet = new Set();
  
  			function resolveCb(res) {
  				rCbSet.delete(r);
  				r = res;
  				thread.next();
  			}
  
  			function resolveEl(res) {
  				rElSet.delete(r);
  				el = res;
  				thread.next();
  			}
  
  			cb = function (${cbArgs}) {
  				var
  					f = ${fLength ? undefined : true},
  					fIsPromise = !done && isPromise(el),
  					res;
  
  				if (el === IGNORE || done) {
  					f = FALSE;
  					return;
  				}
  
  				if (fIsPromise) {
  					f = el.then(function (val) {
  						if (val === IGNORE) {
  							return FALSE;
  						}
  
  						if (brkIf && val === null) {
  							breaker = true;
  							return FALSE;
  						}
  
  						el = val;
  						return TRUE;
  					}, onError);
  				}
  		`;
  
  		if (fLength) {
  			if (fLength < 5) {
  				for (let i = 0; i < fLength; i++) {
  					const callFilter = `filters[${i}](${filterArgs[i]})`;
  
  					iFn += _string.ws`
  						if (${i ? 'f' : 'f === undefined || f'}) {
  							if (fIsPromise) {
  								f = f.then(function (f) {
  									${resolveFilterVal};
  
  									if (f) {
  										return ${callFilter};
  									}
  
  									return FALSE;
  								}, onError);
  
  							} else {
  								f = ${callFilter};
  								fIsPromise = isPromise(f);
  
  								if (!fIsPromise) {
  									${resolveFilterVal}
  								}
  							}
  						}
  					`;
  				}
  			} else {
  				iFn += _string.ws`
  					for (fI = -1; ++fI < fLength;) {
  						if (fIsPromise) {
  							f = f.then((function (fI) {
  								return function (f) {
  									${resolveFilterVal}
  
  									if (f) {
  										return ${callCycleFilter};
  
  									} else {
  										return FALSE;
  									}
  								};
  							})(fI), onError);
  
  						} else {
  							f = ${callCycleFilter};
  							fIsPromise = isPromise(f);
  
  							if (!fIsPromise) {
  								${resolveFilterVal}
  							}
  
  							if (!f) {
  								break;
  							}
  						}
  					}
  				`;
  			}
  		}
  
  		let fnCountHelper = '';
  
  		if (p.from) {
  			fnCountHelper += _string.ws`
  				if (from === 0) {
  					return;
  				}
  
  				from--;
  			`;
  		}
  
  		if (p.count) {
  			fnCountHelper += _string.ws`
  				if (j === count) {
  					return;
  				}
  
  				j++;
  			`;
  		}
  
  		iFn += _string.ws`
  			if (fIsPromise) {
  				f = f.then(function (f) {
  					${resolveFilterVal}
  
  					if (f) {
  						${fnCountHelper}
  						return baseCb(${cbArgs});
  					}
  				});
  
  				res = f;
  
  			} else if (f) {
  				${fnCountHelper}
  				res = baseCb(${cbArgs});
  			}
  		`;
  
  		if (needParallel) {
  			//#if iterators.async
  
  			iFn += _string.ws`
  				if (maxParallelIsNumber) {
  					ctx['${parallelFn}'](maxParallel, null, new Promise(function (r) { r(res); }));
  
  				} else {
  					ctx['${parallelFn}'](new Promise((r) => r(res)));
  				}
  			`;
  
  			//#endif
  		} else {
  			iFn += 'return res;';
  		}
  
  		iFn += '};';
  	}
  
  	//#endif
  
  	if (needCtx) {
  		iFn += _string.ws`
  			var ctx = {
  				$: {},
  				info: {
  					filters: filters.slice(0),
  					mult: ${p.mult},
  					startIndex: startIndex,
  					endIndex: endIndex,
  					from: from,
  					count: count,
  					live: ${p.live},
  					reverse: ${p.reverse},
  					withDescriptor: ${p.withDescriptor},
  					notOwn: ${p.notOwn},
  					inverseFilter: ${p.inverseFilter},
  					type: '${p.type}',
  					async: ${p.async},
  					thread: ${p.thread},
  					priority: ${p.thread} && '${p.priority}',
  					length: ${p.length}
  				},
  
  				true: TRUE,
  				false: FALSE,
  
  				cursor: o.cursor,
  				length: o.cbLength,
  				childResult: childResult,
  				onError: onError,
  
  				get result() {
  					return p.result;
  				},
  
  				set result(value) {
  					p.result = value;
  				},
  
  				get value() {
  					return yieldVal;
  				},
  
  				jump: function (val) {
  					if (${cantModI}) {
  						return false;
  					}
  
  					var diff = i - n;
  					n = val - 1;
  					i = n + diff;
  
  					return i;
  				},
  
  				i: function (val) {
  					if (val === undefined) {
  						return i;
  					}
  
  					if (${cantModI}) {
  						return false;
  					}
  
  					n += val;
  					i += val;
  
  					return i;
  				},
  
  				get id() {
  					return id;
  				},
  
  				get reset() {
  					breaker = true;
  					limit++;
  					return FALSE;
  				},
  
  				get break() {
  					breaker = true;
  					return FALSE;
  				}
  			};
  
  			var fCtx = Object.create(ctx);
  			fCtx.length = o.fLength;
  		`;
  
  		if (p.async) {
  			//#if iterators.async
  
  			iFn += _string.ws`
  				ctx.thread = thread;
  				thread.ctx = ctx;
  
  				var
  					parallelI = {null: {i: 0}},
  					raceI = {null: {i: 0}},
  					waiting = false;
  
  				var
  					waitStore = new Set(),
  					raceStore = new Set();
  
  				childResult = [];
  				function waitFactory(store, max, label, promise) {
  					if (!promise && label) {
  						promise = label;
  						label = null;
  					}
  
  					label = label || null;
  					var parallel = parallelI[label] = parallelI[label] || {i: 0};
  					parallel.max = max;
  
  					function end(err) {
  						parallel.i && parallel.i--;
  						var canNext = true;
  
  						for (var key in parallelI) {
  							if (!parallelI.hasOwnProperty(key)) {
  								break;
  							}
  
  							if (parallelI[key].i >= parallelI[key].max) {
  								canNext = false;
  								break;
  							}
  						}
  
  						canNext && thread.pause && ctx.next();
  					}
  
  					if (promise) {
  						parallel.i++;
  
  						if (parallel.i >= parallel.max) {
  							ctx.yield();
  						}
  
  						waitFactory(store, promise).then(end, function (err) {
  							if (err && err.type === 'CollectionThreadDestroy') {
  								end();
  							}
  						});
  
  						return promise;
  					}
  
  					if (!isPromise(promise = max)) {
  						promise = typeof promise.next === 'function' ? promise.next() : promise();
  					}
  
  					ctx.child(promise);
  					store.add(promise);
  
  					promise.then(
  						function (res) {
  							if (store.has(promise)) {
  								childResult.push(res);
  								store.delete(promise);
  							}
  
  							if (waiting) {
  								ctx.next();
  							}
  						},
  
  						function (err) {
  							if (err && err.type === 'CollectionThreadDestroy') {
  								store.delete(promise);
  								return;
  							}
  
  							onError(err);
  						}
  					);
  
  					return promise;
  				}
  
  				ctx.yield = function (opt_val) {
  					yielder = true;
  					yieldVal = opt_val;
  					return true;
  				};
  
  				ctx.next = function (opt_val) {
  					thread.next(opt_val);
  					return true;
  				};
  
  				ctx.child = function (obj) {
  					if (!obj.thread) {
  						return false;
  					}
  
  					thread.children.push(obj.thread);
  					return true;
  				};
  
  				ctx.race = function (max, label, promise) {
  					if (!promise) {
  						promise = label || max;
  						max = label != null ? max : 1;
  						label = null;
  					}
  
  					label = label || null;
  					var race = raceI[label] = raceI[label] || {i: 0};
  					race.max = max;
  
  					waitFactory(raceStore, promise).then(function () {
  						if (race.i < race.max) {
  							race.i++;
  
  							if (race.i === race.max) {
  								race.i = 0;
  								raceStore.clear();
  								done = true;
  							}
  						}
  					});
  
  					return promise;
  				};
  
  				ctx.wait = function (max, label, promise) {
  					return waitFactory(waitStore, max, label, promise);
  				};
  
  				ctx.sleep = function (time, opt_test, opt_interval) {
  					ctx.yield();
  					return new Promise(function (resolve, reject) {
  						var
  							sleep = thread.sleep;
  
  						if (sleep != null) {
  							sleep.resume();
  						}
  
  						sleep = thread.sleep = {
  							resume: function () {
  								clearTimeout(sleep.id);
  								thread.sleep = null;
  								resolve();
  							},
  
  							id: setTimeout(function () {
  								if (opt_test) {
  									try {
  										thread.sleep = null;
  										var test = opt_test(ctx);
  
  										if (test) {
  											resolve();
  											ctx.next();
  
  										} else if (opt_interval !== false) {
  											ctx.sleep(time, opt_test, opt_interval).then(resolve, reject);
  										}
  
  									} catch (err) {
  										reject(err);
  										onError(err);
  									}
  
  								} else {
  									resolve();
  									ctx.next();
  								}
  							}, time)
  						};
  					});
  				};
  			`;
  
  			//#endif
  		} else {
  			iFn += _string.ws`
  				ctx.yield = ctx.next = ctx.child = ctx.race = ctx.wait = ctx.sleep = o.notAsync;
  			`;
  		}
  	}
  
  	let threadStart = '',
  	    threadEnd = '';
  
  	//#if iterators.async
  	//#if iterators.thread
  
  	if (p.async && p.thread) {
  		threadStart = _string.ws`
  			if (timeStart == null) {
  				timeStart = new Date().valueOf();
  			}
  		`;
  
  		threadEnd = _string.ws`
  			timeEnd = new Date().valueOf();
  			time += timeEnd - timeStart;
  			timeStart = timeEnd;
  
  			if (time > priority[thread.priority]) {
  				yield;
  				time = 0;
  				timeStart = null;
  			}
  		`;
  	}
  
  	//#endif
  	//#endif
  
  	iFn += 'while (limit !== looper) {';
  
  	let yielder = '',
  	    asyncWait = '';
  
  	//#if iterators.async
  
  	if (p.async) {
  		iFn += 'done = false;';
  		yielder = _string.ws`
  			if (yielder) {
  				yielder = false;
  				thread.pause = true;
  				yieldVal = yield yieldVal;
  			}
  		`;
  
  		if (needCtx) {
  			asyncWait = _string.ws`
  				waiting = true;
  
  				while (waitStore.size) {
  					thread.pause = true;
  					yield;
  				}
  
  				while (raceStore.size) {
  					thread.pause = true;
  					yield;
  				}
  			`;
  		}
  	}
  
  	//#endif
  
  	let indexLimits = '';
  
  	if (p.startIndex) {
  		indexLimits = _string.ws`
  			if (n < startIndex) {
  				${threadEnd}
  				continue;
  			}
  		`;
  	}
  
  	if (p.endIndex) {
  		indexLimits += _string.ws`
  			if (n > endIndex) {
  				${threadEnd}
  				break;
  			};
  		`;
  	}
  
  	const defArgs = maxArgsLength || p.async;
  
  	switch (p.type) {
  		case 'array':
  			iFn += _string.ws`
  				var
  					clone = data,
  					dLength = data.length - 1,
  					slice = IGNORE.slice;
  			`;
  
  			if (p.reverse) {
  				iFn += 'clone = slice.call(clone).reverse();';
  			}
  
  			if ((p.reverse || !p.live) && (p.startIndex || p.endIndex)) {
  				iFn += _string.ws`
  					clone = slice.call(clone, startIndex, endIndex || data.length);
  				`;
  			}
  
  			if (!p.reverse && p.live) {
  				iFn += _string.ws`
  					for (n = startIndex - 1; ++n < clone.length;) {
  						${threadStart}
  						i = n;
  						${indexLimits}
  				`;
  			} else {
  				iFn += _string.ws`
  					length = clone.length;
  					for (n = -1; ++n < length;) {
  						${threadStart}
  						i = n + startIndex;
  				`;
  			}
  
  			if (defArgs) {
  				if (maxArgsLength > 1) {
  					if (p.startIndex) {
  						iFn += `key = ${p.reverse ? 'dLength - (' : ''} n + startIndex ${p.reverse ? ')' : ''};`;
  					} else {
  						iFn += `key = ${p.reverse ? 'dLength - ' : ''} n;`;
  					}
  				}
  
  				if (p.withDescriptor) {
  					iFn += 'el = getDescriptor(clone, n);';
  				} else {
  					iFn += 'el = clone[n];';
  				}
  			}
  
  			break;
  
  		case 'object':
  			iFn += _string.ws`
  				var
  					selfHasOwn = data.hasOwnProperty,
  					hasOwnProperty = IGNORE.hasOwnProperty;
  			`;
  
  			if (p.reverse || _hacks.OBJECT_KEYS_NATIVE_SUPPORT && !p.notOwn) {
  				iFn += 'var tmpArray;';
  
  				if (!p.notOwn && _hacks.OBJECT_KEYS_NATIVE_SUPPORT && !p.async) {
  					iFn += 'tmpArray = Object.keys(data);';
  				} else {
  					iFn += 'tmpArray = [];';
  
  					if (p.notOwn) {
  						if (p.notOwn === -1) {
  							iFn += _string.ws`
  								for (key in data) {
  									${threadStart}
  									if (selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key)) {
  										continue;
  									}
  
  									tmpArray.push(key);
  									${threadEnd}
  								}
  							`;
  						} else {
  							iFn += _string.ws`
  								for (key in data) {
  									${threadStart}
  									tmpArray.push(key);
  									${threadEnd}
  								}
  							`;
  						}
  					} else {
  						iFn += _string.ws`
  							for (key in data) {
  								${threadStart}
  								if (!(selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key))) {
  									break;
  								}
  
  								tmpArray.push(key);
  								${threadEnd}
  							}
  						`;
  					}
  				}
  
  				if (p.reverse) {
  					iFn += 'tmpArray.reverse();';
  				}
  
  				if (p.startIndex || p.endIndex) {
  					iFn += `tmpArray = tmpArray.slice(startIndex, endIndex || tmpArray.length);`;
  				}
  
  				iFn += _string.ws`
  					length = tmpArray.length;
  					for (n = -1; ++n < length;) {
  						${threadStart}
  						key = tmpArray[n];
  
  						if (key in data === false) {
  							${threadEnd}
  							continue;
  						}
  
  						i = n + startIndex;
  				`;
  			} else {
  				iFn += _string.ws`
  					for (key in data) {
  						${threadStart}
  				`;
  
  				if (p.notOwn === false) {
  					iFn += _string.ws`
  						if (!(selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key))) {
  							${threadEnd}
  							break;
  						}`;
  				} else if (p.notOwn === -1) {
  					iFn += _string.ws`
  						if (selfHasOwn ? data.hasOwnProperty(key) : hasOwnProperty.call(data, key)) {
  							${threadEnd}
  							continue;
  						}`;
  				}
  
  				iFn += _string.ws`
  					n++;
  					i = n;
  					${indexLimits}
  				`;
  			}
  
  			if (defArgs) {
  				if (p.withDescriptor) {
  					iFn += 'el = getDescriptor(data, key);';
  				} else {
  					iFn += 'el = data[key];';
  				}
  			}
  
  			break;
  
  		case 'map':
  		case 'set':
  		case 'generator':
  		case 'iterator':
  		case 'asyncIterator':
  			if (isMapSet) {
  				iFn += 'var cursor = data.keys();';
  
  				if (!p.live && !p.reverse) {
  					iFn += 'var size = data.size;';
  				}
  			} else if (p.type === 'generator') {
  				iFn += 'var cursor = data();';
  			} else {
  				iFn += _string.ws`
  					var
  						iteratorKey = typeof Symbol !== 'undefined' && Symbol.iterator,
  						cursor;
  
  					if (typeof data.next === 'function') {
  						cursor = data;
  
  					} else {
  						cursor = (iteratorKey ? data[iteratorKey]() : data['@@iterator'] && data['@@iterator']()) || data;
  					}
  				`;
  			}
  
  			iFn += _string.ws`
  				${p.reverse ? 'var tmpArray = [];' : ''}
  
  				for (
  					key = cursor.next(), brkIf = ('done' in key === false);
  					'done' in key ? !key.done : key;
  					key = cursor.next()
  				) {
  					${threadStart}
  			`;
  
  			let asyncIterator = '';
  
  			//#if iterators.async
  
  			if (p.type === 'asyncIterator') {
  				asyncIterator = _string.ws`
  					while (isPromise(el)) {
  						if (!rElSet.has(el)) {
  							rElSet.add(el);
  							el.then(resolveEl, onError);
  						}
  
  						thread.pause = true;
  						yield;
  					}
  				`;
  			}
  
  			//#endif
  
  			if (p.reverse) {
  				iFn += `el = 'value' in key ? key.value : key; ${asyncIterator}`;
  
  				//#if iterators.async
  
  				if (needParallel) {
  					iFn += _string.ws`
  						if (maxParallelIsNumber) {
  							if (isPromise(el)) {
  								ctx['${parallelFn}'](maxParallel, null, el);
  							}
  
  							${yielder}
  						}
  					`;
  				}
  
  				//#endif
  
  				iFn += _string.ws`
  						if (el !== IGNORE) {
  							if (brkIf && el === null) {
  								${threadEnd}
  								break;
  							}
  
  							tmpArray.push(el);
  						}
  
  						${threadEnd}
  					}
  
  					${asyncWait}
  					tmpArray.reverse();
  					var size = tmpArray.length;
  				`;
  
  				if (p.startIndex || p.endIndex) {
  					iFn += `tmpArray = tmpArray.slice(startIndex, endIndex || tmpArray.length);`;
  				}
  
  				iFn += _string.ws`
  					length = size;
  					for (n = -1; ++n < length;) {
  						${threadStart}
  						${defArgs ? 'key = tmpArray[n];' : ''}
  						i = n + startIndex;
  				`;
  			} else {
  				iFn += _string.ws`
  					${defArgs ? `key = 'value' in key ? key.value : key;` : ''}
  					n++;
  					i = n;
  					${indexLimits}
  				`;
  			}
  
  			if (defArgs) {
  				if (p.type === 'map') {
  					iFn += 'el = data.get(key);';
  				} else {
  					iFn += `el = key; ${asyncIterator}`;
  
  					if (maxArgsLength > 1) {
  						if (p.type === 'set') {
  							iFn += 'key = null;';
  						} else if (p.reverse) {
  							iFn += 'key = size - i - 1;';
  						} else {
  							iFn += 'key = i;';
  						}
  					}
  				}
  			}
  
  			break;
  	}
  
  	if (needCtx) {
  		iFn += 'id++;';
  	}
  
  	if (p.count) {
  		iFn += _string.ws`
  			if (j === count) {
  				${threadEnd}
  				break;
  			}
  		`;
  	}
  
  	let tmp = '';
  
  	if (!p.async) {
  		if (fLength) {
  			if (fLength < 5) {
  				for (let i = 0; i < fLength; i++) {
  					iFn += _string.ws`
  						if (${i ? 'f' : 'true'}) {
  							f = filters[${i}](${filterArgs[i]});
  							${resolveFilterVal}
  						}
  					`;
  				}
  			} else {
  				iFn += _string.ws`
  					for (fI = -1; ++fI < fLength;) {
  						f = ${callCycleFilter};
  						${resolveFilterVal}
  
  						if (!f) {
  							break;
  						}
  					}
  				`;
  			}
  
  			iFn += 'if (f) {';
  		}
  
  		if (p.count) {
  			tmp += 'j++;';
  		}
  	}
  
  	tmp += `r = cb(${cbArgs});`;
  
  	if (!p.mult) {
  		tmp += 'breaker = true;';
  	}
  
  	//#if iterators.async
  
  	if (p.async) {
  		tmp += _string.ws`
  			while (isPromise(r)) {
  				if (!rCbSet.has(r)) {
  					rCbSet.add(r);
  					r.then(resolveCb, onError);
  				}
  
  				thread.pause = true;
  				yield;
  			}
  		`;
  	}
  
  	//#endif
  
  	if (!p.async && p.from) {
  		iFn += _string.ws`
  			if (from !== 0) {
  				from--;
  
  			} else {
  				${tmp}
  			}
  		`;
  	} else {
  		iFn += tmp;
  	}
  
  	if (!p.async && fLength) {
  		iFn += '}';
  	}
  
  	iFn += yielder;
  	if (!p.live && !p.reverse && isMapSet) {
  		iFn += _string.ws`
  			size--;
  
  			if (!size) {
  				${threadEnd}
  				break;
  			}
  		`;
  	}
  
  	iFn += _string.ws`
  			${threadEnd}
  
  			if (breaker${p.async ? '|| done' : ''}) {
  				break;
  			}
  		}
  
  		breaker = false;
  		looper++;
  
  		if (onIterationEnd) {
  			onIterationEnd(${needCtx ? 'ctx' : ''});
  		}
  	`;
  
  	iFn += _string.ws`
  			${yielder}
  		}
  
  		${asyncWait}
  
  		if (onComplete) {
  			${p.async ? 'done = true;' : ''}
  			onComplete(p.result);
  		}
  
  		return p.result;
  	`;
  
  	if (p.async) {
  		//#if iterators.async
  		_cache.tmpCycle[key] = new Function(`return function *(o, p) { ${iFn} };`)();
  		//#endif
  	} else {
  		_cache.tmpCycle[key] = new Function('o', 'p', iFn);
  	}
  
  	if (_core2.default.ready) {
  		const delay = 5e3;
  
  		const text = `${_base.NAMESPACE}.cache.cycle["${key}"] = ${_cache.tmpCycle[key].toString()};`;
  		cache[key] = text;
  
  		if (_hacks.IS_BROWSER && _hacks.LOCAL_STORAGE_SUPPORT) {
  			clearTimeout(timeout);
  			timeout = setTimeout(() => {
  				try {
  					localStorage.setItem(_base.CACHE_KEY, JSON.stringify(cache));
  					localStorage.setItem(_base.CACHE_VERSION_KEY, _base.CACHE_VERSION);
  
  					if (_hacks.BLOB_SUPPORT) {
  						const script = document.createElement('script');
  						script.src = URL.createObjectURL(new Blob([text], { type: 'application/javascript' }));
  						document.head.appendChild(script);
  					}
  				} catch (_) {}
  			}, delay);
  		} else if (_hacks.IS_NODE) {
  			//#if isNode
  			clearTimeout(timeout);
  			timeout = setTimeout(() => {
  				require('fs').writeFile(require('path').join(__dirname, 'collection.tmp.js'), `
  						exports.version = ${_base.CACHE_VERSION};
  						exports.cache = ${JSON.stringify(cache)};
  						exports.exec = function () { ${returnCache(cache)} };
  					`, () => {});
  			}, delay);
  
  			timeout['unref']();
  			//#endif
  		}
  	}
  
  	return _cache.tmpCycle[key];
  }
func_documentation_string: Compiles a loop by the specified parameters
  
  @param {string} key - cache key
  @param {!Object} p - compile parameters
  @return {!Function}