# Path: numcodecs/abc.py
# class Codec:
#     """Codec abstract base class."""
# 
#     # override in sub-class
#     codec_id = None
#     """Codec identifier."""
# 
#     @abstractmethod
#     def encode(self, buf):  # pragma: no cover
#         """Encode data in `buf`.
# 
#         Parameters
#         ----------
#         buf : buffer-like
#             Data to be encoded. May be any object supporting the new-style
#             buffer protocol.
# 
#         Returns
#         -------
#         enc : buffer-like
#             Encoded data. May be any object supporting the new-style buffer
#             protocol.
#         """
# 
#     @abstractmethod
#     def decode(self, buf, out=None):  # pragma: no cover
#         """Decode data in `buf`.
# 
#         Parameters
#         ----------
#         buf : buffer-like
#             Encoded data. May be any object supporting the new-style buffer
#             protocol.
#         out : buffer-like, optional
#             Writeable buffer to store decoded data. N.B. if provided, this buffer must
#             be exactly the right size to store the decoded data.
# 
#         Returns
#         -------
#         dec : buffer-like
#             Decoded data. May be any object supporting the new-style
#             buffer protocol.
#         """
# 
#     def get_config(self):
#         """Return a dictionary holding configuration parameters for this
#         codec. Must include an 'id' field with the codec identifier. All
#         values must be compatible with JSON encoding."""
# 
#         # override in sub-class if need special encoding of config values
# 
#         # setup config object
#         config = dict(id=self.codec_id)
# 
#         # by default, assume all non-private members are configuration
#         # parameters - override this in sub-class if not the case
#         for k in self.__dict__:
#             if not k.startswith('_'):
#                 config[k] = getattr(self, k)
# 
#         return config
# 
#     @classmethod
#     def from_config(cls, config):
#         """Instantiate codec from a configuration object."""
#         # N.B., assume at this point the 'id' field has been removed from
#         # the config object
# 
#         # override in sub-class if need special decoding of config values
# 
#         # by default, assume constructor accepts configuration parameters as
#         # keyword arguments without any special decoding
#         return cls(**config)
# 
#     def __eq__(self, other):
#         # override in sub-class if need special equality comparison
#         try:
#             return self.get_config() == other.get_config()
#         except AttributeError:
#             return False
# 
#     def __repr__(self):
# 
#         # override in sub-class if need special representation
# 
#         # by default, assume all non-private members are configuration
#         # parameters and valid keyword arguments to constructor function
# 
#         r = '%s(' % type(self).__name__
#         params = ['{}={!r}'.format(k, getattr(self, k))
#                   for k in sorted(self.__dict__)
#                   if not k.startswith('_')]
#         r += ', '.join(params) + ')'
#         return r
# 
# Path: numcodecs/compat.py
# def ensure_text(s, encoding='utf-8'):
#     if not isinstance(s, str):
#         s = ensure_contiguous_ndarray(s)
#         s = codecs.decode(s, encoding)
#     return s


import json as _json
import textwrap
import numpy as np
from .abc import Codec
from .compat import ensure_text
    codec_id = 'json2'

    def __init__(self, encoding='utf-8', skipkeys=False, ensure_ascii=True,
                 check_circular=True, allow_nan=True, sort_keys=True, indent=None,
                 separators=None, strict=True):
        self._text_encoding = encoding
        if separators is None:
            # ensure separators are explicitly specified, and consistent behaviour across
            # Python versions, and most compact representation if indent is None
            if indent is None:
                separators = ',', ':'
            else:
                separators = ', ', ': '
        separators = tuple(separators)
        self._encoder_config = dict(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
                                    check_circular=check_circular, allow_nan=allow_nan,
                                    indent=indent, separators=separators,
                                    sort_keys=sort_keys)
        self._encoder = _json.JSONEncoder(**self._encoder_config)
        self._decoder_config = dict(strict=strict)
        self._decoder = _json.JSONDecoder(**self._decoder_config)

    def encode(self, buf):
        buf = np.asarray(buf)
        items = buf.tolist()
        items.append(buf.dtype.str)
        items.append(buf.shape)
        return self._encoder.encode(items).encode(self._text_encoding)

    def decode(self, buf, out=None):

