code: def jac(func: Callable):
      def grad_fn(x_in):
          return ivy.to_native(
              func(ivy.to_ivy(x_in, nested=True)),
              nested=True,
              include_derived=True,
          )
  
      def callback_fn(x_in):
          with tf.GradientTape(persistent=True) as tape:
              ivy.nested_map(ivy.copy_array, x_in)
              x_in = ivy.to_native(x_in, nested=True)
              tape.watch(x_in)
              y = grad_fn(x_in)
  
              # Deal with multiple outputs
              if not isinstance(y, ivy.NativeArray):
                  jacobian = ivy.nested_map(
                      lambda yi: ivy.to_ivy(
                          tape.jacobian(
                              yi, x_in, unconnected_gradients="zero"
                          ),
                          nested=True,
                      ),
                      y,
                      include_derived=True,
                  )
              else:
                  jacobian = ivy.to_ivy(tape.jacobian(y, x_in))
          return jacobian
  
      return callback_fn
  
file_path: ivy/ivy/functional/backends/tensorflow/gradients.py
imports: import tensorflow
  from typing import Sequence, Union, Optional, Callable
  import ivy
  from ivy.func_wrapper import outputs_to_ivy_arrays, inputs_to_native_arrays
  from ivy.functional.ivy.gradients import _get_required_float_variables, _get_y_and_ret_idxs, _get_native_y, _set_duplicates, _process_func_ret_and_grads
label_desc: Use image node_id 8 for calling a global function with example usage: jac(func) and returns: callback_fn, ivy, jacobian