# Path: mapbox/encoding.py
# def encode_waypoints(features, min_limit=None, max_limit=None, precision=6):
#     """Given an iterable of features
#     return a string encoded in waypoint-style used by certain mapbox APIs
#     ("lon,lat" pairs separated by ";")
#     """
#     coords = ['{lon},{lat}'.format(
#                   lon=float(round(lon, precision)),
#                   lat=float(round(lat, precision)))
#               for lon, lat in read_points(features)]
# 
#     if min_limit is not None and len(coords) < min_limit:
#         raise InvalidFeatureError(
#             "Not enough features to encode coordinates, "
#             "need at least {0}".format(min_limit))
#     if max_limit is not None and len(coords) > max_limit:
#         raise InvalidFeatureError(
#             "Too many features to encode coordinates, "
#             "need at most {0}".format(max_limit))
# 
#     return ';'.join(coords)
# 
# Path: mapbox/services/base.py
# class Service(object):
#     """Service base class
# 
#     Attributes
#     ----------
#     default_host : str
#         Default service hostname: api.mapbox.com.
#     api_name : str
#         Mapbox API name.
#     api_version : str
#         API version string such as "v1" or "v5".
#     baseuri
#     username
# 
#     Methods
#     -------
#     handle_http_errors(response, custom_messages=None, raise_for_status=False)
#         Converts service errors to Python exceptions.
#     """
# 
#     default_host = 'api.mapbox.com'
#     api_name = 'hors service'
#     api_version = 'v0'
# 
#     def __init__(self, access_token=None, host=None, cache=None):
#         """Constructs a Service object
# 
#         This method should be overridden by subclasses.
# 
#         Parameters
#         ----------
#         access_token : str
#             Mapbox access token string.
#         host : str, optional
#             Mapbox API host (advanced usage only).
#         cache : CacheControl cache instance (Dict or FileCache), optional
#             Optional caching, not generally needed.
# 
#         Returns
#         -------
#         Service
#         """
#         self.session = Session(access_token)
#         self.host = host or os.environ.get('MAPBOX_HOST', self.default_host)
#         if cache:
#             self.session = CacheControl(self.session, cache=cache)
# 
#     @property
#     def baseuri(self):
#         """The service's base URI
# 
#         Returns
#         -------
#         str
#         """
#         return 'https://{0}/{1}/{2}'.format(
#             self.host, self.api_name, self.api_version)
# 
#     @property
#     def username(self):
#         """The username in the service's access token
# 
#         Returns
#         -------
#         str
#         """
#         token = self.session.params.get('access_token')
#         if not token:
#             raise errors.TokenError(
#                 "session does not have a valid access_token param")
#         data = token.split('.')[1]
#         # replace url chars and add padding
#         # (https://gist.github.com/perrygeo/ee7c65bb1541ff6ac770)
#         data = data.replace('-', '+').replace('_', '/') + "==="
#         try:
#             return json.loads(base64.b64decode(data).decode('utf-8'))['u']
#         except (ValueError, KeyError):
#             raise errors.TokenError(
#                 "access_token does not contain username")
# 
#     def handle_http_error(self, response, custom_messages=None,
#                           raise_for_status=False):
#         """Converts service errors to Python exceptions
# 
#         Parameters
#         ----------
#         response : requests.Response
#             A service response.
#         custom_messages : dict, optional
#             A mapping of custom exception messages to HTTP status codes.
#         raise_for_status : bool, optional
#             If True, the requests library provides Python exceptions.
# 
#         Returns
#         -------
#         None
#         """
#         if not custom_messages:
#             custom_messages = {}
#         if response.status_code in custom_messages.keys():
#             raise errors.HTTPError(custom_messages[response.status_code])
#         if raise_for_status:
#             response.raise_for_status()
# 
# Path: mapbox/compat.py

