<commit_before>import { isElement, isText, isArray, defineProperty } from './helpers';
import { isComponent } from './Interfaces';
import { Template, TemplateItem, TemplateItems, TemplateFilter } from './Template';
import { isHyperNode, h } from './HyperNode';
import { DOM } from './DOM';
import { Context, getContext, createContext } from './Context';
import { isThenable, getThenableState } from './Thenable';
import { isObservable, getObservableState, Observable } from './Observable';
import { cloneChildNodes, IterableNodeList } from './NodeList';
import { css } from './css';
import { TemplateFunction } from 'react/src';

/**
 * A cache for converted class values.
 */
const CLASSES_CACHE: { [key: string]: string[] } = {};

/**
 * A cache for converted style values.
 */
const STYLES_CACHE: { [key: string]: { [key: string]: any } } = {};

/**
 * Convert strings or classes map to a list of classes.
 * @param value The value to convert.
 * @return A list of classes.
 */
const convertClasses = (value: any) => {
    let classes: string[] = [];
    if (!value) {
        return classes;
    }
    if (typeof value === 'object') {
        for (let k in value) {
            if (value[k]) {
                classes.push(k);
            }
        }
        return classes;
    }
    return classes = CLASSES_CACHE[value] = CLASSES_CACHE[value] || value.toString().trim().split(' ');
};

/**
 * Convert strings or styles map to a list of styles.
 * @param value The value to convert.
 * @return A set of styles.
 */
const convertStyles = (value: any) => {
    let styles: { [key: string]: string } = {};
    if (!value) {
        return styles;
    }
    if (typeof value === 'object') {
        for (let propertyKey in value) {
            let camelName = propertyKey.replace(/[A-Z]/g, (match: string) =>
                `-${match.toLowerCase()}`
            );
            styles[camelName] = value[propertyKey];
        }
        return styles;
    }
    return styles = STYLES_CACHE[value] = STYLES_CACHE[value] || value
        .toString()
        .split(';')
        .reduce((ruleMap: { [key: string]: string }, ruleString: string) => {
            let rulePair = ruleString.split(':');
            if (rulePair.length == 2) {
                ruleMap[rulePair[0].trim()] = rulePair[1].trim();
            }
            return ruleMap;
        }, styles);
};

/**
 * Render a set of Nodes into another, with some checks for Nodes in order to avoid
 * useless changes in the tree and to mantain or update the state of compatible Nodes.
 *
 * @param root The root Node for the render.
 * @param input The child (or the children) to render in Virtual DOM format or already generated.
 * @param context The render context of the root.
 * @param rootContext The render context of the main render.
 * @param rootNamespaceURI The current namespace uri of the render.
 * @param slot Should handle slot children.
 * @return The resulting child nodes list.
 */
