inferno
Version: 
An extremely fast, React-like JavaScript library for building modern user interfaces
1,324 lines (1,307 loc) • 102 kB
JavaScript
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Inferno = global.Inferno || {}));
})(this, (function (exports) { 'use strict';
    var ERROR_MSG = 'a runtime error occured! Use Inferno in development environment to find the error.';
    var isArray = Array.isArray;
    function isStringOrNumber(o) {
      var type = typeof o;
      return type === 'string' || type === 'number';
    }
    function isNullOrUndef(o) {
      return o === void 0 || o === null;
    }
    function isInvalid(o) {
      return o === null || o === false || o === true || o === void 0;
    }
    function isFunction(o) {
      return typeof o === 'function';
    }
    function isString(o) {
      return typeof o === 'string';
    }
    function isNumber(o) {
      return typeof o === 'number';
    }
    function isNull(o) {
      return o === null;
    }
    function isUndefined(o) {
      return o === void 0;
    }
    function throwError(message) {
      if (!message) {
        message = ERROR_MSG;
      }
      throw new Error("Inferno Error: " + message);
    }
    function warning(message) {
      console.error(message);
    }
    /**
     * Links given data to event as first parameter
     * @param {*} data data to be linked, it will be available in function as first parameter
     * @param {Function} event Function to be called when event occurs
     * @returns {{data: *, event: Function}}
     */
    function linkEvent(data, event) {
      if (isFunction(event)) {
        return {
          data: data,
          event: event
        };
      }
      return null; // Return null when event is invalid, to avoid creating unnecessary event handlers
    }
    // object.event should always be function, otherwise its badly created object.
    function isLinkEventObject(o) {
      return !isNull(o) && typeof o === 'object';
    }
    function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); }
    // We need EMPTY_OBJ defined in one place.
    // It's used for comparison, so we can't inline it into shared
    var EMPTY_OBJ = {};
    // @ts-expect-error hack for fragment type
    var Fragment = '$F';
    var AnimationQueues = function AnimationQueues() {
      this.componentDidAppear = [];
      this.componentWillDisappear = [];
      this.componentWillMove = [];
    };
    {
      Object.freeze(EMPTY_OBJ);
    }
    function normalizeEventName(name) {
      return name.substring(2).toLowerCase();
    }
    function appendChild(parentDOM, dom) {
      parentDOM.appendChild(dom);
    }
    function insertOrAppend(parentDOM, newNode, nextNode) {
      if (isNull(nextNode)) {
        appendChild(parentDOM, newNode);
      } else {
        parentDOM.insertBefore(newNode, nextNode);
      }
    }
    function documentCreateElement(tag, isSVG) {
      if (isSVG) {
        return document.createElementNS('http://www.w3.org/2000/svg', tag);
      }
      return document.createElement(tag);
    }
    function replaceChild(parentDOM, newDom, lastDom) {
      parentDOM.replaceChild(newDom, lastDom);
    }
    function removeChild(parentDOM, childNode) {
      parentDOM.removeChild(childNode);
    }
    function callAll(arrayFn) {
      for (var i = 0; i < arrayFn.length; i++) {
        arrayFn[i]();
      }
    }
    function findChildVNode(vNode, startEdge, flags) {
      var children = vNode.children;
      if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) {
        return children.$LI;
      }
      if ((flags & 8192 /* VNodeFlags.Fragment */) !== 0) {
        return vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */ ? children : children[startEdge ? 0 : children.length - 1];
      }
      return children;
    }
    function findDOMFromVNode(vNode, startEdge) {
      var flags;
      var v = vNode;
      while (!isNullOrUndef(v)) {
        flags = v.flags;
        if ((flags & 1521 /* VNodeFlags.DOMRef */) !== 0) {
          return v.dom;
        }
        v = findChildVNode(v, startEdge, flags);
      }
      return null;
    }
    function callAllAnimationHooks(animationQueue, callback) {
      var animationsLeft = animationQueue.length;
      // Picking from the top because it is faster, invocation order should be irrelevant
      // since all animations are to be run, and we can't predict the order in which they complete.
      var fn;
      while ((fn = animationQueue.pop()) !== undefined) {
        fn(function () {
          if (--animationsLeft <= 0 && isFunction(callback)) {
            callback();
          }
        });
      }
    }
    function callAllMoveAnimationHooks(animationQueue) {
      // Start the animations.
      for (var i = 0; i < animationQueue.length; i++) {
        animationQueue[i].fn();
      }
      // Perform the actual DOM moves when all measurements of initial
      // position have been performed. The rest of the animations are done
      // async.
      for (var _i = 0; _i < animationQueue.length; _i++) {
        var tmp = animationQueue[_i];
        insertOrAppend(tmp.parent, tmp.dom, tmp.next);
      }
      animationQueue.splice(0, animationQueue.length);
    }
    function clearVNodeDOM(vNode, parentDOM, deferredRemoval) {
      while (!isNullOrUndef(vNode)) {
        var flags = vNode.flags;
        if ((flags & 1521 /* VNodeFlags.DOMRef */) !== 0) {
          // On deferred removals the node might disappear because of later operations
          if (!deferredRemoval || vNode.dom.parentNode === parentDOM) {
            removeChild(parentDOM, vNode.dom);
          }
          return;
        }
        var children = vNode.children;
        if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) {
          vNode = children.$LI;
        }
        if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) {
          vNode = children;
        }
        if ((flags & 8192 /* VNodeFlags.Fragment */) !== 0) {
          if (vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) {
            vNode = children;
          } else {
            for (var i = 0, len = children.length; i < len; ++i) {
              clearVNodeDOM(children[i], parentDOM, false);
            }
            return;
          }
        }
      }
    }
    function createDeferComponentClassRemovalCallback(vNode, parentDOM) {
      return function () {
        // Mark removal as deferred to trigger check that node still exists
        clearVNodeDOM(vNode, parentDOM, true);
      };
    }
    function removeVNodeDOM(vNode, parentDOM, animations) {
      if (animations.componentWillDisappear.length > 0) {
        // Wait until animations are finished before removing actual dom nodes
        callAllAnimationHooks(animations.componentWillDisappear, createDeferComponentClassRemovalCallback(vNode, parentDOM));
      } else {
        clearVNodeDOM(vNode, parentDOM, false);
      }
    }
    function addMoveAnimationHook(animations, parentVNode, refOrInstance, dom, parentDOM, nextNode, flags, props) {
      animations.componentWillMove.push({
        dom: dom,
        fn: function fn() {
          if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) {
            refOrInstance.componentWillMove(parentVNode, parentDOM, dom);
          } else if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) {
            refOrInstance.onComponentWillMove(parentVNode, parentDOM, dom, props);
          }
        },
        next: nextNode,
        parent: parentDOM
      });
    }
    function moveVNodeDOM(parentVNode, vNode, parentDOM, nextNode, animations) {
      var refOrInstance;
      var instanceProps;
      var instanceFlags = vNode.flags;
      while (!isNullOrUndef(vNode)) {
        var flags = vNode.flags;
        if ((flags & 1521 /* VNodeFlags.DOMRef */) !== 0) {
          if (!isNullOrUndef(refOrInstance) && (isFunction(refOrInstance.componentWillMove) || isFunction(refOrInstance.onComponentWillMove))) {
            addMoveAnimationHook(animations, parentVNode, refOrInstance, vNode.dom, parentDOM, nextNode, instanceFlags, instanceProps);
          } else {
            // TODO: Should we delay this too to support mixing animated moves with regular?
            insertOrAppend(parentDOM, vNode.dom, nextNode);
          }
          return;
        }
        var children = vNode.children;
        if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) {
          refOrInstance = vNode.children;
          // TODO: We should probably deprecate this in V9 since it is inconsitent with other class component hooks
          instanceProps = vNode.props;
          vNode = children.$LI;
        } else if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) {
          refOrInstance = vNode.ref;
          instanceProps = vNode.props;
          vNode = children;
        } else if ((flags & 8192 /* VNodeFlags.Fragment */) !== 0) {
          if (vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) {
            vNode = children;
          } else {
            for (var i = 0, len = children.length; i < len; ++i) {
              moveVNodeDOM(parentVNode, children[i], parentDOM, nextNode, animations);
            }
            return;
          }
        }
      }
    }
    function getComponentName(instance) {
      var _ref, _ref2, _instance$name;
      // TODO: Fallback for IE
      return (_ref = (_ref2 = (_instance$name = instance.name) != null ? _instance$name : instance.displayName) != null ? _ref2 : instance.constructor.name) != null ? _ref : (instance.toString().match(/^function\s*([^\s(]+)/) || [])[1];
    }
    function createDerivedState(instance, nextProps, state) {
      if (isFunction(instance.constructor.getDerivedStateFromProps)) {
        return _extends$4({}, state, instance.constructor.getDerivedStateFromProps(nextProps, state));
      }
      return state;
    }
    var renderCheck = {
      v: false
    };
    var options = {
      createVNode: null
    };
    function setTextContent(dom, children) {
      dom.textContent = children;
    }
    // Calling this function assumes, nextValue is linkEvent
    function isLastValueSameLinkEvent(lastValue, nextValue) {
      return isLinkEventObject(lastValue) && lastValue.event === nextValue.event && lastValue.data === nextValue.data;
    }
    function mergeUnsetProperties(to, from) {
      for (var propName in from) {
        // @ts-expect-error merge objects
        if (isUndefined(to[propName])) {
          // @ts-expect-error merge objects
          to[propName] = from[propName];
        }
      }
      // @ts-expect-error merge objects
      return to;
    }
    function safeCall1(method, arg1) {
      return isFunction(method) && (method(arg1), true);
    }
    function getTagName(input) {
      var tagName;
      if (isArray(input)) {
        var arrayText = input.length > 3 ? input.slice(0, 3).toString() + ',...' : input.toString();
        tagName = 'Array(' + arrayText + ')';
      } else if (isStringOrNumber(input)) {
        tagName = 'Text(' + input + ')';
      } else if (isInvalid(input)) {
        tagName = 'InvalidVNode(' + input + ')';
      } else {
        var flags = input.flags;
        if (flags & 481 /* VNodeFlags.Element */) {
          tagName = "<" + input.type + (input.className ? ' class="' + input.className + '"' : '') + ">";
        } else if (flags & 16 /* VNodeFlags.Text */) {
          tagName = "Text(" + input.children + ")";
        } else if (flags & 1024 /* VNodeFlags.Portal */) {
          tagName = "Portal*";
        } else {
          tagName = "<" + getComponentName(input.type) + " />";
        }
      }
      return '>> ' + tagName + '\n';
    }
    function DEV_VALIDATE_KEYS(vNodeTree, forceKeyed) {
      var foundKeys = {};
      for (var i = 0, len = vNodeTree.length; i < len; ++i) {
        var childNode = vNodeTree[i];
        if (isArray(childNode)) {
          return 'Encountered ARRAY in mount, array must be flattened, or normalize used. Location: \n' + getTagName(childNode);
        }
        if (isInvalid(childNode)) {
          if (forceKeyed) {
            return 'Encountered invalid node when preparing to keyed algorithm. Location: \n' + getTagName(childNode);
          } else if (Object.keys(foundKeys).length !== 0) {
            return 'Encountered invalid node with mixed keys. Location: \n' + getTagName(childNode);
          }
          continue;
        }
        if (typeof childNode === 'object') {
          if (childNode.isValidated) {
            continue;
          }
          childNode.isValidated = true;
        }
        // Key can be undefined, null too. But typescript complains for no real reason
        var key = childNode.key;
        if (!isNullOrUndef(key) && !isStringOrNumber(key)) {
          return 'Encountered child vNode where key property is not string or number. Location: \n' + getTagName(childNode);
        }
        var children = childNode.children;
        var childFlags = childNode.childFlags;
        if (!isInvalid(children)) {
          var val = void 0;
          if (childFlags & 12 /* ChildFlags.MultipleChildren */) {
            val = DEV_VALIDATE_KEYS(children, (childFlags & 8 /* ChildFlags.HasKeyedChildren */) !== 0);
          } else if (childFlags === 2 /* ChildFlags.HasVNodeChildren */) {
            val = DEV_VALIDATE_KEYS([children], false);
          }
          if (val) {
            val += getTagName(childNode);
            return val;
          }
        }
        if (forceKeyed && isNullOrUndef(key)) {
          return 'Encountered child without key during keyed algorithm. If this error points to Array make sure children is flat list. Location: \n' + getTagName(childNode);
        } else if (!forceKeyed && isNullOrUndef(key)) {
          if (Object.keys(foundKeys).length !== 0) {
            return 'Encountered children with key missing. Location: \n' + getTagName(childNode);
          }
          continue;
        }
        if (foundKeys[key]) {
          return 'Encountered two children with same key: {' + key + '}. Location: \n' + getTagName(childNode);
        }
        foundKeys[key] = true;
      }
      return null;
    }
    function validateVNodeElementChildren(vNode) {
      {
        if (vNode.childFlags === 1 /* ChildFlags.HasInvalidChildren */) {
          return;
        }
        if (vNode.flags & 64 /* VNodeFlags.InputElement */) {
          throwError("input elements can't have children.");
        }
        if (vNode.flags & 128 /* VNodeFlags.TextareaElement */) {
          throwError("textarea elements can't have children.");
        }
        if (vNode.flags & 481 /* VNodeFlags.Element */) {
          var voidTypes = {
            area: true,
            base: true,
            br: true,
            col: true,
            command: true,
            embed: true,
            hr: true,
            img: true,
            input: true,
            keygen: true,
            link: true,
            meta: true,
            param: true,
            source: true,
            track: true,
            wbr: true
          };
          var tag = vNode.type.toLowerCase();
          if (tag === 'media') {
            throwError("media elements can't have children.");
          }
          if (voidTypes[tag]) {
            throwError(tag + " elements can't have children.");
          }
        }
      }
    }
    function validateKeys(vNode) {
      {
        // Checks if there is any key missing or duplicate keys
        if (!vNode.isValidated && vNode.children && vNode.flags & 481 /* VNodeFlags.Element */) {
          var error = DEV_VALIDATE_KEYS(Array.isArray(vNode.children) ? vNode.children : [vNode.children], (vNode.childFlags & 8 /* ChildFlags.HasKeyedChildren */) > 0);
          if (error) {
            throwError(error + getTagName(vNode));
          }
        }
        vNode.isValidated = true;
      }
    }
    function throwIfObjectIsNotVNode(input) {
      if (!isNumber(input.flags)) {
        throwError("normalization received an object that's not a valid VNode, you should stringify it first or fix createVNode flags. Object: \"" + JSON.stringify(input) + "\".");
      }
    }
    function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); }
    var keyPrefix = '$';
    function V(childFlags, children, className, flags, key, props, ref, type) {
      {
        this.isValidated = false;
      }
      this.childFlags = childFlags;
      this.children = children;
      this.className = className;
      this.dom = null;
      this.flags = flags;
      this.key = key === void 0 ? null : key;
      this.props = props === void 0 ? null : props;
      this.ref = ref === void 0 ? null : ref;
      this.type = type;
    }
    function createVNode(flags, type, className, children, childFlags, props, key, ref) {
      {
        if (flags & 14 /* VNodeFlags.Component */) {
          throwError('Creating Component vNodes using createVNode is not allowed. Use Inferno.createComponentVNode method.');
        }
      }
      var childFlag = childFlags === void 0 ? 1 /* ChildFlags.HasInvalidChildren */ : childFlags;
      var vNode = new V(childFlag, children, className, flags, key, props, ref, type);
      if (options.createVNode) {
        options.createVNode(vNode);
      }
      if (childFlag === 0 /* ChildFlags.UnknownChildren */) {
        normalizeChildren(vNode, vNode.children);
      }
      {
        validateVNodeElementChildren(vNode);
      }
      return vNode;
    }
    function mergeDefaultHooks(flags, type, ref) {
      if (flags & 4 /* VNodeFlags.ComponentClass */) {
        return ref;
      }
      var defaultHooks = (flags & 32768 /* VNodeFlags.ForwardRef */ ? type.render : type).defaultHooks;
      if (isNullOrUndef(defaultHooks)) {
        return ref;
      }
      if (isNullOrUndef(ref)) {
        return defaultHooks;
      }
      return mergeUnsetProperties(ref, defaultHooks);
    }
    function mergeDefaultProps(flags, type, props) {
      // set default props
      var defaultProps = (flags & 32768 /* VNodeFlags.ForwardRef */ ? type.render : type).defaultProps;
      if (isNullOrUndef(defaultProps)) {
        return props;
      }
      if (isNullOrUndef(props)) {
        return _extends$3({}, defaultProps);
      }
      return mergeUnsetProperties(props, defaultProps);
    }
    function resolveComponentFlags(flags, type) {
      var _type$prototype;
      if (flags & 12 /* VNodeFlags.ComponentKnown */) {
        return flags;
      }
      if ((_type$prototype = type.prototype) != null && _type$prototype.render) {
        return 4 /* VNodeFlags.ComponentClass */;
      }
      if (type.render) {
        return 32776 /* VNodeFlags.ForwardRefComponent */;
      }
      return 8 /* VNodeFlags.ComponentFunction */;
    }
    function createComponentVNode(flags, type, props, key, ref) {
      {
        if ((flags & 1 /* VNodeFlags.HtmlElement */) !== 0) {
          throwError('Creating element vNodes using createComponentVNode is not allowed. Use Inferno.createVNode method.');
        }
      }
      flags = resolveComponentFlags(flags, type);
      var vNode = new V(1 /* ChildFlags.HasInvalidChildren */, null, null, flags, key, mergeDefaultProps(flags, type, props), mergeDefaultHooks(flags, type, ref), type);
      if (isFunction(options.createVNode)) {
        options.createVNode(vNode);
      }
      return vNode;
    }
    function createTextVNode(text, key) {
      return new V(1 /* ChildFlags.HasInvalidChildren */, isNullOrUndef(text) || text === true || text === false ? '' : text, null, 16 /* VNodeFlags.Text */, key, null, null, null);
    }
    function createFragment(children, childFlags, key) {
      var fragment = createVNode(8192 /* VNodeFlags.Fragment */, 8192 /* VNodeFlags.Fragment */, null, children, childFlags, null, key, null);
      switch (fragment.childFlags) {
        case 1 /* ChildFlags.HasInvalidChildren */:
          fragment.children = createVoidVNode();
          fragment.childFlags = 2 /* ChildFlags.HasVNodeChildren */;
          break;
        case 16 /* ChildFlags.HasTextChildren */:
          fragment.children = [createTextVNode(children)];
          fragment.childFlags = 4 /* ChildFlags.HasNonKeyedChildren */;
          break;
      }
      return fragment;
    }
    function normalizeProps(vNode) {
      var props = vNode.props;
      if (props) {
        var flags = vNode.flags;
        if (flags & 481 /* VNodeFlags.Element */) {
          if (props.children !== void 0 && isNullOrUndef(vNode.children)) {
            normalizeChildren(vNode, props.children);
          }
          if (props.className !== void 0) {
            if (isNullOrUndef(vNode.className)) {
              vNode.className = props.className || null;
            }
            props.className = undefined;
          }
        }
        if (props.key !== void 0) {
          vNode.key = props.key;
          props.key = undefined;
        }
        if (props.ref !== void 0) {
          if (flags & 8 /* VNodeFlags.ComponentFunction */) {
            vNode.ref = _extends$3({}, vNode.ref, props.ref);
          } else {
            vNode.ref = props.ref;
          }
          props.ref = undefined;
        }
      }
      return vNode;
    }
    /*
     * Fragment is different from normal vNode,
     * because when it needs to be cloned we need to clone its children too
     * But not normalize, because otherwise those possibly get KEY and re-mount
     */
    function cloneFragment(vNodeToClone) {
      var oldChildren = vNodeToClone.children;
      var childFlags = vNodeToClone.childFlags;
      return createFragment(childFlags === 2 /* ChildFlags.HasVNodeChildren */ ? directClone(oldChildren) : oldChildren.map(directClone), childFlags, vNodeToClone.key);
    }
    function directClone(vNodeToClone) {
      var flags = vNodeToClone.flags & -16385 /* VNodeFlags.ClearInUse */;
      var props = vNodeToClone.props;
      if (flags & 14 /* VNodeFlags.Component */) {
        if (!isNull(props)) {
          var propsToClone = props;
          props = {};
          for (var key in propsToClone) {
            props[key] = propsToClone[key];
          }
        }
      }
      if ((flags & 8192 /* VNodeFlags.Fragment */) === 0) {
        return new V(vNodeToClone.childFlags, vNodeToClone.children, vNodeToClone.className, flags, vNodeToClone.key, props, vNodeToClone.ref, vNodeToClone.type);
      }
      return cloneFragment(vNodeToClone);
    }
    function createVoidVNode() {
      return createTextVNode('', null);
    }
    function createPortal(children, container) {
      var normalizedRoot = normalizeRoot(children);
      return createVNode(1024 /* VNodeFlags.Portal */, 1024 /* VNodeFlags.Portal */, null, normalizedRoot, 0 /* ChildFlags.UnknownChildren */, null, normalizedRoot.key, container);
    }
    function _normalizeVNodes(nodes, result, index, currentKey) {
      for (var len = nodes.length; index < len; index++) {
        var n = nodes[index];
        if (!isInvalid(n)) {
          var newKey = currentKey + keyPrefix + index;
          if (isArray(n)) {
            _normalizeVNodes(n, result, 0, newKey);
          } else {
            if (isStringOrNumber(n)) {
              n = createTextVNode(n, newKey);
            } else {
              {
                throwIfObjectIsNotVNode(n);
              }
              var oldKey = n.key;
              var isPrefixedKey = isString(oldKey) && oldKey[0] === keyPrefix;
              if (n.flags & 81920 /* VNodeFlags.InUseOrNormalized */ || isPrefixedKey) {
                n = directClone(n);
              }
              n.flags |= 65536 /* VNodeFlags.Normalized */;
              if (!isPrefixedKey) {
                if (isNull(oldKey)) {
                  n.key = newKey;
                } else {
                  n.key = currentKey + oldKey;
                }
              } else if (oldKey.substring(0, currentKey.length) !== currentKey) {
                n.key = currentKey + oldKey;
              }
            }
            result.push(n);
          }
        }
      }
    }
    function getFlagsForElementVnode(type) {
      switch (type) {
        case 'svg':
          return 32 /* VNodeFlags.SvgElement */;
        case 'input':
          return 64 /* VNodeFlags.InputElement */;
        case 'select':
          return 256 /* VNodeFlags.SelectElement */;
        case 'textarea':
          return 128 /* VNodeFlags.TextareaElement */;
        // @ts-expect-error Fragment is special case
        case Fragment:
          return 8192 /* VNodeFlags.Fragment */;
        default:
          return 1 /* VNodeFlags.HtmlElement */;
      }
    }
    function normalizeChildren(vNode, children) {
      var newChildren;
      var newChildFlags = 1 /* ChildFlags.HasInvalidChildren */;
      // Don't change children to match strict equal (===) true in patching
      if (isInvalid(children)) {
        newChildren = children;
      } else if (isStringOrNumber(children)) {
        newChildFlags = 16 /* ChildFlags.HasTextChildren */;
        newChildren = children;
      } else if (isArray(children)) {
        var len = children.length;
        for (var i = 0; i < len; ++i) {
          var n = children[i];
          if (isInvalid(n) || isArray(n)) {
            newChildren = newChildren || children.slice(0, i);
            _normalizeVNodes(children, newChildren, i, '');
            break;
          } else if (isStringOrNumber(n)) {
            newChildren = newChildren || children.slice(0, i);
            newChildren.push(createTextVNode(n, keyPrefix + i));
          } else {
            {
              throwIfObjectIsNotVNode(n);
            }
            var key = n.key;
            var needsCloning = (n.flags & 81920 /* VNodeFlags.InUseOrNormalized */) > 0;
            var isNullKey = isNull(key);
            var isPrefixed = isString(key) && key[0] === keyPrefix;
            if (needsCloning || isNullKey || isPrefixed) {
              newChildren = newChildren || children.slice(0, i);
              if (needsCloning || isPrefixed) {
                n = directClone(n);
              }
              if (isNullKey || isPrefixed) {
                n.key = keyPrefix + i;
              }
              newChildren.push(n);
            } else if (newChildren) {
              newChildren.push(n);
            }
            n.flags |= 65536 /* VNodeFlags.Normalized */;
          }
        }
        newChildren = newChildren || children;
        if (newChildren.length === 0) {
          newChildFlags = 1 /* ChildFlags.HasInvalidChildren */;
        } else {
          newChildFlags = 8 /* ChildFlags.HasKeyedChildren */;
        }
      } else {
        newChildren = children;
        newChildren.flags |= 65536 /* VNodeFlags.Normalized */;
        if (children.flags & 81920 /* VNodeFlags.InUseOrNormalized */) {
          newChildren = directClone(children);
        }
        newChildFlags = 2 /* ChildFlags.HasVNodeChildren */;
      }
      vNode.children = newChildren;
      vNode.childFlags = newChildFlags;
      return vNode;
    }
    function normalizeRoot(input) {
      if (isInvalid(input) || isStringOrNumber(input)) {
        return createTextVNode(input, null);
      }
      if (isArray(input)) {
        return createFragment(input, 0 /* ChildFlags.UnknownChildren */, null);
      }
      return input.flags & 16384 /* VNodeFlags.InUse */ ? directClone(input) : input;
    }
    var xlinkNS = 'http://www.w3.org/1999/xlink';
    var xmlNS = 'http://www.w3.org/XML/1998/namespace';
    var namespaces = {
      'xlink:actuate': xlinkNS,
      'xlink:arcrole': xlinkNS,
      'xlink:href': xlinkNS,
      'xlink:role': xlinkNS,
      'xlink:show': xlinkNS,
      'xlink:title': xlinkNS,
      'xlink:type': xlinkNS,
      'xml:base': xmlNS,
      'xml:lang': xmlNS,
      'xml:space': xmlNS
    };
    function getDelegatedEventObject(v) {
      return {
        onClick: v,
        onDblClick: v,
        onFocusIn: v,
        onFocusOut: v,
        onKeyDown: v,
        onKeyPress: v,
        onKeyUp: v,
        onMouseDown: v,
        onMouseMove: v,
        onMouseUp: v,
        onTouchEnd: v,
        onTouchMove: v,
        onTouchStart: v
      };
    }
    var attachedEventCounts = getDelegatedEventObject(0);
    var attachedEvents = getDelegatedEventObject(null);
    var syntheticEvents = getDelegatedEventObject(true);
    function updateOrAddSyntheticEvent(name, dom) {
      var eventsObject = dom.$EV;
      if (!eventsObject) {
        eventsObject = dom.$EV = getDelegatedEventObject(null);
      }
      if (!eventsObject[name]) {
        if (++attachedEventCounts[name] === 1) {
          attachedEvents[name] = attachEventToDocument(name);
        }
      }
      return eventsObject;
    }
    function unmountSyntheticEvent(name, dom) {
      var eventsObject = dom.$EV;
      if (eventsObject != null && eventsObject[name]) {
        if (--attachedEventCounts[name] === 0) {
          document.removeEventListener(normalizeEventName(name), attachedEvents[name]);
          attachedEvents[name] = null;
        }
        eventsObject[name] = null;
      }
    }
    function handleSyntheticEvent(name, lastEvent, nextEvent, dom) {
      if (isFunction(nextEvent)) {
        updateOrAddSyntheticEvent(name, dom)[name] = nextEvent;
      } else if (isLinkEventObject(nextEvent)) {
        if (isLastValueSameLinkEvent(lastEvent, nextEvent)) {
          return;
        }
        updateOrAddSyntheticEvent(name, dom)[name] = nextEvent;
      } else {
        unmountSyntheticEvent(name, dom);
      }
    }
    // TODO: When browsers fully support event.composedPath we could loop it through instead of using parentNode property
    function getTargetNode(event) {
      return isFunction(event.composedPath) ? event.composedPath()[0] : event.target;
    }
    function dispatchEvents(event, isClick, name, eventData) {
      var dom = getTargetNode(event);
      do {
        // Html Nodes can be nested fe: span inside button in that scenario browser does not handle disabled attribute on parent,
        // because the event listener is on document.body
        // Don't process clicks on disabled elements
        if (isClick && dom.disabled) {
          return;
        }
        var eventsObject = dom.$EV;
        if (!isNullOrUndef(eventsObject)) {
          var currentEvent = eventsObject[name];
          if (currentEvent) {
            // linkEvent object
            eventData.dom = dom;
            if (currentEvent.event) {
              currentEvent.event(currentEvent.data, event);
            } else {
              currentEvent(event);
            }
            if (event.cancelBubble) {
              return;
            }
          }
        }
        dom = dom.parentNode;
      } while (!isNull(dom));
    }
    function stopPropagation() {
      this.cancelBubble = true;
      if (!this.immediatePropagationStopped) {
        this.stopImmediatePropagation();
      }
    }
    function isDefaultPrevented() {
      return this.defaultPrevented;
    }
    function isPropagationStopped() {
      return this.cancelBubble;
    }
    function extendEventProperties(event) {
      // Event data needs to be an object to save reference to currentTarget getter
      var eventData = {
        dom: document
      };
      event.isDefaultPrevented = isDefaultPrevented;
      event.isPropagationStopped = isPropagationStopped;
      event.stopPropagation = stopPropagation;
      Object.defineProperty(event, 'currentTarget', {
        configurable: true,
        get: function get() {
          return eventData.dom;
        }
      });
      return eventData;
    }
    function rootEvent(name) {
      var isClick = name === 'onClick' || name === 'onDblClick';
      return function (event) {
        dispatchEvents(event, isClick, name, extendEventProperties(event));
      };
    }
    function attachEventToDocument(name) {
      var attachedEvent = rootEvent(name);
      document.addEventListener(normalizeEventName(name), attachedEvent);
      return attachedEvent;
    }
    function isSameInnerHTML(dom, innerHTML) {
      var temp = document.createElement('i');
      temp.innerHTML = innerHTML;
      return temp.innerHTML === dom.innerHTML;
    }
    function triggerEventListener(props, methodName, e) {
      var listener = props[methodName];
      if (listener) {
        if (listener.event) {
          listener.event(listener.data, e);
        } else {
          listener(e);
        }
      } else {
        var nativeListenerName = methodName.toLowerCase();
        if (isFunction(props[nativeListenerName])) {
          props[nativeListenerName](e);
        }
      }
    }
    function createWrappedFunction(methodName, applyValue) {
      var fnWrapper = function fnWrapper(e) {
        var _vNode$props;
        var vNode = this.$V;
        // If vNode is gone by the time event fires, no-op
        if (isNullOrUndef(vNode)) {
          return;
        }
        var props = (_vNode$props = vNode.props) != null ? _vNode$props : EMPTY_OBJ;
        var dom = vNode.dom;
        if (isString(methodName)) {
          triggerEventListener(props, methodName, e);
        } else {
          for (var i = 0; i < methodName.length; ++i) {
            triggerEventListener(props, methodName[i], e);
          }
        }
        if (isFunction(applyValue)) {
          var _newVNode$props;
          var newVNode = this.$V;
          var newProps = (_newVNode$props = newVNode.props) != null ? _newVNode$props : EMPTY_OBJ;
          applyValue(newProps, dom, false, newVNode);
        }
      };
      Object.defineProperty(fnWrapper, 'wrapped', {
        configurable: false,
        enumerable: false,
        value: true,
        writable: false
      });
      return fnWrapper;
    }
    function attachEvent(dom, eventName, handler) {
      var previousKey = "$" + eventName;
      var previousArgs = dom[previousKey];
      if (previousArgs) {
        if (previousArgs[1].wrapped) {
          return;
        }
        dom.removeEventListener(previousArgs[0], previousArgs[1]);
        dom[previousKey] = null;
      }
      if (isFunction(handler)) {
        dom.addEventListener(eventName, handler);
        dom[previousKey] = [eventName, handler];
      }
    }
    function isCheckedType(type) {
      return type === 'checkbox' || type === 'radio';
    }
    var onTextInputChange = createWrappedFunction('onInput', applyValueInput);
    var wrappedOnChange$1 = createWrappedFunction(['onClick', 'onChange'], applyValueInput);
    function stopPropagationWrapper(event) {
      event.stopPropagation();
    }
    stopPropagationWrapper.wrapped = true;
    function inputEvents(dom, nextPropsOrEmpty) {
      if (isCheckedType(nextPropsOrEmpty.type)) {
        attachEvent(dom, 'change', wrappedOnChange$1);
        attachEvent(dom, 'click', stopPropagationWrapper);
      } else {
        attachEvent(dom, 'input', onTextInputChange);
      }
    }
    function applyValueInput(nextPropsOrEmpty, dom) {
      var type = nextPropsOrEmpty.type;
      var value = nextPropsOrEmpty.value;
      var checked = nextPropsOrEmpty.checked;
      var multiple = nextPropsOrEmpty.multiple;
      var defaultValue = nextPropsOrEmpty.defaultValue;
      var hasValue = !isNullOrUndef(value);
      if (type != null && type !== dom.type) {
        dom.setAttribute('type', type);
      }
      if (!isNullOrUndef(multiple) && multiple !== dom.multiple) {
        dom.multiple = multiple;
      }
      if (!isNullOrUndef(defaultValue) && !hasValue) {
        if (defaultValue !== dom.value) {
          dom.value = defaultValue + '';
        }
        dom.defaultValue = defaultValue + '';
      }
      if (isCheckedType(type)) {
        if (hasValue) {
          dom.value = value;
        }
        if (!isNullOrUndef(checked)) {
          dom.checked = checked;
        }
      } else {
        if (hasValue && dom.value !== value) {
          dom.defaultValue = value;
          dom.value = value;
        } else if (!isNullOrUndef(checked)) {
          dom.checked = checked;
        }
      }
    }
    function updateChildOptions(vNode, value) {
      if (vNode.type === 'option') {
        updateChildOption(vNode, value);
      } else {
        var children = vNode.children;
        var flags = vNode.flags;
        if ((flags & 4 /* VNodeFlags.ComponentClass */) !== 0) {
          updateChildOptions(children.$LI, value);
        } else if ((flags & 8 /* VNodeFlags.ComponentFunction */) !== 0) {
          updateChildOptions(children, value);
        } else if (vNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) {
          updateChildOptions(children, value);
        } else if ((vNode.childFlags & 12 /* ChildFlags.MultipleChildren */) !== 0) {
          for (var i = 0, len = children.length; i < len; ++i) {
            updateChildOptions(children[i], value);
          }
        }
      }
    }
    function updateChildOption(vNode, value) {
      var _vNode$props;
      var props = (_vNode$props = vNode.props) != null ? _vNode$props : EMPTY_OBJ;
      var propsValue = props.value;
      var dom = vNode.dom;
      // we do this as multiple prop may have changed
      dom.value = propsValue;
      if (propsValue === value || isArray(value) && value.includes(propsValue)) {
        dom.selected = true;
      } else if (!isNullOrUndef(value) || !isNullOrUndef(props.selected)) {
        dom.selected = Boolean(props.selected);
      }
    }
    var onSelectChange = createWrappedFunction('onChange', applyValueSelect);
    function selectEvents(dom) {
      attachEvent(dom, 'change', onSelectChange);
    }
    function applyValueSelect(nextPropsOrEmpty, dom, mounting, vNode) {
      var multiplePropInBoolean = Boolean(nextPropsOrEmpty.multiple);
      if (!isNullOrUndef(nextPropsOrEmpty.multiple) && multiplePropInBoolean !== dom.multiple) {
        dom.multiple = multiplePropInBoolean;
      }
      var index = nextPropsOrEmpty.selectedIndex;
      if (index === -1) {
        dom.selectedIndex = -1;
      }
      var childFlags = vNode.childFlags;
      if (childFlags !== 1 /* ChildFlags.HasInvalidChildren */) {
        var value = nextPropsOrEmpty.value;
        if (isNumber(index) && index > -1 && !isNullOrUndef(dom.options[index])) {
          value = dom.options[index].value;
        }
        if (mounting && isNullOrUndef(value)) {
          value = nextPropsOrEmpty.defaultValue;
        }
        updateChildOptions(vNode, value);
      }
    }
    var onTextareaInputChange = createWrappedFunction('onInput', applyValueTextArea);
    var wrappedOnChange = createWrappedFunction('onChange');
    function textAreaEvents(dom, nextPropsOrEmpty) {
      attachEvent(dom, 'input', onTextareaInputChange);
      if (isFunction(nextPropsOrEmpty.onChange)) {
        attachEvent(dom, 'change', wrappedOnChange);
      }
    }
    function applyValueTextArea(nextPropsOrEmpty, dom, mounting) {
      var value = nextPropsOrEmpty.value;
      var domValue = dom.value;
      if (isNullOrUndef(value)) {
        if (mounting) {
          var defaultValue = nextPropsOrEmpty.defaultValue;
          if (!isNullOrUndef(defaultValue) && defaultValue !== domValue) {
            dom.defaultValue = defaultValue;
            dom.value = defaultValue;
          }
        }
      } else if (domValue !== value) {
        /* There is value so keep it controlled */
        dom.defaultValue = value;
        dom.value = value;
      }
    }
    function processElement(flags, vNode, dom, nextPropsOrEmpty, mounting, isControlled) {
      if ((flags & 64 /* VNodeFlags.InputElement */) !== 0) {
        applyValueInput(nextPropsOrEmpty, dom);
      } else if ((flags & 256 /* VNodeFlags.SelectElement */) !== 0) {
        applyValueSelect(nextPropsOrEmpty, dom, mounting, vNode);
      } else if ((flags & 128 /* VNodeFlags.TextareaElement */) !== 0) {
        applyValueTextArea(nextPropsOrEmpty, dom, mounting);
      }
      if (isControlled) {
        dom.$V = vNode;
      }
    }
    function addFormElementEventHandlers(flags, dom, nextPropsOrEmpty) {
      if ((flags & 64 /* VNodeFlags.InputElement */) !== 0) {
        inputEvents(dom, nextPropsOrEmpty);
      } else if ((flags & 256 /* VNodeFlags.SelectElement */) !== 0) {
        selectEvents(dom);
      } else if ((flags & 128 /* VNodeFlags.TextareaElement */) !== 0) {
        textAreaEvents(dom, nextPropsOrEmpty);
      }
    }
    function isControlledFormElement(nextPropsOrEmpty) {
      return isCheckedType(nextPropsOrEmpty.type) ? !isNullOrUndef(nextPropsOrEmpty.checked) : !isNullOrUndef(nextPropsOrEmpty.value);
    }
    function createRef() {
      return {
        current: null
      };
    }
    // TODO: Make this return value typed
    function forwardRef(render) {
      {
        if (!isFunction(render)) {
          warning("forwardRef requires a render function but was given " + (render === null ? 'null' : typeof render) + ".");
          return;
        }
      }
      return {
        render: render
      };
    }
    function unmountRef(ref) {
      if (!isNullOrUndef(ref)) {
        if (!safeCall1(ref, null) && ref.current) {
          ref.current = null;
        }
      }
    }
    function mountRef(ref, value, lifecycle) {
      if (!isNullOrUndef(ref) && (isFunction(ref) || ref.current !== void 0)) {
        lifecycle.push(function () {
          if (!safeCall1(ref, value) && ref.current !== void 0) {
            ref.current = value;
          }
        });
      }
    }
    function remove(vNode, parentDOM, animations) {
      unmount(vNode, animations);
      removeVNodeDOM(vNode, parentDOM, animations);
    }
    function unmount(vNode, animations) {
      var flags = vNode.flags;
      var children = vNode.children;
      var ref;
      if ((flags & 481 /* VNodeFlags.Element */) !== 0) {
        ref = vNode.ref;
        var props = vNode.props;
        unmountRef(ref);
        var childFlags = vNode.childFlags;
        if (!isNull(props)) {
          var keys = Object.keys(props);
          for (var i = 0, len = keys.length; i < len; i++) {
            var key = keys[i];
            if (syntheticEvents[key]) {
              unmountSyntheticEvent(key, vNode.dom);
            }
          }
        }
        if (childFlags & 12 /* ChildFlags.MultipleChildren */) {
          unmountAllChildren(children, animations);
        } else if (childFlags === 2 /* ChildFlags.HasVNodeChildren */) {
          unmount(children, animations);
        }
      } else if (children) {
        if (flags & 4 /* VNodeFlags.ComponentClass */) {
          if (isFunction(children.componentWillUnmount)) {
            // TODO: Possible entrypoint
            children.componentWillUnmount();
          }
          // If we have a componentWillDisappear on this component, block children from animating
          var childAnimations = animations;
          if (isFunction(children.componentWillDisappear)) {
            childAnimations = new AnimationQueues();
            addDisappearAnimationHook(animations, children, children.$LI.dom, flags, undefined);
          }
          unmountRef(vNode.ref);
          children.$UN = true;
          unmount(children.$LI, childAnimations);
        } else if (flags & 8 /* VNodeFlags.ComponentFunction */) {
          // If we have a onComponentWillDisappear on this component, block children from animating
          var _childAnimations = animations;
          ref = vNode.ref;
          if (!isNullOrUndef(ref)) {
            var domEl = null;
            if (isFunction(ref.onComponentWillUnmount)) {
              domEl = findDOMFromVNode(vNode, true);
              ref.onComponentWillUnmount(domEl, vNode.props || EMPTY_OBJ);
            }
            if (isFunction(ref.onComponentWillDisappear)) {
              _childAnimations = new AnimationQueues();
              domEl = domEl || findDOMFromVNode(vNode, true);
              addDisappearAnimationHook(animations, ref, domEl, flags, vNode.props);
            }
          }
          unmount(children, _childAnimations);
        } else if (flags & 1024 /* VNodeFlags.Portal */) {
          remove(children, vNode.ref, animations);
        } else if (flags & 8192 /* VNodeFlags.Fragment */) {
          if (vNode.childFlags & 12 /* ChildFlags.MultipleChildren */) {
            unmountAllChildren(children, animations);
          }
        }
      }
    }
    function unmountAllChildren(children, animations) {
      for (var i = 0, len = children.length; i < len; ++i) {
        unmount(children[i], animations);
      }
    }
    function createClearAllCallback(children, parentDOM) {
      return function () {
        // We need to remove children one by one because elements can be added during animation
        if (parentDOM) {
          for (var i = 0; i < children.length; i++) {
            var vNode = children[i];
            clearVNodeDOM(vNode, parentDOM, false);
          }
        }
      };
    }
    function clearDOM(parentDOM, children, animations) {
      if (animations.componentWillDisappear.length > 0) {
        // Wait until animations are finished before removing actual dom nodes
        // Be aware that the element could be removed by a later operation
        callAllAnimationHooks(animations.componentWillDisappear, createClearAllCallback(children, parentDOM));
      } else {
        // Optimization for clearing dom
        parentDOM.textContent = '';
      }
    }
    function removeAllChildren(dom, vNode, children, animations) {
      unmountAllChildren(children, animations);
      if (vNode.flags & 8192 /* VNodeFlags.Fragment */) {
        removeVNodeDOM(vNode, dom, animations);
      } else {
        clearDOM(dom, children, animations);
      }
    }
    // Only add animations to queue in browser
    function addDisappearAnimationHook(animations, instanceOrRef, dom, flags, props) {
      // @ts-expect-error TODO: Here is something weird check this behavior
      animations.componentWillDisappear.push(function (callback) {
        if (flags & 4 /* VNodeFlags.ComponentClass */) {
          instanceOrRef.componentWillDisappear(dom, callback);
        } else if (flags & 8 /* VNodeFlags.ComponentFunction */) {
          instanceOrRef.onComponentWillDisappear(dom, props, callback);
        }
      });
    }
    function wrapLinkEvent(nextValue) {
      // This variable makes sure there is no "this" context in callback
      var ev = nextValue.event;
      return function (e) {
        ev(nextValue.data, e);
      };
    }
    function patchEvent(name, lastValue, nextValue, dom) {
      if (isLinkEventObject(nextValue)) {
        if (isLastValueSameLinkEvent(lastValue, nextValue)) {
          return;
        }
        nextValue = wrapLinkEvent(nextValue);
      }
      attachEvent(dom, normalizeEventName(name), nextValue);
    }
    // We are assuming here that we come from patchProp routine
    // -nextAttrValue cannot be null or undefined
    function patchStyle(lastAttrValue, nextAttrValue, dom) {
      if (isNullOrUndef(nextAttrValue)) {
        dom.removeAttribute('style');
        return;
      }
      var domStyle = dom.style;
      var style;
      var value;
      if (isString(nextAttrValue)) {
        domStyle.cssText = nextAttrValue;
        return;
      }
      if (!isNullOrUndef(lastAttrValue) && !isString(lastAttrValue)) {
        for (style in nextAttrValue) {
          // do not add a hasOwnProperty check here, it affects performance
          value = nextAttrValue[style];
          if (value !== lastAttrValue[style]) {
            domStyle.setProperty(style, value);
          }
        }
        for (style in lastAttrValue) {
          if (isNullOrUndef(nextAttrValue[style])) {
            domStyle.removeProperty(style);
          }
        }
      } else {
        for (style in nextAttrValue) {
          value = nextAttrValue[style];
          domStyle.setProperty(style, value);
        }
      }
    }
    function patchDangerInnerHTML(lastValue, nextValue, lastVNode, dom, animations) {
      var lastHtml = (lastValue == null ? void 0 : lastValue.__html) || '';
      var nextHtml = (nextValue == null ? void 0 : nextValue.__html) || '';
      if (lastHtml !== nextHtml) {
        if (!isNullOrUndef(nextHtml) && !isSameInnerHTML(dom, nextHtml)) {
          if (!isNull(lastVNode)) {
            if (lastVNode.childFlags & 12 /* ChildFlags.MultipleChildren */) {
              unmountAllChildren(lastVNode.children, animations);
            } else if (lastVNode.childFlags === 2 /* ChildFlags.HasVNodeChildren */) {
              unmount(lastVNode.children, animations);
            }
            lastVNode.children = null;
            lastVNode.childFlags = 1 /* ChildFlags.HasInvalidChildren */;
          }
          dom.innerHTML = nextHtml;
        }
      }
    }
    function patchDomProp(nextValue, dom, prop) {
      var value = isNullOrUndef(nextValue) ? '' : nextValue;
      if (dom[prop] !== value) {
        dom[prop] = value;
      }
    }
    function patchProp(prop, lastValue, nextValue, dom, isSVG, hasControlledValue, lastVNode, animations) {
      switch (prop) {
        case 'children':
        case 'childrenType':
        case 'className':
        case 'defaultValue':
        case 'key':
        case 'multiple':
        case 'ref':
        case 'selectedIndex':
          break;
        case 'autoFocus':
          dom.autofocus = !!nextValue;
          break;
        case 'allowfulls