# 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/errors.py
# class InvalidProfileError(ValidationError):
#     pass
# 
# class MapboxDeprecationWarning(UserWarning):
#     pass
# 
# 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()


import re
import warnings
from mapbox.encoding import encode_waypoints
from mapbox.errors import InvalidProfileError, MapboxDeprecationWarning
from mapbox.services.base import Service
        response's json() method. The resulting mapping has a code,
        the destinations and the sources, and depending of the
        annotations specified, it can also contain a durations matrix,
        a distances matrix or both of them (by default, only the
        durations matrix is provided).

        code : str
            Status of the response
        sources : list
            Results of snapping selected coordinates to the nearest
            addresses.
        destinations : list
            Results of snapping selected coordinates to the nearest
            addresses.
        durations : list
            An array of arrays representing the matrix in row-major
            order.  durations[i][j] gives the travel time from the i-th
            source to the j-th destination. All values are in seconds.
            The duration between the same coordinate is always 0. If
            a duration can not be found, the result is null.
        distances : list
            An array of arrays representing the matrix in row-major
            order.  distances[i][j] gives the distance from the i-th
            source to the j-th destination. All values are in meters.
            The distance between the same coordinate is always 0. If
            a distance can not be found, the result is null.

        """
        annotations = self._validate_annotations(annotations)
        profile = self._validate_profile(profile)

# 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/errors.py
# class InvalidProfileError(ValidationError):
#     pass
# 
# class MapboxDeprecationWarning(UserWarning):
#     pass
# 
# 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/services/matrix.py
import re
import warnings
from mapbox.encoding import encode_waypoints
from mapbox.errors import InvalidProfileError, MapboxDeprecationWarning
from mapbox.services.base import Service

        response's json() method. The resulting mapping has a code,
        the destinations and the sources, and depending of the
        annotations specified, it can also contain a durations matrix,
        a distances matrix or both of them (by default, only the
        durations matrix is provided).

        code : str
            Status of the response
        sources : list
            Results of snapping selected coordinates to the nearest
            addresses.
        destinations : list
            Results of snapping selected coordinates to the nearest
            addresses.
        durations : list
            An array of arrays representing the matrix in row-major
            order.  durations[i][j] gives the travel time from the i-th
            source to the j-th destination. All values are in seconds.
            The duration between the same coordinate is always 0. If
            a duration can not be found, the result is null.
        distances : list
            An array of arrays representing the matrix in row-major
            order.  distances[i][j] gives the distance from the i-th
            source to the j-th destination. All values are in meters.
            The distance between the same coordinate is always 0. If
            a distance can not be found, the result is null.

        """
        annotations = self._validate_annotations(annotations)
        profile = self._validate_profile(profile)

        coords = encode_waypoints(coordinates)