# Path: numcodecs/abc.py
# class Codec:
#     """Codec abstract base class."""
# 
#     # override in sub-class
#     codec_id = None
#     """Codec identifier."""
# 
#     @abstractmethod
#     def encode(self, buf):  # pragma: no cover
#         """Encode data in `buf`.
# 
#         Parameters
#         ----------
#         buf : buffer-like
#             Data to be encoded. May be any object supporting the new-style
#             buffer protocol.
# 
#         Returns
#         -------
#         enc : buffer-like
#             Encoded data. May be any object supporting the new-style buffer
#             protocol.
#         """
# 
#     @abstractmethod
#     def decode(self, buf, out=None):  # pragma: no cover
#         """Decode data in `buf`.
# 
#         Parameters
#         ----------
#         buf : buffer-like
#             Encoded data. May be any object supporting the new-style buffer
#             protocol.
#         out : buffer-like, optional
#             Writeable buffer to store decoded data. N.B. if provided, this buffer must
#             be exactly the right size to store the decoded data.
# 
#         Returns
#         -------
#         dec : buffer-like
#             Decoded data. May be any object supporting the new-style
#             buffer protocol.
#         """
# 
#     def get_config(self):
#         """Return a dictionary holding configuration parameters for this
#         codec. Must include an 'id' field with the codec identifier. All
#         values must be compatible with JSON encoding."""
# 
#         # override in sub-class if need special encoding of config values
# 
#         # setup config object
#         config = dict(id=self.codec_id)
# 
#         # by default, assume all non-private members are configuration
#         # parameters - override this in sub-class if not the case
#         for k in self.__dict__:
#             if not k.startswith('_'):
#                 config[k] = getattr(self, k)
# 
#         return config
# 
#     @classmethod
#     def from_config(cls, config):
#         """Instantiate codec from a configuration object."""
#         # N.B., assume at this point the 'id' field has been removed from
#         # the config object
# 
#         # override in sub-class if need special decoding of config values
# 
#         # by default, assume constructor accepts configuration parameters as
#         # keyword arguments without any special decoding
#         return cls(**config)
# 
#     def __eq__(self, other):
#         # override in sub-class if need special equality comparison
#         try:
#             return self.get_config() == other.get_config()
#         except AttributeError:
#             return False
# 
#     def __repr__(self):
# 
#         # override in sub-class if need special representation
# 
#         # by default, assume all non-private members are configuration
#         # parameters and valid keyword arguments to constructor function
# 
#         r = '%s(' % type(self).__name__
#         params = ['{}={!r}'.format(k, getattr(self, k))
#                   for k in sorted(self.__dict__)
#                   if not k.startswith('_')]
#         r += ', '.join(params) + ')'
#         return r
# 
# Path: numcodecs/compat.py
# def ensure_text(s, encoding='utf-8'):
#     if not isinstance(s, str):
#         s = ensure_contiguous_ndarray(s)
#         s = codecs.decode(s, encoding)
#     return s


# Path: numcodecs/json.py
import json as _json
import textwrap
import numpy as np
from .abc import Codec
from .compat import ensure_text

    codec_id = 'json2'

    def __init__(self, encoding='utf-8', skipkeys=False, ensure_ascii=True,
                 check_circular=True, allow_nan=True, sort_keys=True, indent=None,
                 separators=None, strict=True):
        self._text_encoding = encoding
        if separators is None:
            # ensure separators are explicitly specified, and consistent behaviour across
            # Python versions, and most compact representation if indent is None
            if indent is None:
                separators = ',', ':'
            else:
                separators = ', ', ': '
        separators = tuple(separators)
        self._encoder_config = dict(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
                                    check_circular=check_circular, allow_nan=allow_nan,
                                    indent=indent, separators=separators,
                                    sort_keys=sort_keys)
        self._encoder = _json.JSONEncoder(**self._encoder_config)
        self._decoder_config = dict(strict=strict)
        self._decoder = _json.JSONDecoder(**self._decoder_config)

    def encode(self, buf):
        buf = np.asarray(buf)
        items = buf.tolist()
        items.append(buf.dtype.str)
        items.append(buf.shape)
        return self._encoder.encode(items).encode(self._text_encoding)

    def decode(self, buf, out=None):

        items = self._decoder.decode(ensure_text(buf, self._text_encoding))