export const internalRender = (
    root: HTMLElement,
    input: Template,
    context?: Context,
    rootContext?: Context,
    rootNamespaceURI = root.namespaceURI || 'http://www.w3.org/1999/xhtml',
    slot = false) => {
    let renderContext = context || getContext(root) || createContext(root);
    let rootRenderContext = rootContext || renderContext;
    let childNodes: IterableNodeList;
    if (slot) {
        childNodes = renderContext.slotChildNodes as IterableNodeList;
    } else {
        childNodes = renderContext.childNodes as IterableNodeList;
    }
    if (!childNodes) {
        return childNodes;
    }

    let currentIndex = 0;
    let currentNode = childNodes.item(currentIndex) as Node;
    let currentContext = currentNode ? (getContext(currentNode) || createContext(currentNode)) : null;
    let updateRender = () => internalRender(root, input, renderContext, rootRenderContext, rootNamespaceURI, slot);

    let oldKeys: string[]|undefined;
    let oldFunctions: TemplateFunction[]|undefined;
    let keys = renderContext.keys;
    let functions = renderContext.functions;
    let rootFunctions = rootRenderContext.functions;
    if (keys) {
        oldKeys = [];
        while (keys.length) oldKeys.unshift(keys.pop());
    }
    if (functions) {
        oldFunctions = [];
        while (functions.length) oldFunctions.unshift(functions.pop() as TemplateFunction);
    }

    const handleItems = (template: Template, filter?: TemplateFilter) => {
        if (template == null || template === false) {
            return;
        }

        let templateType = typeof template;
        let isObjectTemplate = templateType === 'object';
        let templateNode: Element | Text | undefined;
        let templateContext: Context|undefined;
        let templateChildren: TemplateItems | undefined;
        let templateNamespace = rootNamespaceURI;
        let isElementTemplate = false;
        let isComponentTemplate = false;
<commit_msg>fix: handle old functions only when root are defined<commit_after>import { isElement, isText, isArray, defineProperty } from './helpers';
import { isComponent } from './Interfaces';
import { Template, TemplateItem, TemplateItems, TemplateFilter } from './Template';
import { isHyperNode, h } from './HyperNode';
import { DOM } from './DOM';
import { Context, getContext, createContext } from './Context';
import { isThenable, getThenableState } from './Thenable';
import { isObservable, getObservableState, Observable } from './Observable';
import { cloneChildNodes, IterableNodeList } from './NodeList';
import { css } from './css';
import { TemplateFunction } from 'react/src';

/**
 * A cache for converted class values.
 */
const CLASSES_CACHE: { [key: string]: string[] } = {};

/**
 * A cache for converted style values.
 */
const STYLES_CACHE: { [key: string]: { [key: string]: any } } = {};

/**
 * Convert strings or classes map to a list of classes.
 * @param value The value to convert.
 * @return A list of classes.
 */
const convertClasses = (value: any) => {
    let classes: string[] = [];
    if (!value) {
        return classes;
    }
    if (typeof value === 'object') {
        for (let k in value) {
            if (value[k]) {
                classes.push(k);
            }
        }
        return classes;
    }
    return classes = CLASSES_CACHE[value] = CLASSES_CACHE[value] || value.toString().trim().split(' ');
};

/**
 * Convert strings or styles map to a list of styles.
 * @param value The value to convert.
 * @return A set of styles.
 */
const convertStyles = (value: any) => {
    let styles: { [key: string]: string } = {};
    if (!value) {
        return styles;
    }
    if (typeof value === 'object') {
        for (let propertyKey in value) {
            let camelName = propertyKey.replace(/[A-Z]/g, (match: string) =>
                `-${match.toLowerCase()}`
            );
            styles[camelName] = value[propertyKey];
        }
        return styles;
    }
    return styles = STYLES_CACHE[value] = STYLES_CACHE[value] || value
        .toString()
        .split(';')
        .reduce((ruleMap: { [key: string]: string }, ruleString: string) => {
            let rulePair = ruleString.split(':');
            if (rulePair.length == 2) {
                ruleMap[rulePair[0].trim()] = rulePair[1].trim();
            }
            return ruleMap;
        }, styles);
};

/**
 * Render a set of Nodes into another, with some checks for Nodes in order to avoid
 * useless changes in the tree and to mantain or update the state of compatible Nodes.
 *
 * @param root The root Node for the render.
 * @param input The child (or the children) to render in Virtual DOM format or already generated.
 * @param context The render context of the root.
 * @param rootContext The render context of the main render.
 * @param rootNamespaceURI The current namespace uri of the render.
 * @param slot Should handle slot children.
 * @return The resulting child nodes list.
 */
export const internalRender = (
    root: HTMLElement,
    input: Template,
    context?: Context,
    rootContext?: Context,
    rootNamespaceURI = root.namespaceURI || 'http://www.w3.org/1999/xhtml',
    slot = false) => {
    let renderContext = context || getContext(root) || createContext(root);
    let rootRenderContext = rootContext || renderContext;
    let childNodes: IterableNodeList;
    if (slot) {
        childNodes = renderContext.slotChildNodes as IterableNodeList;
    } else {
        childNodes = renderContext.childNodes as IterableNodeList;
    }
    if (!childNodes) {
        return childNodes;
    }

    let currentIndex = 0;
    let currentNode = childNodes.item(currentIndex) as Node;
    let currentContext = currentNode ? (getContext(currentNode) || createContext(currentNode)) : null;
    let updateRender = () => internalRender(root, input, renderContext, rootRenderContext, rootNamespaceURI, slot);

    let oldKeys: string[]|undefined;
    let oldFunctions: TemplateFunction[]|undefined;
    let keys = renderContext.keys;
    let functions = renderContext.functions;
    let rootFunctions = rootRenderContext.functions;
    if (keys) {
        oldKeys = [];
        while (keys.length) oldKeys.unshift(keys.pop());
    }
    if (functions && rootFunctions) {
        oldFunctions = [];
        while (functions.length) oldFunctions.unshift(functions.pop() as TemplateFunction);
    }

    const handleItems = (template: Template, filter?: TemplateFilter) => {
        if (template == null || template === false) {
            return;
        }

        let templateType = typeof template;
        let isObjectTemplate = templateType === 'object';
        let templateNode: Element | Text | undefined;
        let templateContext: Context|undefined;
        let templateChildren: TemplateItems | undefined;
        let templateNamespace = rootNamespaceURI;
        let isElementTemplate = false;
        let isComponentTemplate = false;

{'fraction_non_alphanumeric': 0.12096448748991122, 'fraction_numerical': 0.0018159806295399517, 'mean_word_length': 2.855698171917542, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3251772', 'n_tokens_mistral': 2705, 'n_tokens_neox': 2678, 'n_words': 883}