# 
# Path: mapbox/errors.py
# class ValidationError(ValueError):
# class InvalidCountryCodeError(ValidationError):
# class InvalidPlaceTypeError(ValidationError):
# class InvalidProfileError(ValidationError):
# class InvalidFeatureError(ValidationError):
# class HTTPError(ValidationError):
# class InvalidCoordError(ValidationError):
# class InputSizeError(ValidationError):
# class ImageSizeError(ValidationError):
# class TokenError(ValidationError):
# class InvalidParameterError(ValidationError):
# class InvalidFileError(ValidationError):
# class InvalidResourceTypeError(ValidationError):
# class InvalidPeriodError(ValidationError):
# class InvalidUsernameError(ValidationError):
# class InvalidId(ValidationError):
# class MapboxDeprecationWarning(UserWarning):
# class InvalidZoomError(ValidationError):
# class InvalidColumnError(ValidationError):
# class InvalidRowError(ValidationError):
# class InvalidFileFormatError(ValidationError):
# class InvalidFeatureFormatError(ValidationError):
# class InvalidMarkerNameError(ValidationError):
# class InvalidLabelError(ValidationError):
# class InvalidColorError(ValidationError):


import warnings
import polyline
from numbers import Number
from uritemplate import URITemplate
from mapbox.encoding import encode_waypoints as encode_coordinates
from mapbox.services.base import Service
from mapbox.compat import string_type
from mapbox import errors
            have the same length. Elements of the list must be one of:

            - A number (interpretted as a snapping radius)
            - The string 'unlimited' (unlimited snapping radius)
            - A 3-element tuple consisting of (radius, angle, range)
            - None (no snapping parameters specified for that waypoint)
        annotations : str
            Whether or not to return additional metadata along the route

            Possible values are: 'duration', 'distance', 'speed', and
            'congestion'. Several annotations can be used by joining
            them with ','.
        language : str
            Language of returned turn-by-turn text instructions,
            default: 'en'

        Returns
        -------
        requests.Response
            The response object has a geojson() method for access to
            the route(s) as a GeoJSON-like FeatureCollection
            dictionary.
        """
        # backwards compatible, deprecated
        if 'geometry' in kwargs and geometries is None:
            geometries = kwargs['geometry']
            warnings.warn('Use `geometries` instead of `geometry`',
                          errors.MapboxDeprecationWarning)

        annotations = self._validate_annotations(annotations)

# Path: mapbox/encoding.py
# def encode_waypoints(features, min_limit=None, max_limit=None, precision=6):
#     """Given an iterable of features
#     return a string encoded in waypoint-style used by certain mapbox APIs
#     ("lon,lat" pairs separated by ";")
#     """
#     coords = ['{lon},{lat}'.format(
#                   lon=float(round(lon, precision)),
#                   lat=float(round(lat, precision)))
#               for lon, lat in read_points(features)]
# 
#     if min_limit is not None and len(coords) < min_limit:
#         raise InvalidFeatureError(
#             "Not enough features to encode coordinates, "
#             "need at least {0}".format(min_limit))
#     if max_limit is not None and len(coords) > max_limit:
#         raise InvalidFeatureError(
#             "Too many features to encode coordinates, "
#             "need at most {0}".format(max_limit))
# 
#     return ';'.join(coords)
# 
# Path: mapbox/services/base.py
# class Service(object):
#     """Service base class
# 
#     Attributes
#     ----------
#     default_host : str
#         Default service hostname: api.mapbox.com.
#     api_name : str
#         Mapbox API name.
#     api_version : str
#         API version string such as "v1" or "v5".
#     baseuri
#     username
# 
#     Methods
#     -------
#     handle_http_errors(response, custom_messages=None, raise_for_status=False)
#         Converts service errors to Python exceptions.
#     """
# 
#     default_host = 'api.mapbox.com'
#     api_name = 'hors service'
#     api_version = 'v0'
# 
#     def __init__(self, access_token=None, host=None, cache=None):
#         """Constructs a Service object
# 
#         This method should be overridden by subclasses.
# 
#         Parameters
#         ----------
#         access_token : str
#             Mapbox access token string.
#         host : str, optional
#             Mapbox API host (advanced usage only).
#         cache : CacheControl cache instance (Dict or FileCache), optional
#             Optional caching, not generally needed.
# 
#         Returns
#         -------
#         Service
#         """
#         self.session = Session(access_token)
#         self.host = host or os.environ.get('MAPBOX_HOST', self.default_host)
#         if cache:
#             self.session = CacheControl(self.session, cache=cache)
# 
#     @property
#     def baseuri(self):
#         """The service's base URI
# 
#         Returns
#         -------
#         str
#         """
#         return 'https://{0}/{1}/{2}'.format(
#             self.host, self.api_name, self.api_version)
# 
#     @property
#     def username(self):
#         """The username in the service's access token
# 
#         Returns
#         -------
#         str
#         """
#         token = self.session.params.get('access_token')
#         if not token:
#             raise errors.TokenError(
#                 "session does not have a valid access_token param")
#         data = token.split('.')[1]
#         # replace url chars and add padding
#         # (https://gist.github.com/perrygeo/ee7c65bb1541ff6ac770)
#         data = data.replace('-', '+').replace('_', '/') + "==="
#         try:
#             return json.loads(base64.b64decode(data).decode('utf-8'))['u']
#         except (ValueError, KeyError):
#             raise errors.TokenError(
#                 "access_token does not contain username")
# 
#     def handle_http_error(self, response, custom_messages=None,
#                           raise_for_status=False):
#         """Converts service errors to Python exceptions
# 
#         Parameters
#         ----------
#         response : requests.Response
#             A service response.
#         custom_messages : dict, optional
#             A mapping of custom exception messages to HTTP status codes.
#         raise_for_status : bool, optional
#             If True, the requests library provides Python exceptions.
# 
#         Returns
#         -------
#         None
#         """
#         if not custom_messages:
#             custom_messages = {}
#         if response.status_code in custom_messages.keys():
#             raise errors.HTTPError(custom_messages[response.status_code])
#         if raise_for_status:
#             response.raise_for_status()
# 
# Path: mapbox/compat.py

