docs: def draw_menu(cb, params, qwertz):
      """
      Draws the application's side menu and options.
  
      :param cb: Cursebox instance.
      :type cb: cursebox.Cursebox
      :param params: Current application parameters.
      :type params: params.Params
      """
      w = cb.width
      h = cb.height
  
      x0 = w - MENU_WIDTH + 1
  
      # Clear buffer inside the box
      fill(cb, x0, 1, MENU_WIDTH, h - 2, " ")
  
      def draw_option(key, value, shortcuts):
          """
          Helper function to draw options. Self-increments own counter.
  
          :param key: Name of the option.
          :param value: Value of the option.
          :param shortcuts: Keyboard shortcut keys.
          :return:
          """
          draw_text(cb, x0 + 1, 2 + draw_option.counter,
                    "%s %s %s" % (key, str(value).rjust(MENU_WIDTH - 14 - len(key)), shortcuts))
          draw_option.counter += 1
      draw_option.counter = 1
  
      z = "Z"
      y = "Y"
      if qwertz:
          z, y = y, z
  
      h_seps = [2]
      # Draw title
      draw_text(cb, x0, 1, ("Almonds %s" % __version__).center(MENU_WIDTH - 2))
      # Write options (and stats)
      # Mandelbrot position
      draw_option("Real", "{0:.13g}".format(params.mb_cx),
                  "$[" + symbols["ARROW_LEFT"] + "]$, $[" + symbols["ARROW_RIGHT"] + "]$")
      draw_option("Imaginary", "{0:.13g}".format(params.mb_cy),
                  "$[" + symbols["ARROW_UP"] + "]$, $[" + symbols["ARROW_DOWN"] + "]$")
      # FIXME: try to find a way to avoid this hack
      if is_native_windows():
          cb.put_arrow(x0 + 30, 3, "up", colors.default_bg(), colors.default_fg())
          cb.put_arrow(x0 + 35, 3, "down", colors.default_bg(), colors.default_fg())
          cb.put_arrow(x0 + 30, 4, "left", colors.default_bg(), colors.default_fg())
          cb.put_arrow(x0 + 35, 4, "right", colors.default_bg(), colors.default_fg())
      draw_option("Input coordinates...", "", "$[Enter]$")
      draw_option.counter += 1
      h_seps.append(draw_option.counter + 1)
      # Mandelbrot options
      draw_option("Move speed", params.move_speed, "$[C]$, $[V]$")
      draw_option("Zoom", "{0:.13g}".format(params.zoom), "$[" + y + "]$, $[U]$")
      draw_option("Iterations", params.max_iterations, "$[I]$, $[O]$")
      draw_option("Julia mode", "On" if params.julia else "Off", "$[J]$")
      draw_option.counter += 1
      h_seps.append(draw_option.counter + 1)
      # Palette options
      draw_option("Palette", PALETTES[params.palette][0], "$[P]$")
      draw_option("Color mode", DITHER_TYPES[params.dither_type][0], "$[D]$")
      draw_option("Order", "Reversed" if params.reverse_palette else "Normal", "$[R]$")
      draw_option("Mode", "Adaptive" if params.adaptive_palette else "Linear", "$[A]$")
      draw_option("Cycle!", "", "$[" + z + "]$")
      draw_option.counter += 1
      h_seps.append(draw_option.counter + 1)
      # Misc.
      draw_option("Hi-res capture", "", "$[H]$")
      draw_option("Crosshairs", "On" if params.crosshairs else "Off", "$[X]$")
      draw_option("Theme", "Dark" if colors.dark else "Light", "$[T]$")
      draw_option("Save", "", "$[S]$")
      draw_option("Load...", "", "$[L]$")
      draw_option("Exit", "", "$[ESC]$")
  
      # Draw box with separators
      middle = 3 + draw_option.counter
      draw_box(cb, w - MENU_WIDTH, 0, MENU_WIDTH, h, h_seps=h_seps + [middle - 1, middle + 1])
  
      # Draw log
      draw_text(cb, x0, middle, "Event log".center(MENU_WIDTH - 2))
      latest_logs = params.log.get_latest(h - middle)
      latest_logs = [textwrap.wrap(l, MENU_WIDTH - 4)[::-1] for l in latest_logs]  # Wrap all messages
      latest_logs = [l for ls in latest_logs for l in ls]                          # Flatten [[str]] -> [str]
      i = h - 2
      for l in latest_logs:
          draw_text(cb, x0 + 1, i, l)
          i -= 1
          if i == middle + 1:
              break