<commit_before>import isVoid from '../util/isVoid';
import { getValueWithIndex, getTypeFromValue, ValueTypes } from '../core/variables';
import isArray from '../util/isArray';
import isStringOrNumber from '../util/isStringOrNumber';
import { isRecyclingEnabled, pool } from './recycling';
import replaceChild from '../core/replaceChild';
import appendText from '../util/appendText';
import removeChild from '../core/removeChild';
import updateAndAppendDynamicChildren from '../shared/updateAndAppendDynamicChildren';

const recyclingEnabled = isRecyclingEnabled();

function updateTree(item, oldItem, startItem, treeLifecycle, context) {
	item.tree.dom.update(oldItem, startItem, treeLifecycle, context);
}

export function updateKeyed(items, oldItems, parentNode, parentNextNode, treeLifecycle, context) {
	let stop = false;
	let startIndex = 0;
	let oldStartIndex = 0;
	const itemsLength = items.length;
	const oldItemsLength = oldItems.length;
	let startItem = itemsLength > 0 && items[startIndex];

	// Edge case! In cases where someone try to update from [null] to [null], 'startitem' will be null.
	// Also in cases where someone try to update from [{}] to [{}] (empty object to empty object)
	// We solve that with avoiding going into the iteration loop.
	if (!isVoid(startItem) && (!isVoid(startItem.tree))) {
		if (items == null ||itemsLength === 0 && oldItemsLength >= 5) {
			if (recyclingEnabled) {
				for (let i = 0; i < oldItemsLength; i++) {
					pool(oldItems[i]);
				}
			}
			parentNode.textContent = '';
			return;
		}
		let endIndex = itemsLength - 1;
		let oldEndIndex = oldItemsLength - 1;
		let oldStartItem = oldItemsLength > 0 && oldItems[oldStartIndex];
		let endItem;
		let oldEndItem;
		let nextNode;
		let oldItem;
		let item;
		let endItemKey;
		let oldEndItemKey;
		let oldStartItemKey;
		let startItemKey;

		outer: while (!stop && startIndex <= endIndex && oldStartIndex <= oldEndIndex) {
			oldStartItemKey = oldStartItem.key;
			startItemKey = startItem.key;
			stop = true;
			while (startItemKey === oldStartItemKey) {
				updateTree(startItem, oldStartItem, startItem);
				startIndex++;
				oldStartIndex++;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					startItem = items[startIndex];
					oldStartItem = oldItems[oldStartIndex];
					stop = false;
				}
			}
			endItem = items[endIndex];
			oldEndItem = oldItems[oldEndIndex];
			oldEndItemKey = oldEndItem.key;
			endItemKey = endItem.key;

			while (endItemKey === oldEndItemKey) {
				updateTree(endItem, oldEndItem, endItem);
				endIndex--;
				oldEndIndex--;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					endItem = items[endIndex];
					oldEndItem = oldItems[oldEndIndex];
					stop = false;
				}
			}
			while (endItemKey === oldStartItemKey) {
				nextNode = (endIndex + 1 < itemsLength) ? items[endIndex + 1].rootNode : parentNextNode;
				updateTree(endItem, oldStartItem, endItem);
				insertOrAppend(parentNode, endItem.rootNode, nextNode);
				endIndex--;
				oldStartIndex++;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					endItem = items[endIndex];
					oldStartItem = oldItems[oldStartIndex];
					stop = false;
				}
			}
			while (startItemKey === oldEndItemKey) {
				nextNode = oldItems[oldStartIndex].rootNode;
				updateTree(startItem, oldEndItem, startItem);
				insertOrAppend(parentNode, startItem.rootNode, nextNode);
				startIndex++;
				oldEndIndex--;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					startItem = items[startIndex];
					oldEndItem = oldItems[oldEndIndex];
					stop = false;
				}
			}
		}

		if (oldStartIndex > oldEndIndex) {
			if (startIndex <= endIndex) {
				nextNode = (endIndex + 1 < itemsLength) ? items[endIndex + 1].rootNode : parentNextNode;
				for (; startIndex <= endIndex; startIndex++) {
					item = items[startIndex];
					insertOrAppend(parentNode, item.tree.dom.create(item, treeLifecycle, context), nextNode);
				}
			}
		} else if (startIndex > endIndex) {
			for (; oldStartIndex <= oldEndIndex; oldStartIndex++) {
				oldItem = oldItems[oldStartIndex];
				remove(oldItem, parentNode);
			}
		} else {
			const oldItemsMap = {};
			let oldNextItem = (oldEndIndex + 1 < oldItemsLength) ? oldItems[oldEndIndex + 1] : null;

			for (let i = oldEndIndex; i >= oldStartIndex; i--) {
				oldItem = oldItems[i];
				oldItem.nextItem = oldNextItem;
				oldItemsMap[oldItem.key] = oldItem;
				oldNextItem = oldItem;
			}
			let nextItem = (endIndex + 1 < itemsLength) ? items[endIndex + 1] : null;

			for (let i = endIndex; i >= startIndex; i--) {
				item = items[i];
				const key = item.key;

				oldItem = oldItemsMap[key];
				if (oldItem) {
					oldItemsMap[key] = null;
					oldNextItem = oldItem.nextItem;
					updateTree(item, oldItem, item);

					if (item.rootNode.nextSibling !== (nextItem && nextItem.rootNode)) {
						nextNode = (nextItem && nextItem.rootNode) || parentNextNode;
						insertOrAppend(parentNode, item.rootNode, nextNode);
					}
				} else {
					nextNode = (nextItem && nextItem.rootNode) || parentNextNode;
					insertOrAppend(parentNode, item.tree.dom.create(item, treeLifecycle, context), nextNode);
				}
				nextItem = item;
			}
			for (let i = oldStartIndex; i <= oldEndIndex; i++) {
				oldItem = oldItems[i];
				if (oldItemsMap[oldItem.key] !== null) {
					oldItem = oldItems[oldStartIndex];
					remove(item, parentNode);
				}
			}
		}
	}
}

