code: def get_image_conditioning_js_callback(
      *,
      user_query_box_data_source: models.ColumnDataSource,
      model_query_box_data_source: models.ColumnDataSource,
      pred_box_data_source: models.ColumnDataSource,
  ) -> callbacks.CustomJS:
      """Creates the CustomJS callback that will be triggered upon query entry.
  
      The JavaScript callback in turn calls back to Python, specifically to a
      function with the name specified in py_callback_name, via
      google.colab.kernel.invokeFunction. The Python callback should return a
      color_updates data structure consisting of a list of (box_index, hex_color)
      tuples.
  
      Args:
        user_query_box_data_source: Bokeh ColumnDataSource linked to the query box
          drawn by the user.
        model_query_box_data_source: Bokeh ColumnDataSource linked to the query box
          selected from the model predictions on the source image.
        pred_box_data_source: Bokeh ColumnDataSource linked to the boxes predicted
          for the target image.
  
      Returns:
        Bokeh CustomJS callback object.
      """
      return callbacks.CustomJS(
          args=dict(
              user_query_box_data_source=user_query_box_data_source,
              model_query_box_data_source=model_query_box_data_source,
              pred_box_data_source=pred_box_data_source,
          ),
          code="""
            (async function() {
            // Get query box coordinates:
            const geometry = cb_obj['geometry'];
            const width = geometry['x1'] - geometry['x0'];
            const height = geometry['y0'] - geometry['y1'];
            const x = geometry['x0'] + width/2;
            const y = geometry['y1'] + height/2;
  
            // Update source image with user-drawn query box:
            const data = user_query_box_data_source.data;
            data['x'][0] = x;
            data['y'][0] = y;
            data['width'][0] = width;
            data['height'][0] = height;
            user_query_box_data_source.change.emit();
  
            // Update target plot:
            const result = await google.colab.kernel.invokeFunction(
              '"""
          + IMAGE_CONDITIONING_PY_CALLBACK_NAME
          + """', [geometry], {});
            var result_text = result['data']['text/plain']
            // Need to strip enclosing quotes since invokeFunction returns str:
            result_text = result_text.substring(1, result_text.length-1);
            const result_json = JSON.parse(result_text);
  
            const color_updates = result_json['color_updates']
            const colors = pred_box_data_source.data['colors']
            for (let i = 0; i < color_updates.length; i++) {
                  // Element 0 is the box index, element 1 is the hex color:
                  colors[color_updates[i][0]] = color_updates[i][1]
              }
            pred_box_data_source.change.emit();
  
            // Update source image with actual query box from model:
            const data2 = model_query_box_data_source.data;
            data2['x'][0] = result_json['selected_box']['x'];
            data2['y'][0] = result_json['selected_box']['y'];
            data2['width'][0] = result_json['selected_box']['w'];
            data2['height'][0] = result_json['selected_box']['h'];
            model_query_box_data_source.change.emit();
  
            })();
            """,
      )
  
imports: import base64
  import functools
  import json
  from typing import Any, Mapping, Union
  from bokeh import models
  from bokeh.models import callbacks
  from bokeh.models import widgets
  import matplotlib
  import matplotlib.pyplot
  import numpy
  from scenic.model_lib.base_models import box_utils
  from scenic.projects.owl_vit.notebooks import inference
label_desc: Use image node_id 6 for calling a global function with example usage: get_image_conditioning_js_callback() and returns: callbacks