docs: def map_routes(
      feed: "Feed",
      route_ids: List[str],
      date: Optional[str] = None,
      color_palette: List[str] = cs.COLORS_SET2,
      *,
      include_stops: bool = True,
  ):
      """
      Return a Folium map showing the given routes and (optionally)
      their stops.
  
      Parameters
      ----------
      feed : Feed
      route_ids : list
          IDs of routes in ``feed.routes``
      date : string
          YYYYMMDD date string restricting the output to trips active
          on the date
      color_palette : list
          Palette to use to color the routes. If more routes than colors,
          then colors will be recycled.
      include_stops : boolean
          If ``True``, then include stops in the map
  
      Returns
      -------
      dictionary
          A Folium Map depicting the distinct shapes of the trips on
          each route.
          If ``include_stops``, then include the stops for each route.
  
      Notes
      ------
      - Requires Folium
  
      """
      import folium as fl
  
      # Get routes slice and convert to dictionary
      routes = (
          feed.routes.loc[lambda x: x["route_id"].isin(route_ids)]
          .fillna("n/a")
          .to_dict(orient="records")
      )
  
      # Create route colors
      n = len(routes)
      colors = [color_palette[i % len(color_palette)] for i in range(n)]
  
      # Initialize map
      my_map = fl.Map(tiles="cartodbpositron")
  
      # Collect route bounding boxes to set map zoom later
      bboxes = []
  
      # Create a feature group for each route and add it to the map
      for i, route in enumerate(routes):
          collection = feed.route_to_geojson(
              route_id=route["route_id"], date=date, include_stops=include_stops
          )
          group = fl.FeatureGroup(name="Route " + route["route_short_name"])
          color = colors[i]
  
          for f in collection["features"]:
              prop = f["properties"]
  
              # Add stop
              if f["geometry"]["type"] == "Point":
                  lon, lat = f["geometry"]["coordinates"]
                  fl.CircleMarker(
                      location=[lat, lon],
                      radius=8,
                      fill=True,
                      color=color,
                      weight=1,
                      popup=fl.Popup(hp.make_html(prop)),
                  ).add_to(group)
  
              # Add path
              else:
                  prop["color"] = color
                  path = fl.GeoJson(
                      f,
                      name=route,
                      style_function=lambda x: {
                          "color": x["properties"]["color"]
                      },
                  )
                  path.add_child(fl.Popup(hp.make_html(prop)))
                  path.add_to(group)
                  bboxes.append(sg.box(*sg.shape(f["geometry"]).bounds))
  
          group.add_to(my_map)
  
      fl.LayerControl().add_to(my_map)
  
      # Fit map to bounds
      bounds = so.unary_union(bboxes).bounds
      bounds2 = [bounds[1::-1], bounds[3:1:-1]]  # Folium expects this ordering
      my_map.fit_bounds(bounds2)
  
      return my_map