code: def perform_input(self, actions):
      discrete_keyboard_keys = set()
      discrete_keyboard_labels = set()
  
      for label, game_input, value in actions:
          # Discrete Space
          if value is None:
              if len(game_input) == 0:
                  discrete_keyboard_labels.add(label)
                  continue
  
              for game_input_item in game_input:
                  if isinstance(game_input_item, KeyboardEvent):
                      if game_input_item.event == KeyboardEvents.DOWN:
                          discrete_keyboard_keys.add(
                              game_input_item.keyboard_key
                          )
                          discrete_keyboard_labels.add(label)
  
      discrete_keyboard_keys_sent = False
  
      for label, game_input, value in actions:
          # Discrete
          if value is None:
              # Discrete - Keyboard
              if (
                  len(discrete_keyboard_keys) == 0
                  and len(discrete_keyboard_labels) > 0
              ) or isinstance(
                  game_input[0] if len(game_input) else None,
                  KeyboardEvent,
              ):
                  if not discrete_keyboard_keys_sent:
                      self.input_controller.handle_keys(
                          list(discrete_keyboard_keys)
                      )
  
                      self.analytics_client.track(
                          event_key="GAME_INPUT",
                          data={
                              "keyboard": {
                                  "type": "DISCRETE",
                                  "label": " - ".join(
                                      sorted(discrete_keyboard_labels)
                                  ),
                                  "inputs": sorted(
                                      [
                                          keyboard_key.value
                                          for keyboard_key in discrete_keyboard_keys
                                      ]
                                  ),
                              },
                              "mouse": {},
                          },
                      )
  
                      discrete_keyboard_keys_sent = True
              # Discrete - Mouse
              elif isinstance(game_input[0], MouseEvent):
                  for event in game_input:
                      if event.event == MouseEvents.CLICK:
                          self.input_controller.click(
                              button=event.button
                          )
                      elif event.event == MouseEvents.CLICK_DOWN:
                          self.input_controller.click_down(
                              button=event.button
                          )
                      elif event.event == MouseEvents.CLICK_UP:
                          self.input_controller.click_up(
                              button=event.button
                          )
                      elif (
                          event.event == MouseEvents.CLICK_SCREEN_REGION
                      ):
                          screen_region = event.kwargs["screen_region"]
                          self.input_controller.click_screen_region(
                              button=event.button,
                              screen_region=screen_region,
                          )
                      elif event.event == MouseEvents.SCROLL:
                          self.input_controller.scroll(
                              direction=event.direction
                          )
  
                      self.analytics_client.track(
                          event_key="GAME_INPUT",
                          data={
                              "keyboard": {},
                              "mouse": {
                                  "type": "DISCRETE",
                                  "label": label,
                                  "label_technical": event.as_label,
                                  "input": event.as_input,
                                  "value": value,
                              },
                          },
                      )
          # Continuous
          else:
              if isinstance(game_input[0], KeyboardEvent):
                  self.input_controller.tap_keys(
                      [event.keyboard_key for event in game_input],
                      duration=value,
                  )
  
                  self.analytics_client.track(
                      event_key="GAME_INPUT",
                      data={
                          "keyboard": {
                              "type": "CONTINUOUS",
                              "label": label,
                              "inputs": sorted(
                                  [
                                      event.keyboard_key.value
                                      for event in game_input
                                  ]
                              ),
                              "duration": value,
                          },
                          "mouse": {},
                      },
                  )
              elif isinstance(game_input[0], MouseEvent):
                  # TODO: Tag Analytics
                  for event in game_input:
                      if event.event == MouseEvents.CLICK_SCREEN_REGION:
                          screen_region = event.kwargs["screen_region"]
                          self.input_controller.click_screen_region(
                              button=event.button,
                              screen_region=screen_region,
                          )
                      elif event.event == MouseEvents.MOVE:
                          self.input_controller.move(
                              x=event.x, y=event.y
                          )
                      elif event.event == MouseEvents.MOVE_RELATIVE:
                          self.input_controller.move(
                              x=event.x, y=event.y, absolute=False
                          )
                      elif event.event == MouseEvents.DRAG_START:
                          screen_region = event.kwargs.get(
                              "screen_region"
                          )
                          coordinates = self.input_controller.ratios_to_coordinates(
                              value, screen_region=screen_region
                          )
  
                          self.input_controller.move(
                              x=coordinates[0],
                              y=coordinates[1],
                              duration=0.1,
                          )
                          self.input_controller.click_down(
                              button=event.button
                          )
                      elif event.event == MouseEvents.DRAG_END:
                          screen_region = event.kwargs.get(
                              "screen_region"
                          )
                          coordinates = self.input_controller.ratios_to_coordinates(
                              value, screen_region=screen_region
                          )
  
                          self.input_controller.move(
                              x=coordinates[0],
                              y=coordinates[1],
                              duration=0.1,
                          )
                          self.input_controller.click_up(
                              button=event.button
                          )
  
file_path: SerpentAI/serpent/environment.py
imports: import time
  import collections
  from serpent.input_controller import KeyboardEvent, KeyboardEvents
  from serpent.input_controller import MouseEvent, MouseEvents
  from serpent.config import config
  from serpent.analytics_client import AnalyticsClient
label_desc: Use image node_id 11 for calling the Environment obj's underlying member method code with example usage: obj.perform_input(actions) without return types