src/Transition.js
function transitionRoot(fromState, toState, isUpdate, paramsDiff) {
  let closestCommonParent

  const parents = [fromState].concat(fromState.parents).reverse()

  // Find the closest common parent of the from/to states, if any.
  if (!isUpdate) {
    for (let i = 0; i < fromState.parents.length; i++) {
      const parent = fromState.parents[i]

      if (toState.parents.indexOf(parent) > -1) {
        closestCommonParent = parent
        break
      }
    }
  }

  // Find the top-most parent owning some updated param(s) or bail if we first reach the closestCommonParent
  for (let i = 0; i < parents.length; i++) {
    const parent = parents[i]

    for (let param in paramsDiff.all) {
      if (parent.params[param] || parent.queryParams[param])
        return { root: parent, inclusive: true }
    }

    if (parent === closestCommonParent)
      return { root: closestCommonParent, inclusive: false }
  }

  return closestCommonParent
    ? { root: closestCommonParent, inclusive: false }
    : { inclusive: true }
}
function transitionRoot(fromState, toState, isUpdate, paramsDiff) {
  let closestCommonParent

  const parents = [fromState].concat(fromState.parents).reverse()

  // Find the closest common parent of the from/to states, if any.
  if (!isUpdate) {
    for (let i = 0; i < fromState.parents.length; i++) {
      const parent = fromState.parents[i]

      if (toState.parents.indexOf(parent) > -1) {
        closestCommonParent = parent
        break
      }
    }
  }

  // Find the top-most parent owning some updated param(s) or bail if we first reach the closestCommonParent
  for (let i = 0; i < parents.length; i++) {
    const parent = parents[i]

    for (let param in paramsDiff.all) {
      if (parent.params[param] || parent.queryParams[param])
        return { root: parent, inclusive: true }
    }

    if (parent === closestCommonParent)
      return { root: closestCommonParent, inclusive: false }
  }

  return closestCommonParent
    ? { root: closestCommonParent, inclusive: false }
    : { inclusive: true }
}
/*
The top-most fromState's parent that must be exited
or undefined if the two states are in distinct branches of the tree.