export function updateNonKeyed(items, oldItems, domNodeList, parentNode, parentNextNode, treeLifecycle, context) {

	if (isVoid(items)) {
		return;
	}

	const itemsLength = (oldItems.length === items.length) ? items.length : Math.max(oldItems.length, items.length);

	if (itemsLength) {

		for (let i = 0; i < itemsLength; i++) {

			let item = items[i];
			let oldItem = oldItems[i];
			let domNode = domNodeList[i];

			if (oldItem !== item) {

				if (item == null && domNodeList.length) {<commit_msg>fixed issue removeing wrong node<commit_after>import isVoid from '../util/isVoid';
import { getValueWithIndex, getTypeFromValue, ValueTypes } from '../core/variables';
import isArray from '../util/isArray';
import isStringOrNumber from '../util/isStringOrNumber';
import { isRecyclingEnabled, pool } from './recycling';
import replaceChild from '../core/replaceChild';
import appendText from '../util/appendText';
import removeChild from '../core/removeChild';
import updateAndAppendDynamicChildren from '../shared/updateAndAppendDynamicChildren';

const recyclingEnabled = isRecyclingEnabled();

function updateTree(item, oldItem, startItem, treeLifecycle, context) {
	item.tree.dom.update(oldItem, startItem, treeLifecycle, context);
}

export function updateKeyed(items, oldItems, parentNode, parentNextNode, treeLifecycle, context) {
	let stop = false;
	let startIndex = 0;
	let oldStartIndex = 0;
	const itemsLength = items.length;
	const oldItemsLength = oldItems.length;
	let startItem = itemsLength > 0 && items[startIndex];

	// Edge case! In cases where someone try to update from [null] to [null], 'startitem' will be null.
	// Also in cases where someone try to update from [{}] to [{}] (empty object to empty object)
	// We solve that with avoiding going into the iteration loop.
	if (!isVoid(startItem) && (!isVoid(startItem.tree))) {
		if (items == null ||itemsLength === 0 && oldItemsLength >= 5) {
			if (recyclingEnabled) {
				for (let i = 0; i < oldItemsLength; i++) {
					pool(oldItems[i]);
				}
			}
			parentNode.textContent = '';
			return;
		}
		let endIndex = itemsLength - 1;
		let oldEndIndex = oldItemsLength - 1;
		let oldStartItem = oldItemsLength > 0 && oldItems[oldStartIndex];
		let endItem;
		let oldEndItem;
		let nextNode;
		let oldItem;
		let item;
		let endItemKey;
		let oldEndItemKey;
		let oldStartItemKey;
		let startItemKey;

		outer: while (!stop && startIndex <= endIndex && oldStartIndex <= oldEndIndex) {
			oldStartItemKey = oldStartItem.key;
			startItemKey = startItem.key;
			stop = true;
			while (startItemKey === oldStartItemKey) {
				updateTree(startItem, oldStartItem, startItem);
				startIndex++;
				oldStartIndex++;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					startItem = items[startIndex];
					oldStartItem = oldItems[oldStartIndex];
					stop = false;
				}
			}
			endItem = items[endIndex];
			oldEndItem = oldItems[oldEndIndex];
			oldEndItemKey = oldEndItem.key;
			endItemKey = endItem.key;

			while (endItemKey === oldEndItemKey) {
				updateTree(endItem, oldEndItem, endItem);
				endIndex--;
				oldEndIndex--;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					endItem = items[endIndex];
					oldEndItem = oldItems[oldEndIndex];
					stop = false;
				}
			}
			while (endItemKey === oldStartItemKey) {
				nextNode = (endIndex + 1 < itemsLength) ? items[endIndex + 1].rootNode : parentNextNode;
				updateTree(endItem, oldStartItem, endItem);
				insertOrAppend(parentNode, endItem.rootNode, nextNode);
				endIndex--;
				oldStartIndex++;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					endItem = items[endIndex];
					oldStartItem = oldItems[oldStartIndex];
					stop = false;
				}
			}
			while (startItemKey === oldEndItemKey) {
				nextNode = oldItems[oldStartIndex].rootNode;
				updateTree(startItem, oldEndItem, startItem);
				insertOrAppend(parentNode, startItem.rootNode, nextNode);
				startIndex++;
				oldEndIndex--;
				if (startIndex > endIndex || oldStartIndex > oldEndIndex) {
					break outer;
				} else {
					startItem = items[startIndex];
					oldEndItem = oldItems[oldEndIndex];
					stop = false;
				}
			}
		}

		if (oldStartIndex > oldEndIndex) {
			if (startIndex <= endIndex) {
				nextNode = (endIndex + 1 < itemsLength) ? items[endIndex + 1].rootNode : parentNextNode;
				for (; startIndex <= endIndex; startIndex++) {
					item = items[startIndex];
					insertOrAppend(parentNode, item.tree.dom.create(item, treeLifecycle, context), nextNode);
				}
			}
		} else if (startIndex > endIndex) {
			for (; oldStartIndex <= oldEndIndex; oldStartIndex++) {
				oldItem = oldItems[oldStartIndex];
				remove(oldItem, parentNode);
			}
		} else {
			const oldItemsMap = {};
			let oldNextItem = (oldEndIndex + 1 < oldItemsLength) ? oldItems[oldEndIndex + 1] : null;

			for (let i = oldEndIndex; i >= oldStartIndex; i--) {
				oldItem = oldItems[i];
				oldItem.nextItem = oldNextItem;
				oldItemsMap[oldItem.key] = oldItem;
				oldNextItem = oldItem;
			}
			let nextItem = (endIndex + 1 < itemsLength) ? items[endIndex + 1] : null;

			for (let i = endIndex; i >= startIndex; i--) {
				item = items[i];
				const key = item.key;

				oldItem = oldItemsMap[key];
				if (oldItem) {
					oldItemsMap[key] = null;
					oldNextItem = oldItem.nextItem;
					updateTree(item, oldItem, item);

					if (item.rootNode.nextSibling !== (nextItem && nextItem.rootNode)) {
						nextNode = (nextItem && nextItem.rootNode) || parentNextNode;
						insertOrAppend(parentNode, item.rootNode, nextNode);
					}
				} else {
					nextNode = (nextItem && nextItem.rootNode) || parentNextNode;
					insertOrAppend(parentNode, item.tree.dom.create(item, treeLifecycle, context), nextNode);
				}
				nextItem = item;
			}
			for (let i = oldStartIndex; i <= oldEndIndex; i++) {
				oldItem = oldItems[i];
				if (oldItemsMap[oldItem.key] !== null) {
					oldItem = oldItems[oldStartIndex];
					remove(oldItem, parentNode);
				}
			}
		}
	}
}

export function updateNonKeyed(items, oldItems, domNodeList, parentNode, parentNextNode, treeLifecycle, context) {

	if (isVoid(items)) {
		return;
	}

	const itemsLength = (oldItems.length === items.length) ? items.length : Math.max(oldItems.length, items.length);

	if (itemsLength) {

		for (let i = 0; i < itemsLength; i++) {

			let item = items[i];
			let oldItem = oldItems[i];
			let domNode = domNodeList[i];

			if (oldItem !== item) {

				if (item == null && domNodeList.length) {
{'fraction_non_alphanumeric': 0.12613205993742796, 'fraction_numerical': 0.002963938745265931, 'mean_word_length': 3.564825253664036, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5133173', 'n_tokens_mistral': 4639, 'n_tokens_neox': 3860, 'n_words': 954}