function getComponentKey(component, index) {
    // Do some typechecking here since we call this blindly. We want to ensure
    // that we don't block potential future ES APIs.
    if (component && component.key != null) {
    // Explicit key
        return escape(component.key);
    }
    // Implicit key determined by the index in the set
    return index.toString(36);
}

function traverseAllChildrenImpl(
    children,
    nameSoFar,
    callback,
    traverseContext
) {
    var type = typeof children;

    if (type === "undefined" || type === "boolean") {
    // All of the above are perceived as null.
        children = null;
    }

    if (
        children === null ||
    type === "string" ||
    type === "number" ||
    (type === "object" && children.$$typeof)
    ) {
        callback(
            traverseContext,
            children,
            nameSoFar === "" ? SEPARATOR + getComponentKey(children, 0) : nameSoFar
        );
        return 1;
    }

    var child;
    var nextName;
    var subtreeCount = 0; // Count of children found in the current subtree.
    var nextNamePrefix = nameSoFar === "" ? SEPARATOR : nameSoFar + SUBSEPARATOR;
    var iteratorFn = children && children["@@iterator"];
    if (iteratorFn && typeof iteratorFn === "function") {
        var iterator = iteratorFn.call(children);
        var step;
        children = [];
        while (!(step = iterator.next()).done) {
            children.push(step.value);
        }
    }

    if (Array.isArray(children)) {
        for (var i = 0; i < children.length; i++) {
            child = children[i];
            nextName = nextNamePrefix + getComponentKey(child, i);
            subtreeCount += traverseAllChildrenImpl(
                child,
                nextName,
                callback,
                traverseContext
            );
        }
    }

    return subtreeCount;
}