# 
# Path: mapbox/errors.py
# class ValidationError(ValueError):
# class InvalidCountryCodeError(ValidationError):
# class InvalidPlaceTypeError(ValidationError):
# class InvalidProfileError(ValidationError):
# class InvalidFeatureError(ValidationError):
# class HTTPError(ValidationError):
# class InvalidCoordError(ValidationError):
# class InputSizeError(ValidationError):
# class ImageSizeError(ValidationError):
# class TokenError(ValidationError):
# class InvalidParameterError(ValidationError):
# class InvalidFileError(ValidationError):
# class InvalidResourceTypeError(ValidationError):
# class InvalidPeriodError(ValidationError):
# class InvalidUsernameError(ValidationError):
# class InvalidId(ValidationError):
# class MapboxDeprecationWarning(UserWarning):
# class InvalidZoomError(ValidationError):
# class InvalidColumnError(ValidationError):
# class InvalidRowError(ValidationError):
# class InvalidFileFormatError(ValidationError):
# class InvalidFeatureFormatError(ValidationError):
# class InvalidMarkerNameError(ValidationError):
# class InvalidLabelError(ValidationError):
# class InvalidColorError(ValidationError):


# Path: mapbox/services/directions.py
import warnings
import polyline
from numbers import Number
from uritemplate import URITemplate
from mapbox.encoding import encode_waypoints as encode_coordinates
from mapbox.services.base import Service
from mapbox.compat import string_type
from mapbox import errors

            have the same length. Elements of the list must be one of:

            - A number (interpretted as a snapping radius)
            - The string 'unlimited' (unlimited snapping radius)
            - A 3-element tuple consisting of (radius, angle, range)
            - None (no snapping parameters specified for that waypoint)
        annotations : str
            Whether or not to return additional metadata along the route

            Possible values are: 'duration', 'distance', 'speed', and
            'congestion'. Several annotations can be used by joining
            them with ','.
        language : str
            Language of returned turn-by-turn text instructions,
            default: 'en'

        Returns
        -------
        requests.Response
            The response object has a geojson() method for access to
            the route(s) as a GeoJSON-like FeatureCollection
            dictionary.
        """
        # backwards compatible, deprecated
        if 'geometry' in kwargs and geometries is None:
            geometries = kwargs['geometry']
            warnings.warn('Use `geometries` instead of `geometry`',
                          errors.MapboxDeprecationWarning)

        annotations = self._validate_annotations(annotations)

        coordinates = encode_coordinates(