astroquery-0.2.4/0000755000077000000240000000000012505171566013764 5ustar adamstaff00000000000000astroquery-0.2.4/ah_bootstrap.py0000644000077000000240000006645712464716555017054 0ustar adamstaff00000000000000""" This bootstrap module contains code for ensuring that the astropy_helpers package will be importable by the time the setup.py script runs. It also includes some workarounds to ensure that a recent-enough version of setuptools is being used for the installation. This module should be the first thing imported in the setup.py of distributions that make use of the utilities in astropy_helpers. If the distribution ships with its own copy of astropy_helpers, this module will first attempt to import from the shipped copy. However, it will also check PyPI to see if there are any bug-fix releases on top of the current version that may be useful to get past platform-specific bugs that have been fixed. When running setup.py, use the ``--offline`` command-line option to disable the auto-upgrade checks. When this module is imported or otherwise executed it automatically calls a main function that attempts to read the project's setup.cfg file, which it checks for a configuration section called ``[ah_bootstrap]`` the presences of that section, and options therein, determine the next step taken: If it contains an option called ``auto_use`` with a value of ``True``, it will automatically call the main function of this module called `use_astropy_helpers` (see that function's docstring for full details). Otherwise no further action is taken (however, ``ah_bootstrap.use_astropy_helpers`` may be called manually from within the setup.py script). Additional options in the ``[ah_boostrap]`` section of setup.cfg have the same names as the arguments to `use_astropy_helpers`, and can be used to configure the bootstrap script when ``auto_use = True``. See https://github.com/astropy/astropy-helpers for more details, and for the latest version of this module. """ import contextlib import errno import imp import io import locale import os import re import subprocess as sp import sys try: from ConfigParser import ConfigParser, RawConfigParser except ImportError: from configparser import ConfigParser, RawConfigParser if sys.version_info[0] < 3: _str_types = (str, unicode) _text_type = unicode PY3 = False else: _str_types = (str, bytes) _text_type = str PY3 = True # Some pre-setuptools checks to ensure that either distribute or setuptools >= # 0.7 is used (over pre-distribute setuptools) if it is available on the path; # otherwise the latest setuptools will be downloaded and bootstrapped with # ``ez_setup.py``. This used to be included in a separate file called # setuptools_bootstrap.py; but it was combined into ah_bootstrap.py try: import pkg_resources _setuptools_req = pkg_resources.Requirement.parse('setuptools>=0.7') # This may raise a DistributionNotFound in which case no version of # setuptools or distribute is properly installed _setuptools = pkg_resources.get_distribution('setuptools') if _setuptools not in _setuptools_req: # Older version of setuptools; check if we have distribute; again if # this results in DistributionNotFound we want to give up _distribute = pkg_resources.get_distribution('distribute') if _setuptools != _distribute: # It's possible on some pathological systems to have an old version # of setuptools and distribute on sys.path simultaneously; make # sure distribute is the one that's used sys.path.insert(1, _distribute.location) _distribute.activate() imp.reload(pkg_resources) except: # There are several types of exceptions that can occur here; if all else # fails bootstrap and use the bootstrapped version from ez_setup import use_setuptools use_setuptools() from distutils import log from distutils.debug import DEBUG # In case it didn't successfully import before the ez_setup checks import pkg_resources from setuptools import Distribution from setuptools.package_index import PackageIndex from setuptools.sandbox import run_setup # Note: The following import is required as a workaround to # https://github.com/astropy/astropy-helpers/issues/89; if we don't import this # module now, it will get cleaned up after `run_setup` is called, but that will # later cause the TemporaryDirectory class defined in it to stop working when # used later on by setuptools try: import setuptools.py31compat except ImportError: pass # TODO: Maybe enable checking for a specific version of astropy_helpers? DIST_NAME = 'astropy-helpers' PACKAGE_NAME = 'astropy_helpers' # Defaults for other options DOWNLOAD_IF_NEEDED = True INDEX_URL = 'https://pypi.python.org/simple' USE_GIT = True AUTO_UPGRADE = True def use_astropy_helpers(path=None, download_if_needed=None, index_url=None, use_git=None, auto_upgrade=None): """ Ensure that the `astropy_helpers` module is available and is importable. This supports automatic submodule initialization if astropy_helpers is included in a project as a git submodule, or will download it from PyPI if necessary. Parameters ---------- path : str or None, optional A filesystem path relative to the root of the project's source code that should be added to `sys.path` so that `astropy_helpers` can be imported from that path. If the path is a git submodule it will automatically be initialzed and/or updated. The path may also be to a ``.tar.gz`` archive of the astropy_helpers source distribution. In this case the archive is automatically unpacked and made temporarily available on `sys.path` as a ``.egg`` archive. If `None` skip straight to downloading. download_if_needed : bool, optional If the provided filesystem path is not found an attempt will be made to download astropy_helpers from PyPI. It will then be made temporarily available on `sys.path` as a ``.egg`` archive (using the ``setup_requires`` feature of setuptools. If the ``--offline`` option is given at the command line the value of this argument is overridden to `False`. index_url : str, optional If provided, use a different URL for the Python package index than the main PyPI server. use_git : bool, optional If `False` no git commands will be used--this effectively disables support for git submodules. If the ``--no-git`` option is given at the command line the value of this argument is overridden to `False`. auto_upgrade : bool, optional By default, when installing a package from a non-development source distribution ah_boostrap will try to automatically check for patch releases to astropy-helpers on PyPI and use the patched version over any bundled versions. Setting this to `False` will disable that functionality. If the ``--offline`` option is given at the command line the value of this argument is overridden to `False`. """ # True by default, unless the --offline option was provided on the command # line if '--offline' in sys.argv: download_if_needed = False auto_upgrade = False offline = True sys.argv.remove('--offline') else: offline = False if '--no-git' in sys.argv: use_git = False sys.argv.remove('--no-git') if path is None: path = PACKAGE_NAME if download_if_needed is None: download_if_needed = DOWNLOAD_IF_NEEDED if index_url is None: index_url = INDEX_URL # If this is a release then the .git directory will not exist so we # should not use git. git_dir_exists = os.path.exists(os.path.join(os.path.dirname(__file__), '.git')) if use_git is None and not git_dir_exists: use_git = False if use_git is None: use_git = USE_GIT if auto_upgrade is None: auto_upgrade = AUTO_UPGRADE # Declared as False by default--later we check if astropy-helpers can be # upgraded from PyPI, but only if not using a source distribution (as in # the case of import from a git submodule) is_submodule = False if not isinstance(path, _str_types): if path is not None: raise TypeError('path must be a string or None') if not download_if_needed: log.debug('a path was not given and download from PyPI was not ' 'allowed so this is effectively a no-op') return elif not os.path.exists(path) or os.path.isdir(path): # Even if the given path does not exist on the filesystem, if it *is* a # submodule, `git submodule init` will create it is_submodule = _check_submodule(path, use_git=use_git, offline=offline) if is_submodule or os.path.isdir(path): log.info( 'Attempting to import astropy_helpers from {0} {1!r}'.format( 'submodule' if is_submodule else 'directory', path)) dist = _directory_import(path) else: dist = None if dist is None: msg = ( 'The requested path {0!r} for importing {1} does not ' 'exist, or does not contain a copy of the {1} package. ' 'Attempting download instead.'.format(path, PACKAGE_NAME)) if download_if_needed: log.warn(msg) else: raise _AHBootstrapSystemExit(msg) elif os.path.isfile(path): # Handle importing from a source archive; this also uses setup_requires # but points easy_install directly to the source archive try: dist = _do_download(find_links=[path]) except Exception as e: if download_if_needed: log.warn('{0}\nWill attempt to download astropy_helpers from ' 'PyPI instead.'.format(str(e))) dist = None else: raise _AHBootstrapSystemExit(e.args[0]) else: msg = ('{0!r} is not a valid file or directory (it could be a ' 'symlink?)'.format(path)) if download_if_needed: log.warn(msg) dist = None else: raise _AHBootstrapSystemExit(msg) if dist is not None and auto_upgrade and not is_submodule: # A version of astropy-helpers was found on the available path, but # check to see if a bugfix release is available on PyPI upgrade = _do_upgrade(dist, index_url) if upgrade is not None: dist = upgrade elif dist is None: # Last resort--go ahead and try to download the latest version from # PyPI try: if download_if_needed: log.warn( "Downloading astropy_helpers; run setup.py with the " "--offline option to force offline installation.") dist = _do_download(index_url=index_url) else: raise _AHBootstrapSystemExit( "No source for the astropy_helpers package; " "astropy_helpers must be available as a prerequisite to " "installing this package.") except Exception as e: if DEBUG: raise else: raise _AHBootstrapSystemExit(e.args[0]) if dist is not None: # Otherwise we found a version of astropy-helpers so we're done # Just activate the found distribibution on sys.path--if we did a # download this usually happens automatically but do it again just to # be sure # Note: Adding the dist to the global working set also activates it by # default pkg_resources.working_set.add(dist) def _do_download(version='', find_links=None, index_url=None): try: if find_links: allow_hosts = '' index_url = None else: allow_hosts = None # Annoyingly, setuptools will not handle other arguments to # Distribution (such as options) before handling setup_requires, so it # is not straightfoward to programmatically augment the arguments which # are passed to easy_install class _Distribution(Distribution): def get_option_dict(self, command_name): opts = Distribution.get_option_dict(self, command_name) if command_name == 'easy_install': if find_links is not None: opts['find_links'] = ('setup script', find_links) if index_url is not None: opts['index_url'] = ('setup script', index_url) if allow_hosts is not None: opts['allow_hosts'] = ('setup script', allow_hosts) return opts if version: req = '{0}=={1}'.format(DIST_NAME, version) else: req = DIST_NAME attrs = {'setup_requires': [req]} if DEBUG: dist = _Distribution(attrs=attrs) else: with _silence(): dist = _Distribution(attrs=attrs) # If the setup_requires succeeded it will have added the new dist to # the main working_set return pkg_resources.working_set.by_key.get(DIST_NAME) except Exception as e: if DEBUG: raise msg = 'Error retrieving astropy helpers from {0}:\n{1}' if find_links: source = find_links[0] elif index_url: source = index_url else: source = 'PyPI' raise Exception(msg.format(source, repr(e))) def _do_upgrade(dist, index_url): # Build up a requirement for a higher bugfix release but a lower minor # release (so API compatibility is guaranteed) # sketchy version parsing--maybe come up with something a bit more # robust for this major, minor = (int(part) for part in dist.parsed_version[:2]) next_minor = '.'.join([str(major), str(minor + 1), '0']) req = pkg_resources.Requirement.parse( '{0}>{1},<{2}'.format(DIST_NAME, dist.version, next_minor)) package_index = PackageIndex(index_url=index_url) upgrade = package_index.obtain(req) if upgrade is not None: return _do_download(version=upgrade.version, index_url=index_url) def _directory_import(path): """ Import astropy_helpers from the given path, which will be added to sys.path. Must return True if the import succeeded, and False otherwise. """ # Return True on success, False on failure but download is allowed, and # otherwise raise SystemExit path = os.path.abspath(path) # Use an empty WorkingSet rather than the man pkg_resources.working_set, # since on older versions of setuptools this will invoke a VersionConflict # when trying to install an upgrade ws = pkg_resources.WorkingSet([]) ws.add_entry(path) dist = ws.by_key.get(DIST_NAME) if dist is None: # We didn't find an egg-info/dist-info in the given path, but if a # setup.py exists we can generate it setup_py = os.path.join(path, 'setup.py') if os.path.isfile(setup_py): with _silence(): run_setup(os.path.join(path, 'setup.py'), ['egg_info']) for dist in pkg_resources.find_distributions(path, True): # There should be only one... return dist return dist def _check_submodule(path, use_git=True, offline=False): """ Check if the given path is a git submodule. See the docstrings for ``_check_submodule_using_git`` and ``_check_submodule_no_git`` for futher details. """ if use_git: return _check_submodule_using_git(path, offline) else: return _check_submodule_no_git(path) def _check_submodule_using_git(path, offline): """ Check if the given path is a git submodule. If so, attempt to initialize and/or update the submodule if needed. This function makes calls to the ``git`` command in subprocesses. The ``_check_submodule_no_git`` option uses pure Python to check if the given path looks like a git submodule, but it cannot perform updates. """ if PY3 and not isinstance(path, _text_type): fs_encoding = sys.getfilesystemencoding() path = path.decode(fs_encoding) try: p = sp.Popen(['git', 'submodule', 'status', '--', path], stdout=sp.PIPE, stderr=sp.PIPE) stdout, stderr = p.communicate() except OSError as e: if DEBUG: raise if e.errno == errno.ENOENT: # The git command simply wasn't found; this is most likely the # case on user systems that don't have git and are simply # trying to install the package from PyPI or a source # distribution. Silently ignore this case and simply don't try # to use submodules return False else: raise _AHBoostrapSystemExit( 'An unexpected error occurred when running the ' '`git submodule status` command:\n{0}'.format(str(e))) # Can fail of the default locale is not configured properly. See # https://github.com/astropy/astropy/issues/2749. For the purposes under # consideration 'latin1' is an acceptable fallback. try: stdio_encoding = locale.getdefaultlocale()[1] or 'latin1' except ValueError: # Due to an OSX oddity locale.getdefaultlocale() can also crash # depending on the user's locale/language settings. See: # http://bugs.python.org/issue18378 stdio_encoding = 'latin1' if p.returncode != 0 or stderr: # Unfortunately the return code alone cannot be relied on, as # earlier versions of git returned 0 even if the requested submodule # does not exist stderr = stderr.decode(stdio_encoding) # This is a warning that occurs in perl (from running git submodule) # which only occurs with a malformatted locale setting which can # happen sometimes on OSX. See again # https://github.com/astropy/astropy/issues/2749 perl_warning = ('perl: warning: Falling back to the standard locale ' '("C").') if not stderr.strip().endswith(perl_warning): # Some other uknown error condition occurred log.warn('git submodule command failed ' 'unexpectedly:\n{0}'.format(stderr)) return False stdout = stdout.decode(stdio_encoding) # The stdout should only contain one line--the status of the # requested submodule m = _git_submodule_status_re.match(stdout) if m: # Yes, the path *is* a git submodule _update_submodule(m.group('submodule'), m.group('status'), offline) return True else: log.warn( 'Unexpected output from `git submodule status`:\n{0}\n' 'Will attempt import from {1!r} regardless.'.format( stdout, path)) return False def _check_submodule_no_git(path): """ Like ``_check_submodule_using_git``, but simply parses the .gitmodules file to determine if the supplied path is a git submodule, and does not exec any subprocesses. This can only determine if a path is a submodule--it does not perform updates, etc. This function may need to be updated if the format of the .gitmodules file is changed between git versions. """ gitmodules_path = os.path.abspath('.gitmodules') if not os.path.isfile(gitmodules_path): return False # This is a minimal reader for gitconfig-style files. It handles a few of # the quirks that make gitconfig files incompatible with ConfigParser-style # files, but does not support the full gitconfig syntaix (just enough # needed to read a .gitmodules file). gitmodules_fileobj = io.StringIO() # Must use io.open for cross-Python-compatible behavior wrt unicode with io.open(gitmodules_path) as f: for line in f: # gitconfig files are more flexible with leading whitespace; just # go ahead and remove it line = line.lstrip() # comments can start with either # or ; if line and line[0] in (':', ';'): continue gitmodules_fileobj.write(line) gitmodules_fileobj.seek(0) cfg = RawConfigParser() try: cfg.readfp(gitmodules_fileobj) except Exception as exc: log.warn('Malformatted .gitmodules file: {0}\n' '{1} cannot be assumed to be a git submodule.'.format( exc, path)) return False for section in cfg.sections(): if not cfg.has_option(section, 'path'): continue submodule_path = cfg.get(section, 'path').rstrip(os.sep) if submodule_path == path.rstrip(os.sep): return True return False def _update_submodule(submodule, status, offline): if status == ' ': # The submodule is up to date; no action necessary return elif status == '-': if offline: raise _AHBootstrapSystemExit( "Cannot initialize the {0} submodule in --offline mode; this " "requires being able to clone the submodule from an online " "repository.".format(submodule)) cmd = ['update', '--init'] action = 'Initializing' elif status == '+': cmd = ['update'] action = 'Updating' if offline: cmd.append('--no-fetch') elif status == 'U': raise _AHBoostrapSystemExit( 'Error: Submodule {0} contains unresolved merge conflicts. ' 'Please complete or abandon any changes in the submodule so that ' 'it is in a usable state, then try again.'.format(submodule)) else: log.warn('Unknown status {0!r} for git submodule {1!r}. Will ' 'attempt to use the submodule as-is, but try to ensure ' 'that the submodule is in a clean state and contains no ' 'conflicts or errors.\n{2}'.format(status, submodule, _err_help_msg)) return err_msg = None cmd = ['git', 'submodule'] + cmd + ['--', submodule] log.warn('{0} {1} submodule with: `{2}`'.format( action, submodule, ' '.join(cmd))) try: p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) stdout, stderr = p.communicate() except OSError as e: err_msg = str(e) else: if p.returncode != 0: stderr_encoding = locale.getdefaultlocale()[1] err_msg = stderr.decode(stderr_encoding) if err_msg: log.warn('An unexpected error occurred updating the git submodule ' '{0!r}:\n{1}\n{2}'.format(submodule, err_msg, _err_help_msg)) class _DummyFile(object): """A noop writeable object.""" errors = '' # Required for Python 3.x encoding = 'utf-8' def write(self, s): pass def flush(self): pass @contextlib.contextmanager def _silence(): """A context manager that silences sys.stdout and sys.stderr.""" old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = _DummyFile() sys.stderr = _DummyFile() exception_occurred = False try: yield except: exception_occurred = True # Go ahead and clean up so that exception handling can work normally sys.stdout = old_stdout sys.stderr = old_stderr raise if not exception_occurred: sys.stdout = old_stdout sys.stderr = old_stderr _err_help_msg = """ If the problem persists consider installing astropy_helpers manually using pip (`pip install astropy_helpers`) or by manually downloading the source archive, extracting it, and installing by running `python setup.py install` from the root of the extracted source code. """ class _AHBootstrapSystemExit(SystemExit): def __init__(self, *args): if not args: msg = 'An unknown problem occurred bootstrapping astropy_helpers.' else: msg = args[0] msg += '\n' + _err_help_msg super(_AHBootstrapSystemExit, self).__init__(msg, *args[1:]) if sys.version_info[:2] < (2, 7): # In Python 2.6 the distutils log does not log warnings, errors, etc. to # stderr so we have to wrap it to ensure consistency at least in this # module import distutils class log(object): def __getattr__(self, attr): return getattr(distutils.log, attr) def warn(self, msg, *args): self._log_to_stderr(distutils.log.WARN, msg, *args) def error(self, msg): self._log_to_stderr(distutils.log.ERROR, msg, *args) def fatal(self, msg): self._log_to_stderr(distutils.log.FATAL, msg, *args) def log(self, level, msg, *args): if level in (distutils.log.WARN, distutils.log.ERROR, distutils.log.FATAL): self._log_to_stderr(level, msg, *args) else: distutils.log.log(level, msg, *args) def _log_to_stderr(self, level, msg, *args): # This is the only truly 'public' way to get the current threshold # of the log current_threshold = distutils.log.set_threshold(distutils.log.WARN) distutils.log.set_threshold(current_threshold) if level >= current_threshold: if args: msg = msg % args sys.stderr.write('%s\n' % msg) sys.stderr.flush() log = log() # Output of `git submodule status` is as follows: # # 1: Status indicator: '-' for submodule is uninitialized, '+' if submodule is # initialized but is not at the commit currently indicated in .gitmodules (and # thus needs to be updated), or 'U' if the submodule is in an unstable state # (i.e. has merge conflicts) # # 2. SHA-1 hash of the current commit of the submodule (we don't really need # this information but it's useful for checking that the output is correct) # # 3. The output of `git describe` for the submodule's current commit hash (this # includes for example what branches the commit is on) but only if the # submodule is initialized. We ignore this information for now _git_submodule_status_re = re.compile( '^(?P[+-U ])(?P[0-9a-f]{40}) (?P\S+)( .*)?$') # Implement the auto-use feature; this allows use_astropy_helpers() to be used # at import-time automatically so long as the correct options are specified in # setup.cfg _CFG_OPTIONS = [('auto_use', bool), ('path', str), ('download_if_needed', bool), ('index_url', str), ('use_git', bool), ('auto_upgrade', bool)] def _main(): if not os.path.exists('setup.cfg'): return cfg = ConfigParser() try: cfg.read('setup.cfg') except Exception as e: if DEBUG: raise log.error( "Error reading setup.cfg: {0!r}\nastropy_helpers will not be " "automatically bootstrapped and package installation may fail." "\n{1}".format(e, _err_help_msg)) return if not cfg.has_section('ah_bootstrap'): return kwargs = {} for option, type_ in _CFG_OPTIONS: if not cfg.has_option('ah_bootstrap', option): continue if type_ is bool: value = cfg.getboolean('ah_bootstrap', option) else: value = cfg.get('ah_bootstrap', option) kwargs[option] = value if kwargs.pop('auto_use', False): use_astropy_helpers(**kwargs) _main() astroquery-0.2.4/astropy_helpers/0000755000077000000240000000000012505171566017207 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/.coveragerc0000644000077000000240000000063312354456432021332 0ustar adamstaff00000000000000[run] source = astropy_helpers ah_bootstrap omit = astropy_helpers/tests* [report] exclude_lines = # Have to re-enable the standard pragma pragma: no cover # Don't complain about packages we have installed except ImportError # Don't complain if tests don't hit assertions raise AssertionError raise NotImplementedError # Don't complain about script hooks def main\(.*\): astroquery-0.2.4/astropy_helpers/.travis.yml0000644000077000000240000000153612464715714021330 0ustar adamstaff00000000000000language: python python: - 2.6 - 2.7 - 3.2 - 3.3 - 3.4 before_install: # Use utf8 encoding. Should be default, but this is insurance against # future changes - export PYTHONIOENCODING=UTF8 # Install conda - wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh - chmod +x miniconda.sh - ./miniconda.sh -b - export PATH=/home/travis/miniconda/bin:$PATH - conda update --yes conda install: - conda install --yes pip "pytest<2.6" sphinx cython numpy - pip install coveralls pytest-cov before_script: # Some of the tests use git commands that require a user to be configured - git config --global user.name "A U Thor" - git config --global user.email "author@example.com" script: - py.test --cov astropy_helpers after_success: - coveralls astroquery-0.2.4/astropy_helpers/ah_bootstrap.py0000644000077000000240000006645712464715714022273 0ustar adamstaff00000000000000""" This bootstrap module contains code for ensuring that the astropy_helpers package will be importable by the time the setup.py script runs. It also includes some workarounds to ensure that a recent-enough version of setuptools is being used for the installation. This module should be the first thing imported in the setup.py of distributions that make use of the utilities in astropy_helpers. If the distribution ships with its own copy of astropy_helpers, this module will first attempt to import from the shipped copy. However, it will also check PyPI to see if there are any bug-fix releases on top of the current version that may be useful to get past platform-specific bugs that have been fixed. When running setup.py, use the ``--offline`` command-line option to disable the auto-upgrade checks. When this module is imported or otherwise executed it automatically calls a main function that attempts to read the project's setup.cfg file, which it checks for a configuration section called ``[ah_bootstrap]`` the presences of that section, and options therein, determine the next step taken: If it contains an option called ``auto_use`` with a value of ``True``, it will automatically call the main function of this module called `use_astropy_helpers` (see that function's docstring for full details). Otherwise no further action is taken (however, ``ah_bootstrap.use_astropy_helpers`` may be called manually from within the setup.py script). Additional options in the ``[ah_boostrap]`` section of setup.cfg have the same names as the arguments to `use_astropy_helpers`, and can be used to configure the bootstrap script when ``auto_use = True``. See https://github.com/astropy/astropy-helpers for more details, and for the latest version of this module. """ import contextlib import errno import imp import io import locale import os import re import subprocess as sp import sys try: from ConfigParser import ConfigParser, RawConfigParser except ImportError: from configparser import ConfigParser, RawConfigParser if sys.version_info[0] < 3: _str_types = (str, unicode) _text_type = unicode PY3 = False else: _str_types = (str, bytes) _text_type = str PY3 = True # Some pre-setuptools checks to ensure that either distribute or setuptools >= # 0.7 is used (over pre-distribute setuptools) if it is available on the path; # otherwise the latest setuptools will be downloaded and bootstrapped with # ``ez_setup.py``. This used to be included in a separate file called # setuptools_bootstrap.py; but it was combined into ah_bootstrap.py try: import pkg_resources _setuptools_req = pkg_resources.Requirement.parse('setuptools>=0.7') # This may raise a DistributionNotFound in which case no version of # setuptools or distribute is properly installed _setuptools = pkg_resources.get_distribution('setuptools') if _setuptools not in _setuptools_req: # Older version of setuptools; check if we have distribute; again if # this results in DistributionNotFound we want to give up _distribute = pkg_resources.get_distribution('distribute') if _setuptools != _distribute: # It's possible on some pathological systems to have an old version # of setuptools and distribute on sys.path simultaneously; make # sure distribute is the one that's used sys.path.insert(1, _distribute.location) _distribute.activate() imp.reload(pkg_resources) except: # There are several types of exceptions that can occur here; if all else # fails bootstrap and use the bootstrapped version from ez_setup import use_setuptools use_setuptools() from distutils import log from distutils.debug import DEBUG # In case it didn't successfully import before the ez_setup checks import pkg_resources from setuptools import Distribution from setuptools.package_index import PackageIndex from setuptools.sandbox import run_setup # Note: The following import is required as a workaround to # https://github.com/astropy/astropy-helpers/issues/89; if we don't import this # module now, it will get cleaned up after `run_setup` is called, but that will # later cause the TemporaryDirectory class defined in it to stop working when # used later on by setuptools try: import setuptools.py31compat except ImportError: pass # TODO: Maybe enable checking for a specific version of astropy_helpers? DIST_NAME = 'astropy-helpers' PACKAGE_NAME = 'astropy_helpers' # Defaults for other options DOWNLOAD_IF_NEEDED = True INDEX_URL = 'https://pypi.python.org/simple' USE_GIT = True AUTO_UPGRADE = True def use_astropy_helpers(path=None, download_if_needed=None, index_url=None, use_git=None, auto_upgrade=None): """ Ensure that the `astropy_helpers` module is available and is importable. This supports automatic submodule initialization if astropy_helpers is included in a project as a git submodule, or will download it from PyPI if necessary. Parameters ---------- path : str or None, optional A filesystem path relative to the root of the project's source code that should be added to `sys.path` so that `astropy_helpers` can be imported from that path. If the path is a git submodule it will automatically be initialzed and/or updated. The path may also be to a ``.tar.gz`` archive of the astropy_helpers source distribution. In this case the archive is automatically unpacked and made temporarily available on `sys.path` as a ``.egg`` archive. If `None` skip straight to downloading. download_if_needed : bool, optional If the provided filesystem path is not found an attempt will be made to download astropy_helpers from PyPI. It will then be made temporarily available on `sys.path` as a ``.egg`` archive (using the ``setup_requires`` feature of setuptools. If the ``--offline`` option is given at the command line the value of this argument is overridden to `False`. index_url : str, optional If provided, use a different URL for the Python package index than the main PyPI server. use_git : bool, optional If `False` no git commands will be used--this effectively disables support for git submodules. If the ``--no-git`` option is given at the command line the value of this argument is overridden to `False`. auto_upgrade : bool, optional By default, when installing a package from a non-development source distribution ah_boostrap will try to automatically check for patch releases to astropy-helpers on PyPI and use the patched version over any bundled versions. Setting this to `False` will disable that functionality. If the ``--offline`` option is given at the command line the value of this argument is overridden to `False`. """ # True by default, unless the --offline option was provided on the command # line if '--offline' in sys.argv: download_if_needed = False auto_upgrade = False offline = True sys.argv.remove('--offline') else: offline = False if '--no-git' in sys.argv: use_git = False sys.argv.remove('--no-git') if path is None: path = PACKAGE_NAME if download_if_needed is None: download_if_needed = DOWNLOAD_IF_NEEDED if index_url is None: index_url = INDEX_URL # If this is a release then the .git directory will not exist so we # should not use git. git_dir_exists = os.path.exists(os.path.join(os.path.dirname(__file__), '.git')) if use_git is None and not git_dir_exists: use_git = False if use_git is None: use_git = USE_GIT if auto_upgrade is None: auto_upgrade = AUTO_UPGRADE # Declared as False by default--later we check if astropy-helpers can be # upgraded from PyPI, but only if not using a source distribution (as in # the case of import from a git submodule) is_submodule = False if not isinstance(path, _str_types): if path is not None: raise TypeError('path must be a string or None') if not download_if_needed: log.debug('a path was not given and download from PyPI was not ' 'allowed so this is effectively a no-op') return elif not os.path.exists(path) or os.path.isdir(path): # Even if the given path does not exist on the filesystem, if it *is* a # submodule, `git submodule init` will create it is_submodule = _check_submodule(path, use_git=use_git, offline=offline) if is_submodule or os.path.isdir(path): log.info( 'Attempting to import astropy_helpers from {0} {1!r}'.format( 'submodule' if is_submodule else 'directory', path)) dist = _directory_import(path) else: dist = None if dist is None: msg = ( 'The requested path {0!r} for importing {1} does not ' 'exist, or does not contain a copy of the {1} package. ' 'Attempting download instead.'.format(path, PACKAGE_NAME)) if download_if_needed: log.warn(msg) else: raise _AHBootstrapSystemExit(msg) elif os.path.isfile(path): # Handle importing from a source archive; this also uses setup_requires # but points easy_install directly to the source archive try: dist = _do_download(find_links=[path]) except Exception as e: if download_if_needed: log.warn('{0}\nWill attempt to download astropy_helpers from ' 'PyPI instead.'.format(str(e))) dist = None else: raise _AHBootstrapSystemExit(e.args[0]) else: msg = ('{0!r} is not a valid file or directory (it could be a ' 'symlink?)'.format(path)) if download_if_needed: log.warn(msg) dist = None else: raise _AHBootstrapSystemExit(msg) if dist is not None and auto_upgrade and not is_submodule: # A version of astropy-helpers was found on the available path, but # check to see if a bugfix release is available on PyPI upgrade = _do_upgrade(dist, index_url) if upgrade is not None: dist = upgrade elif dist is None: # Last resort--go ahead and try to download the latest version from # PyPI try: if download_if_needed: log.warn( "Downloading astropy_helpers; run setup.py with the " "--offline option to force offline installation.") dist = _do_download(index_url=index_url) else: raise _AHBootstrapSystemExit( "No source for the astropy_helpers package; " "astropy_helpers must be available as a prerequisite to " "installing this package.") except Exception as e: if DEBUG: raise else: raise _AHBootstrapSystemExit(e.args[0]) if dist is not None: # Otherwise we found a version of astropy-helpers so we're done # Just activate the found distribibution on sys.path--if we did a # download this usually happens automatically but do it again just to # be sure # Note: Adding the dist to the global working set also activates it by # default pkg_resources.working_set.add(dist) def _do_download(version='', find_links=None, index_url=None): try: if find_links: allow_hosts = '' index_url = None else: allow_hosts = None # Annoyingly, setuptools will not handle other arguments to # Distribution (such as options) before handling setup_requires, so it # is not straightfoward to programmatically augment the arguments which # are passed to easy_install class _Distribution(Distribution): def get_option_dict(self, command_name): opts = Distribution.get_option_dict(self, command_name) if command_name == 'easy_install': if find_links is not None: opts['find_links'] = ('setup script', find_links) if index_url is not None: opts['index_url'] = ('setup script', index_url) if allow_hosts is not None: opts['allow_hosts'] = ('setup script', allow_hosts) return opts if version: req = '{0}=={1}'.format(DIST_NAME, version) else: req = DIST_NAME attrs = {'setup_requires': [req]} if DEBUG: dist = _Distribution(attrs=attrs) else: with _silence(): dist = _Distribution(attrs=attrs) # If the setup_requires succeeded it will have added the new dist to # the main working_set return pkg_resources.working_set.by_key.get(DIST_NAME) except Exception as e: if DEBUG: raise msg = 'Error retrieving astropy helpers from {0}:\n{1}' if find_links: source = find_links[0] elif index_url: source = index_url else: source = 'PyPI' raise Exception(msg.format(source, repr(e))) def _do_upgrade(dist, index_url): # Build up a requirement for a higher bugfix release but a lower minor # release (so API compatibility is guaranteed) # sketchy version parsing--maybe come up with something a bit more # robust for this major, minor = (int(part) for part in dist.parsed_version[:2]) next_minor = '.'.join([str(major), str(minor + 1), '0']) req = pkg_resources.Requirement.parse( '{0}>{1},<{2}'.format(DIST_NAME, dist.version, next_minor)) package_index = PackageIndex(index_url=index_url) upgrade = package_index.obtain(req) if upgrade is not None: return _do_download(version=upgrade.version, index_url=index_url) def _directory_import(path): """ Import astropy_helpers from the given path, which will be added to sys.path. Must return True if the import succeeded, and False otherwise. """ # Return True on success, False on failure but download is allowed, and # otherwise raise SystemExit path = os.path.abspath(path) # Use an empty WorkingSet rather than the man pkg_resources.working_set, # since on older versions of setuptools this will invoke a VersionConflict # when trying to install an upgrade ws = pkg_resources.WorkingSet([]) ws.add_entry(path) dist = ws.by_key.get(DIST_NAME) if dist is None: # We didn't find an egg-info/dist-info in the given path, but if a # setup.py exists we can generate it setup_py = os.path.join(path, 'setup.py') if os.path.isfile(setup_py): with _silence(): run_setup(os.path.join(path, 'setup.py'), ['egg_info']) for dist in pkg_resources.find_distributions(path, True): # There should be only one... return dist return dist def _check_submodule(path, use_git=True, offline=False): """ Check if the given path is a git submodule. See the docstrings for ``_check_submodule_using_git`` and ``_check_submodule_no_git`` for futher details. """ if use_git: return _check_submodule_using_git(path, offline) else: return _check_submodule_no_git(path) def _check_submodule_using_git(path, offline): """ Check if the given path is a git submodule. If so, attempt to initialize and/or update the submodule if needed. This function makes calls to the ``git`` command in subprocesses. The ``_check_submodule_no_git`` option uses pure Python to check if the given path looks like a git submodule, but it cannot perform updates. """ if PY3 and not isinstance(path, _text_type): fs_encoding = sys.getfilesystemencoding() path = path.decode(fs_encoding) try: p = sp.Popen(['git', 'submodule', 'status', '--', path], stdout=sp.PIPE, stderr=sp.PIPE) stdout, stderr = p.communicate() except OSError as e: if DEBUG: raise if e.errno == errno.ENOENT: # The git command simply wasn't found; this is most likely the # case on user systems that don't have git and are simply # trying to install the package from PyPI or a source # distribution. Silently ignore this case and simply don't try # to use submodules return False else: raise _AHBoostrapSystemExit( 'An unexpected error occurred when running the ' '`git submodule status` command:\n{0}'.format(str(e))) # Can fail of the default locale is not configured properly. See # https://github.com/astropy/astropy/issues/2749. For the purposes under # consideration 'latin1' is an acceptable fallback. try: stdio_encoding = locale.getdefaultlocale()[1] or 'latin1' except ValueError: # Due to an OSX oddity locale.getdefaultlocale() can also crash # depending on the user's locale/language settings. See: # http://bugs.python.org/issue18378 stdio_encoding = 'latin1' if p.returncode != 0 or stderr: # Unfortunately the return code alone cannot be relied on, as # earlier versions of git returned 0 even if the requested submodule # does not exist stderr = stderr.decode(stdio_encoding) # This is a warning that occurs in perl (from running git submodule) # which only occurs with a malformatted locale setting which can # happen sometimes on OSX. See again # https://github.com/astropy/astropy/issues/2749 perl_warning = ('perl: warning: Falling back to the standard locale ' '("C").') if not stderr.strip().endswith(perl_warning): # Some other uknown error condition occurred log.warn('git submodule command failed ' 'unexpectedly:\n{0}'.format(stderr)) return False stdout = stdout.decode(stdio_encoding) # The stdout should only contain one line--the status of the # requested submodule m = _git_submodule_status_re.match(stdout) if m: # Yes, the path *is* a git submodule _update_submodule(m.group('submodule'), m.group('status'), offline) return True else: log.warn( 'Unexpected output from `git submodule status`:\n{0}\n' 'Will attempt import from {1!r} regardless.'.format( stdout, path)) return False def _check_submodule_no_git(path): """ Like ``_check_submodule_using_git``, but simply parses the .gitmodules file to determine if the supplied path is a git submodule, and does not exec any subprocesses. This can only determine if a path is a submodule--it does not perform updates, etc. This function may need to be updated if the format of the .gitmodules file is changed between git versions. """ gitmodules_path = os.path.abspath('.gitmodules') if not os.path.isfile(gitmodules_path): return False # This is a minimal reader for gitconfig-style files. It handles a few of # the quirks that make gitconfig files incompatible with ConfigParser-style # files, but does not support the full gitconfig syntaix (just enough # needed to read a .gitmodules file). gitmodules_fileobj = io.StringIO() # Must use io.open for cross-Python-compatible behavior wrt unicode with io.open(gitmodules_path) as f: for line in f: # gitconfig files are more flexible with leading whitespace; just # go ahead and remove it line = line.lstrip() # comments can start with either # or ; if line and line[0] in (':', ';'): continue gitmodules_fileobj.write(line) gitmodules_fileobj.seek(0) cfg = RawConfigParser() try: cfg.readfp(gitmodules_fileobj) except Exception as exc: log.warn('Malformatted .gitmodules file: {0}\n' '{1} cannot be assumed to be a git submodule.'.format( exc, path)) return False for section in cfg.sections(): if not cfg.has_option(section, 'path'): continue submodule_path = cfg.get(section, 'path').rstrip(os.sep) if submodule_path == path.rstrip(os.sep): return True return False def _update_submodule(submodule, status, offline): if status == ' ': # The submodule is up to date; no action necessary return elif status == '-': if offline: raise _AHBootstrapSystemExit( "Cannot initialize the {0} submodule in --offline mode; this " "requires being able to clone the submodule from an online " "repository.".format(submodule)) cmd = ['update', '--init'] action = 'Initializing' elif status == '+': cmd = ['update'] action = 'Updating' if offline: cmd.append('--no-fetch') elif status == 'U': raise _AHBoostrapSystemExit( 'Error: Submodule {0} contains unresolved merge conflicts. ' 'Please complete or abandon any changes in the submodule so that ' 'it is in a usable state, then try again.'.format(submodule)) else: log.warn('Unknown status {0!r} for git submodule {1!r}. Will ' 'attempt to use the submodule as-is, but try to ensure ' 'that the submodule is in a clean state and contains no ' 'conflicts or errors.\n{2}'.format(status, submodule, _err_help_msg)) return err_msg = None cmd = ['git', 'submodule'] + cmd + ['--', submodule] log.warn('{0} {1} submodule with: `{2}`'.format( action, submodule, ' '.join(cmd))) try: p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) stdout, stderr = p.communicate() except OSError as e: err_msg = str(e) else: if p.returncode != 0: stderr_encoding = locale.getdefaultlocale()[1] err_msg = stderr.decode(stderr_encoding) if err_msg: log.warn('An unexpected error occurred updating the git submodule ' '{0!r}:\n{1}\n{2}'.format(submodule, err_msg, _err_help_msg)) class _DummyFile(object): """A noop writeable object.""" errors = '' # Required for Python 3.x encoding = 'utf-8' def write(self, s): pass def flush(self): pass @contextlib.contextmanager def _silence(): """A context manager that silences sys.stdout and sys.stderr.""" old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = _DummyFile() sys.stderr = _DummyFile() exception_occurred = False try: yield except: exception_occurred = True # Go ahead and clean up so that exception handling can work normally sys.stdout = old_stdout sys.stderr = old_stderr raise if not exception_occurred: sys.stdout = old_stdout sys.stderr = old_stderr _err_help_msg = """ If the problem persists consider installing astropy_helpers manually using pip (`pip install astropy_helpers`) or by manually downloading the source archive, extracting it, and installing by running `python setup.py install` from the root of the extracted source code. """ class _AHBootstrapSystemExit(SystemExit): def __init__(self, *args): if not args: msg = 'An unknown problem occurred bootstrapping astropy_helpers.' else: msg = args[0] msg += '\n' + _err_help_msg super(_AHBootstrapSystemExit, self).__init__(msg, *args[1:]) if sys.version_info[:2] < (2, 7): # In Python 2.6 the distutils log does not log warnings, errors, etc. to # stderr so we have to wrap it to ensure consistency at least in this # module import distutils class log(object): def __getattr__(self, attr): return getattr(distutils.log, attr) def warn(self, msg, *args): self._log_to_stderr(distutils.log.WARN, msg, *args) def error(self, msg): self._log_to_stderr(distutils.log.ERROR, msg, *args) def fatal(self, msg): self._log_to_stderr(distutils.log.FATAL, msg, *args) def log(self, level, msg, *args): if level in (distutils.log.WARN, distutils.log.ERROR, distutils.log.FATAL): self._log_to_stderr(level, msg, *args) else: distutils.log.log(level, msg, *args) def _log_to_stderr(self, level, msg, *args): # This is the only truly 'public' way to get the current threshold # of the log current_threshold = distutils.log.set_threshold(distutils.log.WARN) distutils.log.set_threshold(current_threshold) if level >= current_threshold: if args: msg = msg % args sys.stderr.write('%s\n' % msg) sys.stderr.flush() log = log() # Output of `git submodule status` is as follows: # # 1: Status indicator: '-' for submodule is uninitialized, '+' if submodule is # initialized but is not at the commit currently indicated in .gitmodules (and # thus needs to be updated), or 'U' if the submodule is in an unstable state # (i.e. has merge conflicts) # # 2. SHA-1 hash of the current commit of the submodule (we don't really need # this information but it's useful for checking that the output is correct) # # 3. The output of `git describe` for the submodule's current commit hash (this # includes for example what branches the commit is on) but only if the # submodule is initialized. We ignore this information for now _git_submodule_status_re = re.compile( '^(?P[+-U ])(?P[0-9a-f]{40}) (?P\S+)( .*)?$') # Implement the auto-use feature; this allows use_astropy_helpers() to be used # at import-time automatically so long as the correct options are specified in # setup.cfg _CFG_OPTIONS = [('auto_use', bool), ('path', str), ('download_if_needed', bool), ('index_url', str), ('use_git', bool), ('auto_upgrade', bool)] def _main(): if not os.path.exists('setup.cfg'): return cfg = ConfigParser() try: cfg.read('setup.cfg') except Exception as e: if DEBUG: raise log.error( "Error reading setup.cfg: {0!r}\nastropy_helpers will not be " "automatically bootstrapped and package installation may fail." "\n{1}".format(e, _err_help_msg)) return if not cfg.has_section('ah_bootstrap'): return kwargs = {} for option, type_ in _CFG_OPTIONS: if not cfg.has_option('ah_bootstrap', option): continue if type_ is bool: value = cfg.getboolean('ah_bootstrap', option) else: value = cfg.get('ah_bootstrap', option) kwargs[option] = value if kwargs.pop('auto_use', False): use_astropy_helpers(**kwargs) _main() astroquery-0.2.4/astropy_helpers/astropy_helpers/0000755000077000000240000000000012505171566022432 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/__init__.py0000644000077000000240000000024312425434461024537 0ustar adamstaff00000000000000try: from .version import version as __version__ from .version import githash as __githash__ except ImportError: __version__ = '' __githash__ = '' astroquery-0.2.4/astropy_helpers/astropy_helpers/compat/0000755000077000000240000000000012505171566023715 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/compat/__init__.py0000644000077000000240000000056012354456432026027 0ustar adamstaff00000000000000def _fix_user_options(options): """ This is for Python 2.x and 3.x compatibility. distutils expects Command options to all be byte strings on Python 2 and Unicode strings on Python 3. """ def to_str_or_none(x): if x is None: return None return str(x) return [tuple(to_str_or_none(x) for x in y) for y in options] astroquery-0.2.4/astropy_helpers/astropy_helpers/compat/_subprocess_py2/0000755000077000000240000000000012505171566027036 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/compat/_subprocess_py2/__init__.py0000644000077000000240000000243212354456432031150 0ustar adamstaff00000000000000from __future__ import absolute_import from subprocess import * def check_output(*popenargs, **kwargs): r"""Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example:: >>> check_output(["ls", "-l", "/dev/null"]) 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT.:: >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) 'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') process = Popen(stdout=PIPE, *popenargs, **kwargs) output, unused_err = process.communicate() retcode = process.poll() if retcode: cmd = kwargs.get("args") if cmd is None: cmd = popenargs[0] raise CalledProcessError(retcode, cmd) return output astroquery-0.2.4/astropy_helpers/astropy_helpers/compat/subprocess.py0000644000077000000240000000105012354456432026453 0ustar adamstaff00000000000000""" A replacement wrapper around the subprocess module that adds check_output (which was only added to Python in 2.7. Instead of importing subprocess, other modules should use this as follows:: from astropy.utils.compat import subprocess This module is safe to import from anywhere within astropy. """ from __future__ import absolute_import, print_function import subprocess # python2.7 and later provide a check_output method if not hasattr(subprocess, 'check_output'): from ._subprocess_py2 import check_output from subprocess import * astroquery-0.2.4/astropy_helpers/astropy_helpers/git_helpers.py0000644000077000000240000001172512464715714025322 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Utilities for retrieving revision information from a project's git repository. """ # Do not remove the following comment; it is used by # astropy_helpers.version_helpers to determine the beginning of the code in # this module # BEGIN import locale import os import subprocess import warnings def _decode_stdio(stream): try: stdio_encoding = locale.getdefaultlocale()[1] or 'utf-8' except ValueError: stdio_encoding = 'utf-8' try: text = stream.decode(stdio_encoding) except UnicodeDecodeError: # Final fallback text = stream.decode('latin1') return text def update_git_devstr(version, path=None): """ Updates the git revision string if and only if the path is being imported directly from a git working copy. This ensures that the revision number in the version string is accurate. """ try: # Quick way to determine if we're in git or not - returns '' if not devstr = get_git_devstr(sha=True, show_warning=False, path=path) except OSError: return version if not devstr: # Probably not in git so just pass silently return version if 'dev' in version: # update to the current git revision version_base = version.split('.dev', 1)[0] devstr = get_git_devstr(sha=False, show_warning=False, path=path) return version_base + '.dev' + devstr else: #otherwise it's already the true/release version return version def get_git_devstr(sha=False, show_warning=True, path=None): """ Determines the number of revisions in this repository. Parameters ---------- sha : bool If True, the full SHA1 hash will be returned. Otherwise, the total count of commits in the repository will be used as a "revision number". show_warning : bool If True, issue a warning if git returns an error code, otherwise errors pass silently. path : str or None If a string, specifies the directory to look in to find the git repository. If `None`, the current working directory is used. If given a filename it uses the directory containing that file. Returns ------- devversion : str Either a string with the revsion number (if `sha` is False), the SHA1 hash of the current commit (if `sha` is True), or an empty string if git version info could not be identified. """ if path is None: path = os.getcwd() if not os.path.isdir(path): path = os.path.abspath(os.path.dirname(path)) if not os.path.exists(os.path.join(path, '.git')): return '' if sha: # Faster for getting just the hash of HEAD cmd = ['rev-parse', 'HEAD'] else: cmd = ['rev-list', '--count', 'HEAD'] def run_git(cmd): try: p = subprocess.Popen(['git'] + cmd, cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate() except OSError as e: if show_warning: warnings.warn('Error running git: ' + str(e)) return (None, '', '') if p.returncode == 128: if show_warning: warnings.warn('No git repository present at {0!r}! Using ' 'default dev version.'.format(path)) return (p.returncode, '', '') if p.returncode == 129: if show_warning: warnings.warn('Your git looks old (does it support {0}?); ' 'consider upgrading to v1.7.2 or ' 'later.'.format(cmd[0])) return (p.returncode, stdout, stderr) elif p.returncode != 0: if show_warning: warnings.warn('Git failed while determining revision ' 'count: {0}'.format(_decode_stdio(stderr))) return (p.returncode, stdout, stderr) return p.returncode, stdout, stderr returncode, stdout, stderr = run_git(cmd) if not sha and returncode == 129: # git returns 129 if a command option failed to parse; in # particualr this could happen in git versions older than 1.7.2 # where the --count option is not supported # Also use --abbrev-commit and --abbrev=0 to display the minimum # number of characters needed per-commit (rather than the full hash) cmd = ['rev-list', '--abbrev-commit', '--abbrev=0', 'HEAD'] returncode, stdout, stderr = run_git(cmd) # Fall back on the old method of getting all revisions and counting # the lines if returncode == 0: return str(stdout.count(b'\n')) else: return '' elif sha: return _decode_stdio(stdout)[:40] else: return _decode_stdio(stdout).strip() astroquery-0.2.4/astropy_helpers/astropy_helpers/setup_helpers.py0000644000077000000240000015662612464715714025711 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module contains a number of utilities for use during setup/build/packaging that are useful to astropy as a whole. """ from __future__ import absolute_import, print_function import collections import errno import imp import inspect import os import pkgutil import re import shlex import shutil import subprocess import sys import textwrap from distutils import log, ccompiler, sysconfig from distutils.cmd import DistutilsOptionError from distutils.dist import Distribution from distutils.errors import DistutilsError, DistutilsFileError from distutils.core import Extension from distutils.core import Command from distutils.command.sdist import sdist as DistutilsSdist from setuptools.command.build_ext import build_ext as SetuptoolsBuildExt from setuptools.command.build_py import build_py as SetuptoolsBuildPy from setuptools.command.install import install as SetuptoolsInstall from setuptools.command.install_lib import install_lib as SetuptoolsInstallLib from setuptools.command.register import register as SetuptoolsRegister from setuptools import find_packages from .test_helpers import AstropyTest from .utils import silence, invalidate_caches, walk_skip_hidden _module_state = { 'adjusted_compiler': False, 'registered_commands': None, 'have_cython': False, 'have_sphinx': False } try: import Cython _module_state['have_cython'] = True except ImportError: pass try: import sphinx from sphinx.setup_command import BuildDoc as SphinxBuildDoc _module_state['have_sphinx'] = True except ValueError as e: # This can occur deep in the bowels of Sphinx's imports by way of docutils # and an occurence of this bug: http://bugs.python.org/issue18378 # In this case sphinx is effectively unusable if 'unknown locale' in e.args[0]: log.warn( "Possible misconfiguration of one of the environment variables " "LC_ALL, LC_CTYPES, LANG, or LANGUAGE. For an example of how to " "configure your system's language environment on OSX see " "http://blog.remibergsma.com/2012/07/10/" "setting-locales-correctly-on-mac-osx-terminal-application/") except ImportError: pass except SyntaxError: # occurs if markupsafe is recent version, which doesn't support Python 3.2 pass PY3 = sys.version_info[0] >= 3 # This adds a new keyword to the setup() function Distribution.skip_2to3 = [] def adjust_compiler(package): """ This function detects broken compilers and switches to another. If the environment variable CC is explicitly set, or a compiler is specified on the commandline, no override is performed -- the purpose here is to only override a default compiler. The specific compilers with problems are: * The default compiler in XCode-4.2, llvm-gcc-4.2, segfaults when compiling wcslib. The set of broken compilers can be updated by changing the compiler_mapping variable. It is a list of 2-tuples where the first in the pair is a regular expression matching the version of the broken compiler, and the second is the compiler to change to. """ compiler_mapping = [ (b'i686-apple-darwin[0-9]*-llvm-gcc-4.2', 'clang') ] if _module_state['adjusted_compiler']: return # Whatever the result of this function is, it only needs to be run once _module_state['adjusted_compiler'] = True if 'CC' in os.environ: # Check that CC is not set to llvm-gcc-4.2 c_compiler = os.environ['CC'] try: version = get_compiler_version(c_compiler) except OSError: msg = textwrap.dedent( """ The C compiler set by the CC environment variable: {compiler:s} cannot be found or executed. """.format(compiler=c_compiler)) log.warn(msg) sys.exit(1) for broken, fixed in compiler_mapping: if re.match(broken, version): msg = textwrap.dedent( """Compiler specified by CC environment variable ({compiler:s}:{version:s}) will fail to compile {pkg:s}. Please set CC={fixed:s} and try again. You can do this, for example, by running: CC={fixed:s} python setup.py where is the command you ran. """.format(compiler=c_compiler, version=version, pkg=package, fixed=fixed)) log.warn(msg) sys.exit(1) # If C compiler is set via CC, and isn't broken, we are good to go. We # should definitely not try accessing the compiler specified by # ``sysconfig.get_config_var('CC')`` lower down, because this may fail # if the compiler used to compile Python is missing (and maybe this is # why the user is setting CC). For example, the official Python 2.7.3 # MacOS X binary was compled with gcc-4.2, which is no longer available # in XCode 4. return if get_distutils_build_option('compiler'): return compiler_type = ccompiler.get_default_compiler() if compiler_type == 'unix': # We have to get the compiler this way, as this is the one that is # used if os.environ['CC'] is not set. It is actually read in from # the Python Makefile. Note that this is not necessarily the same # compiler as returned by ccompiler.new_compiler() c_compiler = sysconfig.get_config_var('CC') try: version = get_compiler_version(c_compiler) except OSError: msg = textwrap.dedent( """ The C compiler used to compile Python {compiler:s}, and which is normally used to compile C extensions, is not available. You can explicitly specify which compiler to use by setting the CC environment variable, for example: CC=gcc python setup.py or if you are using MacOS X, you can try: CC=clang python setup.py """.format(compiler=c_compiler)) log.warn(msg) sys.exit(1) for broken, fixed in compiler_mapping: if re.match(broken, version): os.environ['CC'] = fixed break def get_compiler_version(compiler): process = subprocess.Popen( shlex.split(compiler) + ['--version'], stdout=subprocess.PIPE) output = process.communicate()[0].strip() try: version = output.split()[0] except IndexError: return 'unknown' return version def get_dummy_distribution(): """Returns a distutils Distribution object used to instrument the setup environment before calling the actual setup() function. """ if _module_state['registered_commands'] is None: raise RuntimeError( 'astropy_helpers.setup_helpers.register_commands() must be ' 'called before using ' 'astropy_helpers.setup_helpers.get_dummy_distribution()') # Pre-parse the Distutils command-line options and config files to if # the option is set. dist = Distribution({'script_name': os.path.basename(sys.argv[0]), 'script_args': sys.argv[1:]}) dist.cmdclass.update(_module_state['registered_commands']) with silence(): try: dist.parse_config_files() dist.parse_command_line() except (DistutilsError, AttributeError, SystemExit): # Let distutils handle DistutilsErrors itself AttributeErrors can # get raise for ./setup.py --help SystemExit can be raised if a # display option was used, for example pass return dist def get_distutils_option(option, commands): """ Returns the value of the given distutils option. Parameters ---------- option : str The name of the option commands : list of str The list of commands on which this option is available Returns ------- val : str or None the value of the given distutils option. If the option is not set, returns None. """ dist = get_dummy_distribution() for cmd in commands: cmd_opts = dist.command_options.get(cmd) if cmd_opts is not None and option in cmd_opts: return cmd_opts[option][1] else: return None def get_distutils_build_option(option): """ Returns the value of the given distutils build option. Parameters ---------- option : str The name of the option Returns ------- val : str or None The value of the given distutils build option. If the option is not set, returns None. """ return get_distutils_option(option, ['build', 'build_ext', 'build_clib']) def get_distutils_install_option(option): """ Returns the value of the given distutils install option. Parameters ---------- option : str The name of the option Returns ------- val : str or None The value of the given distutils build option. If the option is not set, returns None. """ return get_distutils_option(option, ['install']) def get_distutils_build_or_install_option(option): """ Returns the value of the given distutils build or install option. Parameters ---------- option : str The name of the option Returns ------- val : str or None The value of the given distutils build or install option. If the option is not set, returns None. """ return get_distutils_option(option, ['build', 'build_ext', 'build_clib', 'install']) def get_compiler_option(): """ Determines the compiler that will be used to build extension modules. Returns ------- compiler : str The compiler option specificied for the build, build_ext, or build_clib command; or the default compiler for the platform if none was specified. """ compiler = get_distutils_build_option('compiler') if compiler is None: return ccompiler.get_default_compiler() return compiler def get_debug_option(packagename): """ Determines if the build is in debug mode. Returns ------- debug : bool True if the current build was started with the debug option, False otherwise. """ try: current_debug = get_pkg_version_module(packagename, fromlist=['debug'])[0] except (ImportError, AttributeError): current_debug = None # Only modify the debug flag if one of the build commands was explicitly # run (i.e. not as a sub-command of something else) dist = get_dummy_distribution() if any(cmd in dist.commands for cmd in ['build', 'build_ext']): debug = bool(get_distutils_build_option('debug')) else: debug = bool(current_debug) if current_debug is not None and current_debug != debug: build_ext_cmd = dist.get_command_class('build_ext') build_ext_cmd.force_rebuild = True return debug # TODO: Move this into astropy_helpers.version_helpers once the dependency of # version_helpers on *this* module has been resolved (IOW, once these modules # have been refactored to reduce their interdependency) def get_pkg_version_module(packagename, fromlist=None): """Returns the package's .version module generated by `astropy_helpers.version_helpers.generate_version_py`. Raises an ImportError if the version module is not found. If ``fromlist`` is an iterable, return a tuple of the members of the version module corresponding to the member names given in ``fromlist``. Raises an `AttributeError` if any of these module members are not found. """ if not fromlist: # Due to a historical quirk of Python's import implementation, # __import__ will not return submodules of a package if 'fromlist' is # empty. # TODO: For Python 3.1 and up it may be preferable to use importlib # instead of the __import__ builtin return __import__(packagename + '.version', fromlist=['']) else: mod = __import__(packagename + '.version', fromlist=fromlist) return tuple(getattr(mod, member) for member in fromlist) def register_commands(package, version, release): if _module_state['registered_commands'] is not None: return _module_state['registered_commands'] _module_state['registered_commands'] = registered_commands = { 'test': generate_test_command(package), # Use distutils' sdist because it respects package_data. # setuptools/distributes sdist requires duplication of information in # MANIFEST.in 'sdist': DistutilsSdist, # The exact form of the build_ext command depends on whether or not # we're building a release version 'build_ext': generate_build_ext_command(package, release), # We have a custom build_py to generate the default configuration file 'build_py': AstropyBuildPy, # Since install can (in some circumstances) be run without # first building, we also need to override install and # install_lib. See #2223 'install': AstropyInstall, 'install_lib': AstropyInstallLib, 'register': AstropyRegister } if _module_state['have_sphinx']: registered_commands['build_sphinx'] = AstropyBuildSphinx else: registered_commands['build_sphinx'] = FakeBuildSphinx # Need to override the __name__ here so that the commandline options are # presented as being related to the "build" command, for example; normally # this wouldn't be necessary since commands also have a command_name # attribute, but there is a bug in distutils' help display code that it # uses __name__ instead of command_name. Yay distutils! for name, cls in registered_commands.items(): cls.__name__ = name # Add a few custom options; more of these can be added by specific packages # later for option in [ ('use-system-libraries', "Use system libraries whenever possible", True)]: add_command_option('build', *option) add_command_option('install', *option) return registered_commands def generate_test_command(package_name): """ Creates a custom 'test' command for the given package which sets the command's ``package_name`` class attribute to the name of the package being tested. """ return type(package_name.title() + 'Test', (AstropyTest,), {'package_name': package_name}) def generate_build_ext_command(packagename, release): """ Creates a custom 'build_ext' command that allows for manipulating some of the C extension options at build time. We use a function to build the class since the base class for build_ext may be different depending on certain build-time parameters (for example, we may use Cython's build_ext instead of the default version in distutils). Uses the default distutils.command.build_ext by default. """ uses_cython = should_build_with_cython(packagename, release) if uses_cython: from Cython.Distutils import build_ext as basecls else: basecls = SetuptoolsBuildExt attrs = dict(basecls.__dict__) orig_run = getattr(basecls, 'run', None) orig_finalize = getattr(basecls, 'finalize_options', None) def finalize_options(self): # Add a copy of the _compiler.so module as well, but only if there are # in fact C modules to compile (otherwise there's no reason to include # a record of the compiler used) if self.extensions: src_path = os.path.relpath( os.path.join(os.path.dirname(__file__), 'src')) shutil.copy2(os.path.join(src_path, 'compiler.c'), os.path.join(self.package_name, '_compiler.c')) ext = Extension(self.package_name + '._compiler', [os.path.join(self.package_name, '_compiler.c')]) self.extensions.insert(0, ext) if orig_finalize is not None: orig_finalize(self) # Generate if self.uses_cython: try: from Cython import __version__ as cython_version except ImportError: # This shouldn't happen if we made it this far cython_version = None if (cython_version is not None and cython_version != self.uses_cython): self.force_rebuild = True # Update the used cython version self.uses_cython = cython_version # Regardless of the value of the '--force' option, force a rebuild if # the debug flag changed from the last build if self.force_rebuild: self.force = True def run(self): # For extensions that require 'numpy' in their include dirs, replace # 'numpy' with the actual paths np_include = get_numpy_include_path() for extension in self.extensions: if 'numpy' in extension.include_dirs: idx = extension.include_dirs.index('numpy') extension.include_dirs.insert(idx, np_include) extension.include_dirs.remove('numpy') # Replace .pyx with C-equivalents, unless c files are missing for jdx, src in enumerate(extension.sources): if src.endswith('.pyx'): pyxfn = src cfn = src[:-4] + '.c' elif src.endswith('.c'): pyxfn = src[:-2] + '.pyx' cfn = src if not os.path.isfile(pyxfn): continue if self.uses_cython: extension.sources[jdx] = pyxfn else: if os.path.isfile(cfn): extension.sources[jdx] = cfn else: msg = ( 'Could not find C file {0} for Cython file {1} ' 'when building extension {2}. Cython must be ' 'installed to build from a git checkout.'.format( cfn, pyxfn, extension.name)) raise IOError(errno.ENOENT, msg, cfn) if orig_run is not None: # This should always be the case for a correctly implemented # distutils command. orig_run(self) # Update cython_version.py if building with Cython try: cython_version = get_pkg_version_module( packagename, fromlist=['cython_version'])[0] except (AttributeError, ImportError): cython_version = 'unknown' if self.uses_cython and self.uses_cython != cython_version: package_dir = os.path.relpath(packagename) cython_py = os.path.join(package_dir, 'cython_version.py') with open(cython_py, 'w') as f: f.write('# Generated file; do not modify\n') f.write('cython_version = {0!r}\n'.format(self.uses_cython)) if os.path.isdir(self.build_lib): # The build/lib directory may not exist if the build_py command # was not previously run, which may sometimes be the case self.copy_file(cython_py, os.path.join(self.build_lib, cython_py), preserve_mode=False) invalidate_caches() attrs['run'] = run attrs['finalize_options'] = finalize_options attrs['force_rebuild'] = False attrs['uses_cython'] = uses_cython attrs['package_name'] = packagename attrs['user_options'] = basecls.user_options[:] attrs['boolean_options'] = basecls.boolean_options[:] return type('build_ext', (basecls, object), attrs) def _get_platlib_dir(cmd): plat_specifier = '.{0}-{1}'.format(cmd.plat_name, sys.version[0:3]) return os.path.join(cmd.build_base, 'lib' + plat_specifier) class AstropyInstall(SetuptoolsInstall): user_options = SetuptoolsInstall.user_options[:] boolean_options = SetuptoolsInstall.boolean_options[:] def finalize_options(self): build_cmd = self.get_finalized_command('build') platlib_dir = _get_platlib_dir(build_cmd) self.build_lib = platlib_dir SetuptoolsInstall.finalize_options(self) class AstropyInstallLib(SetuptoolsInstallLib): user_options = SetuptoolsInstallLib.user_options[:] boolean_options = SetuptoolsInstallLib.boolean_options[:] def finalize_options(self): build_cmd = self.get_finalized_command('build') platlib_dir = _get_platlib_dir(build_cmd) self.build_dir = platlib_dir SetuptoolsInstallLib.finalize_options(self) class AstropyBuildPy(SetuptoolsBuildPy): user_options = SetuptoolsBuildPy.user_options[:] boolean_options = SetuptoolsBuildPy.boolean_options[:] def finalize_options(self): # Update build_lib settings from the build command to always put # build files in platform-specific subdirectories of build/, even # for projects with only pure-Python source (this is desirable # specifically for support of multiple Python version). build_cmd = self.get_finalized_command('build') platlib_dir = _get_platlib_dir(build_cmd) build_cmd.build_purelib = platlib_dir build_cmd.build_lib = platlib_dir self.build_lib = platlib_dir SetuptoolsBuildPy.finalize_options(self) def run_2to3(self, files, doctests=False): # Filter the files to exclude things that shouldn't be 2to3'd skip_2to3 = self.distribution.skip_2to3 filtered_files = [] for file in files: for package in skip_2to3: if file[len(self.build_lib) + 1:].startswith(package): break else: filtered_files.append(file) SetuptoolsBuildPy.run_2to3(self, filtered_files, doctests) def run(self): # first run the normal build_py SetuptoolsBuildPy.run(self) def add_command_option(command, name, doc, is_bool=False): """ Add a custom option to a setup command. Issues a warning if the option already exists on that command. Parameters ---------- command : str The name of the command as given on the command line name : str The name of the build option doc : str A short description of the option, for the `--help` message is_bool : bool, optional When `True`, the option is a boolean option and doesn't require an associated value. """ dist = get_dummy_distribution() cmdcls = dist.get_command_class(command) if (hasattr(cmdcls, '_astropy_helpers_options') and name in cmdcls._astropy_helpers_options): return attr = name.replace('-', '_') if hasattr(cmdcls, attr): raise RuntimeError( '{0!r} already has a {1!r} class attribute, barring {2!r} from ' 'being usable as a custom option name.'.format(cmdcls, attr, name)) for idx, cmd in enumerate(cmdcls.user_options): if cmd[0] == name: log.warn('Overriding existing {0!r} option ' '{1!r}'.format(command, name)) del cmdcls.user_options[idx] if name in cmdcls.boolean_options: cmdcls.boolean_options.remove(name) break cmdcls.user_options.append((name, None, doc)) if is_bool: cmdcls.boolean_options.append(name) # Distutils' command parsing requires that a command object have an # attribute with the same name as the option (with '-' replaced with '_') # in order for that option to be recognized as valid setattr(cmdcls, attr, None) # This caches the options added through add_command_option so that if it is # run multiple times in the same interpreter repeated adds are ignored # (this way we can still raise a RuntimeError if a custom option overrides # a built-in option) if not hasattr(cmdcls, '_astropy_helpers_options'): cmdcls._astropy_helpers_options = set([name]) else: cmdcls._astropy_helpers_options.add(name) class AstropyRegister(SetuptoolsRegister): """Extends the built in 'register' command to support a ``--hidden`` option to make the registered version hidden on PyPI by default. The result of this is that when a version is registered as "hidden" it can still be downloaded from PyPI, but it does not show up in the list of actively supported versions under http://pypi.python.org/pypi/astropy, and is not set as the most recent version. Although this can always be set through the web interface it may be more convenient to be able to specify via the 'register' command. Hidden may also be considered a safer default when running the 'register' command, though this command uses distutils' normal behavior if the ``--hidden`` option is omitted. """ user_options = SetuptoolsRegister.user_options + [ ('hidden', None, 'mark this release as hidden on PyPI by default') ] boolean_options = SetuptoolsRegister.boolean_options + ['hidden'] def initialize_options(self): SetuptoolsRegister.initialize_options(self) self.hidden = False def build_post_data(self, action): data = SetuptoolsRegister.build_post_data(self, action) if action == 'submit' and self.hidden: data['_pypi_hidden'] = '1' return data def _set_config(self): # The original register command is buggy--if you use .pypirc with a # server-login section *at all* the repository you specify with the -r # option will be overwritten with either the repository in .pypirc or # with the default, # If you do not have a .pypirc using the -r option will just crash. # Way to go distutils # If we don't set self.repository back to a default value _set_config # can crash if there was a user-supplied value for this option; don't # worry, we'll get the real value back afterwards self.repository = 'pypi' SetuptoolsRegister._set_config(self) options = self.distribution.get_option_dict('register') if 'repository' in options: source, value = options['repository'] # Really anything that came from setup.cfg or the command line # should override whatever was in .pypirc self.repository = value if _module_state['have_sphinx']: class AstropyBuildSphinx(SphinxBuildDoc): """ A version of the ``build_sphinx`` command that uses the version of Astropy that is built by the setup ``build`` command, rather than whatever is installed on the system - to build docs against the installed version, run ``make html`` in the ``astropy/docs`` directory. This also automatically creates the docs/_static directories - this is needed because github won't create the _static dir because it has no tracked files. """ description = 'Build Sphinx documentation for Astropy environment' user_options = SphinxBuildDoc.user_options[:] user_options.append(('warnings-returncode', 'w', 'Parses the sphinx output and sets the return ' 'code to 1 if there are any warnings. Note that ' 'this will cause the sphinx log to only update ' 'when it completes, rather than continuously as ' 'is normally the case.')) user_options.append(('clean-docs', 'l', 'Completely clean previous builds, including ' 'automodapi-generated files before building new ' 'ones')) user_options.append(('no-intersphinx', 'n', 'Skip intersphinx, even if conf.py says to use ' 'it')) user_options.append(('open-docs-in-browser', 'o', 'Open the docs in a browser (using the ' 'webbrowser module) if the build finishes ' 'successfully.')) boolean_options = SphinxBuildDoc.boolean_options[:] boolean_options.append('warnings-returncode') boolean_options.append('clean-docs') boolean_options.append('no-intersphinx') boolean_options.append('open-docs-in-browser') _self_iden_rex = re.compile(r"self\.([^\d\W][\w]+)", re.UNICODE) def initialize_options(self): SphinxBuildDoc.initialize_options(self) self.clean_docs = False self.no_intersphinx = False self.open_docs_in_browser = False self.warnings_returncode = False def finalize_options(self): #Clear out previous sphinx builds, if requested if self.clean_docs: dirstorm = [os.path.join(self.source_dir, 'api')] if self.build_dir is None: dirstorm.append('docs/_build') else: dirstorm.append(self.build_dir) for d in dirstorm: if os.path.isdir(d): log.info('Cleaning directory ' + d) shutil.rmtree(d) else: log.info('Not cleaning directory ' + d + ' because ' 'not present or not a directory') SphinxBuildDoc.finalize_options(self) def run(self): # TODO: Break this method up into a few more subroutines and # document them better import webbrowser if PY3: from urllib.request import pathname2url else: from urllib import pathname2url # This is used at the very end of `run` to decide if sys.exit should # be called. If it's None, it won't be. retcode = None # If possible, create the _static dir if self.build_dir is not None: # the _static dir should be in the same place as the _build dir # for Astropy basedir, subdir = os.path.split(self.build_dir) if subdir == '': # the path has a trailing /... basedir, subdir = os.path.split(basedir) staticdir = os.path.join(basedir, '_static') if os.path.isfile(staticdir): raise DistutilsOptionError( 'Attempted to build_sphinx in a location where' + staticdir + 'is a file. Must be a directory.') self.mkpath(staticdir) #Now make sure Astropy is built and determine where it was built build_cmd = self.reinitialize_command('build') build_cmd.inplace = 0 self.run_command('build') build_cmd = self.get_finalized_command('build') build_cmd_path = os.path.abspath(build_cmd.build_lib) ah_importer = pkgutil.get_importer('astropy_helpers') ah_path = os.path.abspath(ah_importer.path) #Now generate the source for and spawn a new process that runs the #command. This is needed to get the correct imports for the built #version runlines, runlineno = inspect.getsourcelines(SphinxBuildDoc.run) subproccode = textwrap.dedent(""" from sphinx.setup_command import * os.chdir({srcdir!r}) sys.path.insert(0, {build_cmd_path!r}) sys.path.insert(0, {ah_path!r}) """).format(build_cmd_path=build_cmd_path, ah_path=ah_path, srcdir=self.source_dir) #runlines[1:] removes 'def run(self)' on the first line subproccode += textwrap.dedent(''.join(runlines[1:])) # All "self.foo" in the subprocess code needs to be replaced by the # values taken from the current self in *this* process subproccode = AstropyBuildSphinx._self_iden_rex.split(subproccode) for i in range(1, len(subproccode), 2): iden = subproccode[i] val = getattr(self, iden) if iden.endswith('_dir'): #Directories should be absolute, because the `chdir` call #in the new process moves to a different directory subproccode[i] = repr(os.path.abspath(val)) else: subproccode[i] = repr(val) subproccode = ''.join(subproccode) if self.no_intersphinx: #the confoverrides variable in sphinx.setup_command.BuildDoc can #be used to override the conf.py ... but this could well break #if future versions of sphinx change the internals of BuildDoc, #so remain vigilant! subproccode = subproccode.replace('confoverrides = {}', 'confoverrides = {\'intersphinx_mapping\':{}}') log.debug('Starting subprocess of {0} with python code:\n{1}\n' '[CODE END])'.format(sys.executable, subproccode)) # To return the number of warnings, we need to capture stdout. This # prevents a continuous updating at the terminal, but there's no # apparent way around this. if self.warnings_returncode: proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdo, stde = proc.communicate(subproccode.encode('utf-8')) print(stdo) stdolines = stdo.split(b'\n') if stdolines[-2] == b'build succeeded.': retcode = 0 else: retcode = 1 if retcode != 0: if os.environ.get('TRAVIS', None) == 'true': #this means we are in the travis build, so customize #the message appropriately. msg = ('The build_sphinx travis build FAILED ' 'because sphinx issued documentation ' 'warnings (scroll up to see the warnings).') else: # standard failure message msg = ('build_sphinx returning a non-zero exit ' 'code because sphinx issued documentation ' 'warnings.') log.warn(msg) else: proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE) proc.communicate(subproccode.encode('utf-8')) if proc.returncode == 0: if self.open_docs_in_browser: if self.builder == 'html': absdir = os.path.abspath(self.builder_target_dir) index_path = os.path.join(absdir, 'index.html') fileurl = 'file://' + pathname2url(index_path) webbrowser.open(fileurl) else: log.warn('open-docs-in-browser option was given, but ' 'the builder is not html! Ignogring.') else: log.warn('Sphinx Documentation subprocess failed with return ' 'code ' + str(proc.returncode)) if retcode is not None: # this is potentially dangerous in that there might be something # after the call to `setup` in `setup.py`, and exiting here will # prevent that from running. But there's no other apparent way # to signal what the return code should be. sys.exit(retcode) def get_distutils_display_options(): """ Returns a set of all the distutils display options in their long and short forms. These are the setup.py arguments such as --name or --version which print the project's metadata and then exit. Returns ------- opts : set The long and short form display option arguments, including the - or -- """ short_display_opts = set('-' + o[1] for o in Distribution.display_options if o[1]) long_display_opts = set('--' + o[0] for o in Distribution.display_options) # Include -h and --help which are not explicitly listed in # Distribution.display_options (as they are handled by optparse) short_display_opts.add('-h') long_display_opts.add('--help') # This isn't the greatest approach to hardcode these commands. # However, there doesn't seem to be a good way to determine # whether build *will be* run as part of the command at this # phase. display_commands = set([ 'clean', 'register', 'setopt', 'saveopts', 'egg_info', 'alias']) return short_display_opts.union(long_display_opts.union(display_commands)) def is_distutils_display_option(): """ Returns True if sys.argv contains any of the distutils display options such as --version or --name. """ display_options = get_distutils_display_options() return bool(set(sys.argv[1:]).intersection(display_options)) def update_package_files(srcdir, extensions, package_data, packagenames, package_dirs): """ This function is deprecated and maintained for backward compatibility with affiliated packages. Affiliated packages should update their setup.py to use `get_package_info` instead. """ info = get_package_info(srcdir) extensions.extend(info['ext_modules']) package_data.update(info['package_data']) packagenames = list(set(packagenames + info['packages'])) package_dirs.update(info['package_dir']) def get_package_info(srcdir='.', exclude=()): """ Collates all of the information for building all subpackages subpackages and returns a dictionary of keyword arguments that can be passed directly to `distutils.setup`. The purpose of this function is to allow subpackages to update the arguments to the package's ``setup()`` function in its setup.py script, rather than having to specify all extensions/package data directly in the ``setup.py``. See Astropy's own ``setup.py`` for example usage and the Astropy development docs for more details. This function obtains that information by iterating through all packages in ``srcdir`` and locating a ``setup_package.py`` module. This module can contain the following functions: ``get_extensions()``, ``get_package_data()``, ``get_build_options()``, ``get_external_libraries()``, and ``requires_2to3()``. Each of those functions take no arguments. - ``get_extensions`` returns a list of `distutils.extension.Extension` objects. - ``get_package_data()`` returns a dict formatted as required by the ``package_data`` argument to ``setup()``. - ``get_build_options()`` returns a list of tuples describing the extra build options to add. - ``get_external_libraries()`` returns a list of libraries that can optionally be built using external dependencies. - ``requires_2to3()`` should return `True` when the source code requires `2to3` processing to run on Python 3.x. If ``requires_2to3()`` is missing, it is assumed to return `True`. """ ext_modules = [] packages = [] package_data = {} package_dir = {} skip_2to3 = [] # Use the find_packages tool to locate all packages and modules packages = filter_packages(find_packages(srcdir, exclude=exclude)) # For each of the setup_package.py modules, extract any # information that is needed to install them. The build options # are extracted first, so that their values will be available in # subsequent calls to `get_extensions`, etc. for setuppkg in iter_setup_packages(srcdir, packages): if hasattr(setuppkg, 'get_build_options'): options = setuppkg.get_build_options() for option in options: add_command_option('build', *option) if hasattr(setuppkg, 'get_external_libraries'): libraries = setuppkg.get_external_libraries() for library in libraries: add_external_library(library) if hasattr(setuppkg, 'requires_2to3'): requires_2to3 = setuppkg.requires_2to3() else: requires_2to3 = True if not requires_2to3: skip_2to3.append( os.path.dirname(setuppkg.__file__)) for setuppkg in iter_setup_packages(srcdir, packages): # get_extensions must include any Cython extensions by their .pyx # filename. if hasattr(setuppkg, 'get_extensions'): ext_modules.extend(setuppkg.get_extensions()) if hasattr(setuppkg, 'get_package_data'): package_data.update(setuppkg.get_package_data()) # Locate any .pyx files not already specified, and add their extensions in. # The default include dirs include numpy to facilitate numerical work. ext_modules.extend(get_cython_extensions(srcdir, packages, ext_modules, ['numpy'])) # Now remove extensions that have the special name 'skip_cython', as they # exist Only to indicate that the cython extensions shouldn't be built for i, ext in reversed(list(enumerate(ext_modules))): if ext.name == 'skip_cython': del ext_modules[i] # On Microsoft compilers, we need to pass the '/MANIFEST' # commandline argument. This was the default on MSVC 9.0, but is # now required on MSVC 10.0, but it doesn't seeem to hurt to add # it unconditionally. if get_compiler_option() == 'msvc': for ext in ext_modules: ext.extra_link_args.append('/MANIFEST') return { 'ext_modules': ext_modules, 'packages': packages, 'package_dir': package_dir, 'package_data': package_data, 'skip_2to3': skip_2to3 } def iter_setup_packages(srcdir, packages): """ A generator that finds and imports all of the ``setup_package.py`` modules in the source packages. Returns ------- modgen : generator A generator that yields (modname, mod), where `mod` is the module and `modname` is the module name for the ``setup_package.py`` modules. """ for packagename in packages: package_parts = packagename.split('.') package_path = os.path.join(srcdir, *package_parts) setup_package = os.path.relpath( os.path.join(package_path, 'setup_package.py')) if os.path.isfile(setup_package): module = import_file(setup_package) yield module def iter_pyx_files(package_dir, package_name): """ A generator that yields Cython source files (ending in '.pyx') in the source packages. Returns ------- pyxgen : generator A generator that yields (extmod, fullfn) where `extmod` is the full name of the module that the .pyx file would live in based on the source directory structure, and `fullfn` is the path to the .pyx file. """ for dirpath, dirnames, filenames in walk_skip_hidden(package_dir): for fn in filenames: if fn.endswith('.pyx'): fullfn = os.path.relpath(os.path.join(dirpath, fn)) # Package must match file name extmod = '.'.join([package_name, fn[:-4]]) yield (extmod, fullfn) break # Don't recurse into subdirectories def should_build_with_cython(package, release=None): """Returns the previously used Cython version (or 'unknown' if not previously built) if Cython should be used to build extension modules from pyx files. If the ``release`` parameter is not specified an attempt is made to determine the release flag from `astropy.version`. """ try: version_module = __import__(package + '.cython_version', fromlist=['release', 'cython_version']) except ImportError: version_module = None if release is None and version_module is not None: try: release = version_module.release except AttributeError: pass try: cython_version = version_module.cython_version except AttributeError: cython_version = 'unknown' # Only build with Cython if, of course, Cython is installed, we're in a # development version (i.e. not release) or the Cython-generated source # files haven't been created yet (cython_version == 'unknown'). The latter # case can happen even when release is True if checking out a release tag # from the repository if (_module_state['have_cython'] and (not release or cython_version == 'unknown')): return cython_version else: return False def get_cython_extensions(srcdir, packages, prevextensions=tuple(), extincludedirs=None): """ Looks for Cython files and generates Extensions if needed. Parameters ---------- srcdir : str Path to the root of the source directory to search. prevextensions : list of `~distutils.core.Extension` objects The extensions that are already defined. Any .pyx files already here will be ignored. extincludedirs : list of str or None Directories to include as the `include_dirs` argument to the generated `~distutils.core.Extension` objects. Returns ------- exts : list of `~distutils.core.Extension` objects The new extensions that are needed to compile all .pyx files (does not include any already in `prevextensions`). """ # Vanilla setuptools and old versions of distribute include Cython files # as .c files in the sources, not .pyx, so we cannot simply look for # existing .pyx sources in the previous sources, but we should also check # for .c files with the same remaining filename. So we look for .pyx and # .c files, and we strip the extension. prevsourcepaths = [] ext_modules = [] for ext in prevextensions: for s in ext.sources: if s.endswith(('.pyx', '.c')): sourcepath = os.path.realpath(os.path.splitext(s)[0]) prevsourcepaths.append(sourcepath) for package_name in packages: package_parts = package_name.split('.') package_path = os.path.join(srcdir, *package_parts) for extmod, pyxfn in iter_pyx_files(package_path, package_name): sourcepath = os.path.realpath(os.path.splitext(pyxfn)[0]) if sourcepath not in prevsourcepaths: ext_modules.append(Extension(extmod, [pyxfn], include_dirs=extincludedirs)) return ext_modules def write_if_different(filename, data): """ Write `data` to `filename`, if the content of the file is different. Parameters ---------- filename : str The file name to be written to. data : bytes The data to be written to `filename`. """ assert isinstance(data, bytes) if os.path.exists(filename): with open(filename, 'rb') as fd: original_data = fd.read() else: original_data = None if original_data != data: with open(filename, 'wb') as fd: fd.write(data) def get_numpy_include_path(): """ Gets the path to the numpy headers. """ # We need to go through this nonsense in case setuptools # downloaded and installed Numpy for us as part of the build or # install, since Numpy may still think it's in "setup mode", when # in fact we're ready to use it to build astropy now. if sys.version_info[0] >= 3: import builtins if hasattr(builtins, '__NUMPY_SETUP__'): del builtins.__NUMPY_SETUP__ import imp import numpy imp.reload(numpy) else: import __builtin__ if hasattr(__builtin__, '__NUMPY_SETUP__'): del __builtin__.__NUMPY_SETUP__ import numpy reload(numpy) try: numpy_include = numpy.get_include() except AttributeError: numpy_include = numpy.get_numpy_include() return numpy_include def import_file(filename): """ Imports a module from a single file as if it doesn't belong to a particular package. """ # Specifying a traditional dot-separated fully qualified name here # results in a number of "Parent module 'astropy' not found while # handling absolute import" warnings. Using the same name, the # namespaces of the modules get merged together. So, this # generates an underscore-separated name which is more likely to # be unique, and it doesn't really matter because the name isn't # used directly here anyway. with open(filename, 'U') as fd: name = '_'.join( os.path.relpath(os.path.splitext(filename)[0]).split(os.sep)[1:]) return imp.load_module(name, fd, filename, ('.py', 'U', 1)) class DistutilsExtensionArgs(collections.defaultdict): """ A special dictionary whose default values are the empty list. This is useful for building up a set of arguments for `distutils.Extension` without worrying whether the entry is already present. """ def __init__(self, *args, **kwargs): def default_factory(): return [] super(DistutilsExtensionArgs, self).__init__( default_factory, *args, **kwargs) def update(self, other): for key, val in other.items(): self[key].extend(val) def pkg_config(packages, default_libraries, executable='pkg-config'): """ Uses pkg-config to update a set of distutils Extension arguments to include the flags necessary to link against the given packages. If the pkg-config lookup fails, default_libraries is applied to libraries. Parameters ---------- packages : list of str A list of pkg-config packages to look up. default_libraries : list of str A list of library names to use if the pkg-config lookup fails. Returns ------- config : dict A dictionary containing keyword arguments to `distutils.Extension`. These entries include: - ``include_dirs``: A list of include directories - ``library_dirs``: A list of library directories - ``libraries``: A list of libraries - ``define_macros``: A list of macro defines - ``undef_macros``: A list of macros to undefine - ``extra_compile_args``: A list of extra arguments to pass to the compiler """ flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries', '-D': 'define_macros', '-U': 'undef_macros'} command = "{0} --libs --cflags {1}".format(executable, ' '.join(packages)), result = DistutilsExtensionArgs() try: pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) output = pipe.communicate()[0].strip() except subprocess.CalledProcessError as e: lines = [ "{0} failed. This may cause the build to fail below.".format(executable), " command: {0}".format(e.cmd), " returncode: {0}".format(e.returncode), " output: {0}".format(e.output) ] log.warn('\n'.join(lines)) result['libraries'].extend(default_libraries) else: if pipe.returncode != 0: lines = [ "pkg-config could not lookup up package(s) {0}.".format( ", ".join(packages)), "This may cause the build to fail below." ] log.warn('\n'.join(lines)) result['libraries'].extend(default_libraries) else: for token in output.split(): # It's not clear what encoding the output of # pkg-config will come to us in. It will probably be # some combination of pure ASCII (for the compiler # flags) and the filesystem encoding (for any argument # that includes directories or filenames), but this is # just conjecture, as the pkg-config documentation # doesn't seem to address it. arg = token[:2].decode('ascii') value = token[2:].decode(sys.getfilesystemencoding()) if arg in flag_map: if arg == '-D': value = tuple(value.split('=', 1)) result[flag_map[arg]].append(value) else: result['extra_compile_args'].append(value) return result def add_external_library(library): """ Add a build option for selecting the internal or system copy of a library. Parameters ---------- library : str The name of the library. If the library is `foo`, the build option will be called `--use-system-foo`. """ for command in ['build', 'build_ext', 'install']: add_command_option(command, str('use-system-' + library), 'Use the system {0} library'.format(library), is_bool=True) def use_system_library(library): """ Returns `True` if the build configuration indicates that the given library should use the system copy of the library rather than the internal one. For the given library `foo`, this will be `True` if `--use-system-foo` or `--use-system-libraries` was provided at the commandline or in `setup.cfg`. Parameters ---------- library : str The name of the library Returns ------- use_system : bool `True` if the build should use the system copy of the library. """ return ( get_distutils_build_or_install_option('use_system_{0}'.format(library)) or get_distutils_build_or_install_option('use_system_libraries')) def filter_packages(packagenames): """ Removes some packages from the package list that shouldn't be installed on the current version of Python. """ if PY3: exclude = '_py2' else: exclude = '_py3' return [x for x in packagenames if not x.endswith(exclude)] class FakeBuildSphinx(Command): """ A dummy build_sphinx command that is called if Sphinx is not installed and displays a relevant error message """ #user options inherited from sphinx.setup_command.BuildDoc user_options = [ ('fresh-env', 'E', '' ), ('all-files', 'a', ''), ('source-dir=', 's', ''), ('build-dir=', None, ''), ('config-dir=', 'c', ''), ('builder=', 'b', ''), ('project=', None, ''), ('version=', None, ''), ('release=', None, ''), ('today=', None, ''), ('link-index', 'i', ''), ] #user options appended in astropy.setup_helpers.AstropyBuildSphinx user_options.append(('warnings-returncode', 'w','')) user_options.append(('clean-docs', 'l', '')) user_options.append(('no-intersphinx', 'n', '')) user_options.append(('open-docs-in-browser', 'o','')) def initialize_options(self): try: raise RuntimeError("Sphinx must be installed for build_sphinx") except: log.error('error : Sphinx must be installed for build_sphinx') sys.exit(1) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/0000755000077000000240000000000012505171566023743 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/__init__.py0000644000077000000240000000041412354456432026053 0ustar adamstaff00000000000000""" This package contains utilities and extensions for the Astropy sphinx documentation. In particular, the `astropy.sphinx.conf` should be imported by the sphinx ``conf.py`` file for affiliated packages that wish to make use of the Astropy documentation format. """ astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/conf.py0000644000077000000240000002457612425434461025255 0ustar adamstaff00000000000000# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # # Astropy shared Sphinx settings. These settings are shared between # astropy itself and affiliated packages. # # Note that not all possible configuration values are present in this file. # # All configuration values have a default; values that are commented out # serve to show the default. import warnings from os import path # -- General configuration ---------------------------------------------------- # The version check in Sphinx itself can only compare the major and # minor parts of the version number, not the micro. To do a more # specific version check, call check_sphinx_version("x.y.z.") from # your project's conf.py needs_sphinx = '1.2' def check_sphinx_version(expected_version): import sphinx from distutils import version sphinx_version = version.LooseVersion(sphinx.__version__) expected_version = version.LooseVersion(expected_version) if sphinx_version < expected_version: raise RuntimeError( "At least Sphinx version {0} is required to build this " "documentation. Found {1}.".format( expected_version, sphinx_version)) # Configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('http://docs.python.org/', None), 'python3': ('http://docs.python.org/3/', path.abspath(path.join(path.dirname(__file__), 'local/python3links.inv'))), 'numpy': ('http://docs.scipy.org/doc/numpy/', None), 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), 'matplotlib': ('http://matplotlib.org/', None), 'astropy': ('http://docs.astropy.org/en/stable/', None), 'h5py': ('http://docs.h5py.org/en/latest/', None) } # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # Add any paths that contain templates here, relative to this directory. # templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # The reST default role (used for this markup: `text`) to use for all # documents. Set to the "smart" one. default_role = 'obj' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # This is added to the end of RST files - a good place to put substitutions to # be used globally. rst_epilog = """ .. _Astropy: http://astropy.org """ # -- Project information ------------------------------------------------------ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. #pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Settings for extensions and extension options ---------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.inheritance_diagram', 'astropy_helpers.sphinx.ext.numpydoc', 'astropy_helpers.sphinx.ext.astropyautosummary', 'astropy_helpers.sphinx.ext.automodsumm', 'astropy_helpers.sphinx.ext.automodapi', 'astropy_helpers.sphinx.ext.tocdepthfix', 'astropy_helpers.sphinx.ext.doctest', 'astropy_helpers.sphinx.ext.changelog_links', 'astropy_helpers.sphinx.ext.viewcode', # Use patched version of viewcode 'astropy_helpers.sphinx.ext.smart_resolver' ] # Above, we use a patched version of viewcode rather than 'sphinx.ext.viewcode' # This can be changed to the sphinx version once the following issue is fixed # in sphinx: # https://bitbucket.org/birkenfeld/sphinx/issue/623/ # extension-viewcode-fails-with-function try: import matplotlib.sphinxext.plot_directive extensions += [matplotlib.sphinxext.plot_directive.__name__] # AttributeError is checked here in case matplotlib is installed but # Sphinx isn't. Note that this module is imported by the config file # generator, even if we're not building the docs. except (ImportError, AttributeError): warnings.warn( "matplotlib's plot_directive could not be imported. " + "Inline plots will not be included in the output") # Don't show summaries of the members in each class along with the # class' docstring numpydoc_show_class_members = False autosummary_generate = True automodapi_toctreedirnm = 'api' # Class documentation should contain *both* the class docstring and # the __init__ docstring autoclass_content = "both" # -- Options for HTML output ------------------------------------------------- # Add any paths that contain custom themes here, relative to this directory. html_theme_path = [path.abspath(path.join(path.dirname(__file__), 'themes'))] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'bootstrap-astropy' # Custom sidebar templates, maps document names to template names. html_sidebars = { '**': ['localtoc.html'], 'search': [], 'genindex': [], 'py-modindex': [], } # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # included in the bootstrap-astropy theme html_favicon = path.join(html_theme_path[0], html_theme, 'static', 'astropy_logo.ico') # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%d %b %Y' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # -- Options for LaTeX output ------------------------------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. latex_use_parts = True # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. latex_preamble = r""" % Use a more modern-looking monospace font \usepackage{inconsolata} % The enumitem package provides unlimited nesting of lists and enums. % Sphinx may use this in the future, in which case this can be removed. % See https://bitbucket.org/birkenfeld/sphinx/issue/777/latex-output-too-deeply-nested \usepackage{enumitem} \setlistdepth{15} % In the parameters section, place a newline after the Parameters % header. (This is stolen directly from Numpy's conf.py, since it % affects Numpy-style docstrings). \usepackage{expdlist} \let\latexdescription=\description \def\description{\latexdescription{}{} \breaklabel} % Support the superscript Unicode numbers used by the "unicode" units % formatter \DeclareUnicodeCharacter{2070}{\ensuremath{^0}} \DeclareUnicodeCharacter{00B9}{\ensuremath{^1}} \DeclareUnicodeCharacter{00B2}{\ensuremath{^2}} \DeclareUnicodeCharacter{00B3}{\ensuremath{^3}} \DeclareUnicodeCharacter{2074}{\ensuremath{^4}} \DeclareUnicodeCharacter{2075}{\ensuremath{^5}} \DeclareUnicodeCharacter{2076}{\ensuremath{^6}} \DeclareUnicodeCharacter{2077}{\ensuremath{^7}} \DeclareUnicodeCharacter{2078}{\ensuremath{^8}} \DeclareUnicodeCharacter{2079}{\ensuremath{^9}} \DeclareUnicodeCharacter{207B}{\ensuremath{^-}} \DeclareUnicodeCharacter{00B0}{\ensuremath{^{\circ}}} \DeclareUnicodeCharacter{2032}{\ensuremath{^{\prime}}} \DeclareUnicodeCharacter{2033}{\ensuremath{^{\prime\prime}}} % Make the "warning" and "notes" sections use a sans-serif font to % make them stand out more. \renewenvironment{notice}[2]{ \def\py@noticetype{#1} \csname py@noticestart@#1\endcsname \textsf{\textbf{#2}} }{\csname py@noticeend@\py@noticetype\endcsname} """ # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # -- Options for the linkcheck builder ---------------------------------------- # A timeout value, in seconds, for the linkcheck builder linkcheck_timeout = 60 astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/0000755000077000000240000000000012505171566024543 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/__init__.py0000644000077000000240000000013612354456432026654 0ustar adamstaff00000000000000from __future__ import division, absolute_import, print_function from .numpydoc import setup astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/astropyautosummary.py0000644000077000000240000000652712425434461031134 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension builds off of `sphinx.ext.autosummary` to clean up some issues it presents in the Astropy docs. The main issue this fixes is the summary tables getting cut off before the end of the sentence in some cases. """ import re from sphinx.ext.autosummary import Autosummary # used in AstropyAutosummary.get_items _itemsummrex = re.compile(r'^([A-Z].*?\.(?:\s|$))') class AstropyAutosummary(Autosummary): def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ from sphinx.ext.autosummary import (get_import_prefixes_from_env, import_by_name, get_documenter, mangle_signature) env = self.state.document.settings.env prefixes = get_import_prefixes_from_env(env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: import_by_name_values = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('[astropyautosummary] failed to import %s' % name) items.append((name, '', '', name)) continue # to accommodate Sphinx v1.2.2 and v1.2.3 if len(import_by_name_values) == 3: real_name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: real_name, obj, parent, module_name = import_by_name_values # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('[astropyautosummary] failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): self.warn('[astropyautosummary] failed to import object %s' % real_name) items.append((display_name, '', '', real_name)) continue # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the summary doc = list(documenter.process_doc(documenter.get_doc())) while doc and not doc[0].strip(): doc.pop(0) m = _itemsummrex.search(" ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items def setup(app): # need autosummary, of course app.setup_extension('sphinx.ext.autosummary') # this replaces the default autosummary with the astropy one app.add_directive('autosummary', AstropyAutosummary) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/automodapi.py0000644000077000000240000003060512401041777027256 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension adds a tools to simplify generating the API documentation for Astropy packages and affiliated packages. .. _automodapi: ======================== automodapi directive ======================== This directive takes a single argument that must be a module or package. It will produce a block of documentation that includes the docstring for the package, an :ref:`automodsumm` directive, and an :ref:`automod-diagram` if there are any classes in the module. If only the main docstring of the module/package is desired in the documentation, use `automodule`_ instead of `automodapi`_. It accepts the following options: * ``:no-inheritance-diagram:`` If present, the inheritance diagram will not be shown even if the module/package has classes. * ``:skip: str`` This option results in the specified object being skipped, that is the object will *not* be included in the generated documentation. This option may appear any number of times to skip multiple objects. * ``:no-main-docstr:`` If present, the docstring for the module/package will not be generated. The function and class tables will still be used, however. * ``:headings: str`` Specifies the characters (in one string) used as the heading levels used for the generated section. This must have at least 2 characters (any after 2 will be ignored). This also *must* match the rest of the documentation on this page for sphinx to be happy. Defaults to "-^", which matches the convention used for Python's documentation, assuming the automodapi call is inside a top-level section (which usually uses '='). * ``:no-heading:`` If specified do not create a top level heading for the section. That is, do not create a title heading with text like "packagename Package". The actual docstring for the package/module will still be shown, though, unless ``:no-main-docstr:`` is given. * ``:allowed-package-names: str`` Specifies the packages that functions/classes documented here are allowed to be from, as comma-separated list of package names. If not given, only objects that are actually in a subpackage of the package currently being documented are included. This extension also adds two sphinx configuration options: * ``automodapi_toctreedirnm`` This must be a string that specifies the name of the directory the automodsumm generated documentation ends up in. This directory path should be relative to the documentation root (e.g., same place as ``index.rst``). Defaults to ``'api'``. * ``automodapi_writereprocessed`` Should be a bool, and if `True`, will cause `automodapi`_ to write files with any `automodapi`_ sections replaced with the content Sphinx processes after `automodapi`_ has run. The output files are not actually used by sphinx, so this option is only for figuring out the cause of sphinx warnings or other debugging. Defaults to `False`. .. _automodule: http://sphinx-doc.org/latest/ext/autodoc.html?highlight=automodule#directive-automodule """ # Implementation note: # The 'automodapi' directive is not actually implemented as a docutils # directive. Instead, this extension searches for the 'automodapi' text in # all sphinx documents, and replaces it where necessary from a template built # into this extension. This is necessary because automodsumm (and autosummary) # use the "builder-inited" event, which comes before the directives are # actually built. import inspect import os import re import sys from .utils import find_mod_objs automod_templ_modheader = """ {modname} {pkgormod} {modhds}{pkgormodhds} {automoduleline} """ automod_templ_classes = """ Classes {clshds} .. automodsumm:: {modname} :classes-only: {clsfuncoptions} """ automod_templ_funcs = """ Functions {funchds} .. automodsumm:: {modname} :functions-only: {clsfuncoptions} """ automod_templ_inh = """ Class Inheritance Diagram {clsinhsechds} .. automod-diagram:: {modname} :private-bases: :parts: 1 {allowedpkgnms} """ _automodapirex = re.compile(r'^(?:\s*\.\.\s+automodapi::\s*)([A-Za-z0-9_.]+)' r'\s*$((?:\n\s+:[a-zA-Z_\-]+:.*$)*)', flags=re.MULTILINE) # the last group of the above regex is intended to go into finall with the below _automodapiargsrex = re.compile(r':([a-zA-Z_\-]+):(.*)$', flags=re.MULTILINE) def automodapi_replace(sourcestr, app, dotoctree=True, docname=None, warnings=True): """ Replaces `sourcestr`'s entries of ".. automdapi::" with the automodapi template form based on provided options. This is used with the sphinx event 'source-read' to replace `automodapi`_ entries before sphinx actually processes them, as automodsumm needs the code to be present to generate stub documentation. Parameters ---------- sourcestr : str The string with sphinx source to be checked for automodapi replacement. app : `sphinx.application.Application` The sphinx application. dotoctree : bool If `True`, a ":toctree:" option will be added in the ".. automodsumm::" sections of the template, pointing to the appropriate "generated" directory based on the Astropy convention (e.g. in ``docs/api``) docname : str The name of the file for this `sourcestr` (if known - if not, it can be `None`). If not provided and `dotoctree` is `True`, the generated files may end up in the wrong place. warnings : bool If `False`, all warnings that would normally be issued are silenced. Returns ------- newstr :str The string with automodapi entries replaced with the correct sphinx markup. """ spl = _automodapirex.split(sourcestr) if len(spl) > 1: # automodsumm is in this document if dotoctree: toctreestr = ':toctree: ' dirnm = app.config.automodapi_toctreedirnm if not dirnm.endswith(os.sep): dirnm += os.sep if docname is not None: toctreestr += '../' * docname.count('/') + dirnm else: toctreestr += dirnm else: toctreestr = '' newstrs = [spl[0]] for grp in range(len(spl) // 3): modnm = spl[grp * 3 + 1] # find where this is in the document for warnings if docname is None: location = None else: location = (docname, spl[0].count('\n')) # initialize default options toskip = [] inhdiag = maindocstr = top_head = True hds = '-^' allowedpkgnms = [] # look for actual options unknownops = [] for opname, args in _automodapiargsrex.findall(spl[grp * 3 + 2]): if opname == 'skip': toskip.append(args.strip()) elif opname == 'no-inheritance-diagram': inhdiag = False elif opname == 'no-main-docstr': maindocstr = False elif opname == 'headings': hds = args elif opname == 'no-heading': top_head = False elif opname == 'allowed-package-names': allowedpkgnms.append(args.strip()) else: unknownops.append(opname) #join all the allowedpkgnms if len(allowedpkgnms) == 0: allowedpkgnms = '' onlylocals = True else: allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms) onlylocals = allowedpkgnms # get the two heading chars if len(hds) < 2: msg = 'Not enough headings (got {0}, need 2), using default -^' if warnings: app.warn(msg.format(len(hds)), location) hds = '-^' h1, h2 = hds.lstrip()[:2] # tell sphinx that the remaining args are invalid. if len(unknownops) > 0 and app is not None: opsstrs = ','.join(unknownops) msg = 'Found additional options ' + opsstrs + ' in automodapi.' if warnings: app.warn(msg, location) ispkg, hascls, hasfuncs = _mod_info(modnm, toskip, onlylocals=onlylocals) # add automodule directive only if no-main-docstr isn't present if maindocstr: automodline = '.. automodule:: {modname}'.format(modname=modnm) else: automodline = '' if top_head: newstrs.append(automod_templ_modheader.format(modname=modnm, modhds=h1 * len(modnm), pkgormod='Package' if ispkg else 'Module', pkgormodhds=h1 * (8 if ispkg else 7), automoduleline=automodline)) else: newstrs.append(automod_templ_modheader.format( modname='', modhds='', pkgormod='', pkgormodhds='', automoduleline=automodline)) #construct the options for the class/function sections #start out indented at 4 spaces, but need to keep the indentation. clsfuncoptions = [] if toctreestr: clsfuncoptions.append(toctreestr) if toskip: clsfuncoptions.append(':skip: ' + ','.join(toskip)) if allowedpkgnms: clsfuncoptions.append(allowedpkgnms) clsfuncoptionstr = '\n '.join(clsfuncoptions) if hasfuncs: newstrs.append(automod_templ_funcs.format( modname=modnm, funchds=h2 * 9, clsfuncoptions=clsfuncoptionstr)) if hascls: newstrs.append(automod_templ_classes.format( modname=modnm, clshds=h2 * 7, clsfuncoptions=clsfuncoptionstr)) if inhdiag and hascls: # add inheritance diagram if any classes are in the module newstrs.append(automod_templ_inh.format( modname=modnm, clsinhsechds=h2 * 25, allowedpkgnms=allowedpkgnms)) newstrs.append(spl[grp * 3 + 3]) newsourcestr = ''.join(newstrs) if app.config.automodapi_writereprocessed: # sometimes they are unicode, sometimes not, depending on how # sphinx has processed things if isinstance(newsourcestr, unicode): ustr = newsourcestr else: ustr = newsourcestr.decode(app.config.source_encoding) if docname is None: with open(os.path.join(app.srcdir, 'unknown.automodapi'), 'a') as f: f.write('\n**NEW DOC**\n\n') f.write(ustr.encode('utf8')) else: with open(os.path.join(app.srcdir, docname + '.automodapi'), 'w') as f: f.write(ustr.encode('utf8')) return newsourcestr else: return sourcestr def _mod_info(modname, toskip=[], onlylocals=True): """ Determines if a module is a module or a package and whether or not it has classes or functions. """ hascls = hasfunc = False for localnm, fqnm, obj in zip(*find_mod_objs(modname, onlylocals=onlylocals)): if localnm not in toskip: hascls = hascls or inspect.isclass(obj) hasfunc = hasfunc or inspect.isroutine(obj) if hascls and hasfunc: break # find_mod_objs has already imported modname pkg = sys.modules[modname] ispkg = '__init__.' in os.path.split(pkg.__name__)[1] return ispkg, hascls, hasfunc def process_automodapi(app, docname, source): source[0] = automodapi_replace(source[0], app, True, docname) def setup(app): # need automodsumm for automodapi app.setup_extension('astropy_helpers.sphinx.ext.automodsumm') app.connect('source-read', process_automodapi) app.add_config_value('automodapi_toctreedirnm', 'api', True) app.add_config_value('automodapi_writereprocessed', False, True) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/automodsumm.py0000644000077000000240000005453312464715714027504 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension adds two directives for summarizing the public members of a module or package. These directives are primarily for use with the `automodapi`_ extension, but can be used independently. .. _automodsumm: ======================= automodsumm directive ======================= This directive will produce an "autosummary"-style table for public attributes of a specified module. See the `sphinx.ext.autosummary`_ extension for details on this process. The main difference from the `autosummary`_ directive is that `autosummary`_ requires manually inputting all attributes that appear in the table, while this captures the entries automatically. This directive requires a single argument that must be a module or package. It also accepts any options supported by the `autosummary`_ directive- see `sphinx.ext.autosummary`_ for details. It also accepts two additional options: * ``:classes-only:`` If present, the autosummary table will only contain entries for classes. This cannot be used at the same time with ``:functions-only:`` . * ``:functions-only:`` If present, the autosummary table will only contain entries for functions. This cannot be used at the same time with ``:classes-only:`` . * ``:skip: obj1, [obj2, obj3, ...]`` If present, specifies that the listed objects should be skipped and not have their documentation generated, nor be includded in the summary table. * ``:allowed-package-names: pkgormod1, [pkgormod2, pkgormod3, ...]`` Specifies the packages that functions/classes documented here are allowed to be from, as comma-separated list of package names. If not given, only objects that are actually in a subpackage of the package currently being documented are included. This extension also adds one sphinx configuration option: * ``automodsumm_writereprocessed`` Should be a bool, and if True, will cause `automodsumm`_ to write files with any ``automodsumm`` sections replaced with the content Sphinx processes after ``automodsumm`` has run. The output files are not actually used by sphinx, so this option is only for figuring out the cause of sphinx warnings or other debugging. Defaults to `False`. .. _sphinx.ext.autosummary: http://sphinx-doc.org/latest/ext/autosummary.html .. _autosummary: http://sphinx-doc.org/latest/ext/autosummary.html#directive-autosummary .. _automod-diagram: =========================== automod-diagram directive =========================== This directive will produce an inheritance diagram like that of the `sphinx.ext.inheritance_diagram`_ extension. This directive requires a single argument that must be a module or package. It accepts no options. .. note:: Like 'inheritance-diagram', 'automod-diagram' requires `graphviz `_ to generate the inheritance diagram. .. _sphinx.ext.inheritance_diagram: http://sphinx-doc.org/latest/ext/inheritance.html """ import inspect import os import re from sphinx.ext.autosummary import Autosummary from sphinx.ext.inheritance_diagram import InheritanceDiagram from docutils.parsers.rst.directives import flag from .utils import find_mod_objs from .astropyautosummary import AstropyAutosummary def _str_list_converter(argument): """ A directive option conversion function that converts the option into a list of strings. Used for 'skip' option. """ if argument is None: return [] else: return [s.strip() for s in argument.split(',')] class Automodsumm(AstropyAutosummary): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False has_content = False option_spec = dict(Autosummary.option_spec) option_spec['functions-only'] = flag option_spec['classes-only'] = flag option_spec['skip'] = _str_list_converter option_spec['allowed-package-names'] = _str_list_converter def run(self): env = self.state.document.settings.env modname = self.arguments[0] self.warnings = [] nodelist = [] try: localnames, fqns, objs = find_mod_objs(modname) except ImportError: self.warnings = [] self.warn("Couldn't import module " + modname) return self.warnings try: # set self.content to trick the Autosummary internals. # Be sure to respect functions-only and classes-only. funconly = 'functions-only' in self.options clsonly = 'classes-only' in self.options skipnames = [] if 'skip' in self.options: option_skipnames = set(self.options['skip']) for lnm in localnames: if lnm in option_skipnames: option_skipnames.remove(lnm) skipnames.append(lnm) if len(option_skipnames) > 0: self.warn('Tried to skip objects {objs} in module {mod}, ' 'but they were not present. Ignoring.'.format( objs=option_skipnames, mod=modname)) if funconly and not clsonly: cont = [] for nm, obj in zip(localnames, objs): if nm not in skipnames and inspect.isroutine(obj): cont.append(nm) elif clsonly: cont = [] for nm, obj in zip(localnames, objs): if nm not in skipnames and inspect.isclass(obj): cont.append(nm) else: if clsonly and funconly: self.warning('functions-only and classes-only both ' 'defined. Skipping.') cont = [nm for nm in localnames if nm not in skipnames] self.content = cont #for some reason, even though ``currentmodule`` is substituted in, sphinx #doesn't necessarily recognize this fact. So we just force it #internally, and that seems to fix things env.temp_data['py:module'] = modname #can't use super because Sphinx/docutils has trouble #return super(Autosummary,self).run() nodelist.extend(Autosummary.run(self)) return self.warnings + nodelist finally: # has_content = False for the Automodsumm self.content = [] #<-------------------automod-diagram stuff------------------------------------> class Automoddiagram(InheritanceDiagram): option_spec = dict(InheritanceDiagram.option_spec) option_spec['allowed-package-names'] = _str_list_converter def run(self): try: ols = self.options.get('allowed-package-names', []) ols = True if len(ols) == 0 else ols # if none are given, assume only local nms, objs = find_mod_objs(self.arguments[0], onlylocals=ols)[1:] except ImportError: self.warnings = [] self.warn("Couldn't import module " + self.arguments[0]) return self.warnings clsnms = [] for n, o in zip(nms, objs): if inspect.isclass(o): clsnms.append(n) oldargs = self.arguments try: if len(clsnms) > 0: self.arguments = [' '.join(clsnms).decode('utf-8')] return InheritanceDiagram.run(self) finally: self.arguments = oldargs #<---------------------automodsumm generation stuff---------------------------> def process_automodsumm_generation(app): env = app.builder.env ext = app.config.source_suffix filestosearch = [x + ext for x in env.found_docs if os.path.isfile(env.doc2path(x))]\ liness = [] for sfn in filestosearch: lines = automodsumm_to_autosummary_lines(sfn, app) liness.append(lines) if app.config.automodsumm_writereprocessed: if lines: # empty list means no automodsumm entry is in the file outfn = os.path.join(app.srcdir, sfn) + '.automodsumm' with open(outfn, 'w') as f: for l in lines: f.write(l) f.write('\n') for sfn, lines in zip(filestosearch, liness): if len(lines) > 0: generate_automodsumm_docs(lines, sfn, builder=app.builder, warn=app.warn, info=app.info, suffix=app.config.source_suffix, base_path=app.srcdir) #_automodsummrex = re.compile(r'^(\s*)\.\. automodsumm::\s*([A-Za-z0-9_.]+)\s*' # r'\n\1(\s*)(\S|$)', re.MULTILINE) _lineendrex = r'(?:\n|$)' _hdrex = r'^\n?(\s*)\.\. automodsumm::\s*(\S+)\s*' + _lineendrex _oprex1 = r'(?:\1(\s+)\S.*' + _lineendrex + ')' _oprex2 = r'(?:\1\4\S.*' + _lineendrex + ')' _automodsummrex = re.compile(_hdrex + '(' + _oprex1 + '?' + _oprex2 + '*)', re.MULTILINE) def automodsumm_to_autosummary_lines(fn, app): """ Generates lines from a file with an "automodsumm" entry suitable for feeding into "autosummary". Searches the provided file for `automodsumm` directives and returns a list of lines specifying the `autosummary` commands for the modules requested. This does *not* return the whole file contents - just an autosummary section in place of any :automodsumm: entries. Note that any options given for `automodsumm` are also included in the generated `autosummary` section. Parameters ---------- fn : str The name of the file to search for `automodsumm` entries. app : sphinx.application.Application The sphinx Application object Return ------ lines : list of str Lines for all `automodsumm` entries with the entries replaced by `autosummary` and the module's members added. """ fullfn = os.path.join(app.builder.env.srcdir, fn) with open(fullfn) as fr: if 'astropy_helpers.sphinx.ext.automodapi' in app._extensions: from astropy_helpers.sphinx.ext.automodapi import automodapi_replace # Must do the automodapi on the source to get the automodsumm # that might be in there filestr = automodapi_replace(fr.read(), app, True, fn, False) else: filestr = fr.read() spl = _automodsummrex.split(filestr) #0th entry is the stuff before the first automodsumm line indent1s = spl[1::5] mods = spl[2::5] opssecs = spl[3::5] indent2s = spl[4::5] remainders = spl[5::5] # only grab automodsumm sections and convert them to autosummary with the # entries for all the public objects newlines = [] #loop over all automodsumms in this document for i, (i1, i2, modnm, ops, rem) in enumerate(zip(indent1s, indent2s, mods, opssecs, remainders)): allindent = i1 + ('' if i2 is None else i2) #filter out functions-only and classes-only options if present oplines = ops.split('\n') toskip = [] allowedpkgnms = [] funcsonly = clssonly = False for i, ln in reversed(list(enumerate(oplines))): if ':functions-only:' in ln: funcsonly = True del oplines[i] if ':classes-only:' in ln: clssonly = True del oplines[i] if ':skip:' in ln: toskip.extend(_str_list_converter(ln.replace(':skip:', ''))) del oplines[i] if ':allowed-package-names:' in ln: allowedpkgnms.extend(_str_list_converter(ln.replace(':allowed-package-names:', ''))) del oplines[i] if funcsonly and clssonly: msg = ('Defined both functions-only and classes-only options. ' 'Skipping this directive.') lnnum = sum([spl[j].count('\n') for j in range(i * 5 + 1)]) app.warn('[automodsumm]' + msg, (fn, lnnum)) continue # Use the currentmodule directive so we can just put the local names # in the autosummary table. Note that this doesn't always seem to # actually "take" in Sphinx's eyes, so in `Automodsumm.run`, we have to # force it internally, as well. newlines.extend([i1 + '.. currentmodule:: ' + modnm, '', '.. autosummary::']) newlines.extend(oplines) ols = True if len(allowedpkgnms) == 0 else allowedpkgnms for nm, fqn, obj in zip(*find_mod_objs(modnm, onlylocals=ols)): if nm in toskip: continue if funcsonly and not inspect.isroutine(obj): continue if clssonly and not inspect.isclass(obj): continue newlines.append(allindent + nm) return newlines def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None, info=None, base_path=None, builder=None, template_dir=None): """ This function is adapted from `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to generate source for the automodsumm directives that should be autosummarized. Unlike generate_autosummary_docs, this function is called one file at a time. """ from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.ext.autosummary import import_by_name, get_documenter from sphinx.ext.autosummary.generate import (find_autosummary_in_lines, _simple_info, _simple_warn) from sphinx.util.osutil import ensuredir from sphinx.util.inspect import safe_getattr from jinja2 import FileSystemLoader, TemplateNotFound from jinja2.sandbox import SandboxedEnvironment if info is None: info = _simple_info if warn is None: warn = _simple_warn #info('[automodsumm] generating automodsumm for: ' + srcfn) # Create our own templating environment - here we use Astropy's # templates rather than the default autosummary templates, in order to # allow docstrings to be shown for methods. template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'), os.path.join(base_path, '_templates')] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read #items = find_autosummary_in_files(sources) items = find_autosummary_in_lines(lines, filename=srcfn) if len(items) > 0: msg = '[automodsumm] {1}: found {0} automodsumm entries to generate' info(msg.format(len(items), srcfn)) # gennms = [item[0] for item in items] # if len(gennms) > 20: # gennms = gennms[:10] + ['...'] + gennms[-10:] # info('[automodsumm] generating autosummary for: ' + ', '.join(gennms)) # remove possible duplicates items = dict([(item, True) for item in items]).keys() # keep track of new files new_files = [] # write for name, path, template_name in sorted(items): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = os.path.abspath(path) ensuredir(path) try: import_by_name_values = import_by_name(name) except ImportError as e: warn('[automodsumm] failed to import %r: %s' % (name, e)) continue # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively if len(import_by_name_values) == 3: name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: name, obj, parent, module_name = import_by_name_values fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) f = open(fn, 'w') try: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: tmplstr = 'autosummary/%s.rst' try: template = template_env.get_template(tmplstr % doc.objtype) except TemplateNotFound: template = template_env.get_template(tmplstr % 'base') def get_members_mod(obj, typ, include_public=[]): """ typ = None -> all """ items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class """ items = [] # using dir gets all of the attributes, including the elements # from the base class, otherwise use __slots__ or __dict__ if include_base: names = dir(obj) else: if hasattr(obj, '__slots__'): names = tuple(getattr(obj, '__slots__')) else: names = getattr(obj, '__dict__').keys() for name in names: try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} if doc.objtype == 'module': ns['members'] = get_members_mod(obj, None) ns['functions'], ns['all_functions'] = \ get_members_mod(obj, 'function') ns['classes'], ns['all_classes'] = \ get_members_mod(obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members_mod(obj, 'exception') elif doc.objtype == 'class': api_class_methods = ['__init__', '__call__'] ns['members'] = get_members_class(obj, None) ns['methods'], ns['all_methods'] = \ get_members_class(obj, 'method', api_class_methods) ns['attributes'], ns['all_attributes'] = \ get_members_class(obj, 'attribute') ns['methods'].sort() ns['attributes'].sort() parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' # We now check whether a file for reference footnotes exists for # the module being documented. We first check if the # current module is a file or a directory, as this will give a # different path for the reference file. For example, if # documenting astropy.wcs then the reference file is at # ../wcs/references.txt, while if we are documenting # astropy.config.logging_helper (which is at # astropy/config/logging_helper.py) then the reference file is set # to ../config/references.txt if '.' in mod_name: mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1] else: mod_name_dir = mod_name if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \ and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])): mod_name_dir = mod_name_dir.rsplit('/', 1)[0] # We then have to check whether it exists, and if so, we pass it # to the template. if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')): # An important subtlety here is that the path we pass in has # to be relative to the file being generated, so we have to # figure out the right number of '..'s ndirsback = path.replace(base_path, '').count('/') ref_file_rel_segments = ['..'] * ndirsback ref_file_rel_segments.append(mod_name_dir) ref_file_rel_segments.append('references.txt') ns['referencefile'] = os.path.join(*ref_file_rel_segments) rendered = template.render(**ns) f.write(rendered) finally: f.close() def setup(app): # need our autosummary app.setup_extension('astropy_helpers.sphinx.ext.astropyautosummary') # need inheritance-diagram for automod-diagram app.setup_extension('sphinx.ext.inheritance_diagram') app.add_directive('automod-diagram', Automoddiagram) app.add_directive('automodsumm', Automodsumm) app.connect('builder-inited', process_automodsumm_generation) app.add_config_value('automodsumm_writereprocessed', False, True) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/changelog_links.py0000644000077000000240000000542012403272746030244 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension makes the issue numbers in the changelog into links to GitHub issues. """ from __future__ import print_function import re from docutils.nodes import Text, reference BLOCK_PATTERN = re.compile('\[#.+\]', flags=re.DOTALL) ISSUE_PATTERN = re.compile('#[0-9]+') def process_changelog_links(app, doctree, docname): for rex in app.changelog_links_rexes: if rex.match(docname): break else: # if the doc doesn't match any of the changelog regexes, don't process return app.info('[changelog_links] Adding changelog links to "{0}"'.format(docname)) for item in doctree.traverse(): if not isinstance(item, Text): continue # We build a new list of items to replace the current item. If # a link is found, we need to use a 'reference' item. children = [] # First cycle through blocks of issues (delimited by []) then # iterate inside each one to find the individual issues. prev_block_end = 0 for block in BLOCK_PATTERN.finditer(item): block_start, block_end = block.start(), block.end() children.append(Text(item[prev_block_end:block_start])) block = item[block_start:block_end] prev_end = 0 for m in ISSUE_PATTERN.finditer(block): start, end = m.start(), m.end() children.append(Text(block[prev_end:start])) issue_number = block[start:end] refuri = app.config.github_issues_url + issue_number[1:] children.append(reference(text=issue_number, name=issue_number, refuri=refuri)) prev_end = end prev_block_end = block_end # If no issues were found, this adds the whole item, # otherwise it adds the remaining text. children.append(Text(block[prev_end:block_end])) # If no blocks were found, this adds the whole item, otherwise # it adds the remaining text. children.append(Text(item[prev_block_end:])) # Replace item by the new list of items we have generated, # which may contain links. item.parent.replace(item, children) def setup_patterns_rexes(app): app.changelog_links_rexes = [re.compile(pat) for pat in app.config.changelog_links_docpattern] def setup(app): app.connect('doctree-resolved', process_changelog_links) app.connect('builder-inited', setup_patterns_rexes) app.add_config_value('github_issues_url', None, True) app.add_config_value('changelog_links_docpattern', ['.*changelog.*', 'whatsnew/.*'], True) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/comment_eater.py0000644000077000000240000001245112354456432027742 0ustar adamstaff00000000000000from __future__ import division, absolute_import, print_function import sys if sys.version_info[0] >= 3: from io import StringIO else: from io import StringIO import compiler import inspect import textwrap import tokenize from .compiler_unparse import unparse class Comment(object): """ A comment block. """ is_comment = True def __init__(self, start_lineno, end_lineno, text): # int : The first line number in the block. 1-indexed. self.start_lineno = start_lineno # int : The last line number. Inclusive! self.end_lineno = end_lineno # str : The text block including '#' character but not any leading spaces. self.text = text def add(self, string, start, end, line): """ Add a new comment line. """ self.start_lineno = min(self.start_lineno, start[0]) self.end_lineno = max(self.end_lineno, end[0]) self.text += string def __repr__(self): return '%s(%r, %r, %r)' % (self.__class__.__name__, self.start_lineno, self.end_lineno, self.text) class NonComment(object): """ A non-comment block of code. """ is_comment = False def __init__(self, start_lineno, end_lineno): self.start_lineno = start_lineno self.end_lineno = end_lineno def add(self, string, start, end, line): """ Add lines to the block. """ if string.strip(): # Only add if not entirely whitespace. self.start_lineno = min(self.start_lineno, start[0]) self.end_lineno = max(self.end_lineno, end[0]) def __repr__(self): return '%s(%r, %r)' % (self.__class__.__name__, self.start_lineno, self.end_lineno) class CommentBlocker(object): """ Pull out contiguous comment blocks. """ def __init__(self): # Start with a dummy. self.current_block = NonComment(0, 0) # All of the blocks seen so far. self.blocks = [] # The index mapping lines of code to their associated comment blocks. self.index = {} def process_file(self, file): """ Process a file object. """ if sys.version_info[0] >= 3: nxt = file.__next__ else: nxt = file.next for token in tokenize.generate_tokens(nxt): self.process_token(*token) self.make_index() def process_token(self, kind, string, start, end, line): """ Process a single token. """ if self.current_block.is_comment: if kind == tokenize.COMMENT: self.current_block.add(string, start, end, line) else: self.new_noncomment(start[0], end[0]) else: if kind == tokenize.COMMENT: self.new_comment(string, start, end, line) else: self.current_block.add(string, start, end, line) def new_noncomment(self, start_lineno, end_lineno): """ We are transitioning from a noncomment to a comment. """ block = NonComment(start_lineno, end_lineno) self.blocks.append(block) self.current_block = block def new_comment(self, string, start, end, line): """ Possibly add a new comment. Only adds a new comment if this comment is the only thing on the line. Otherwise, it extends the noncomment block. """ prefix = line[:start[1]] if prefix.strip(): # Oops! Trailing comment, not a comment block. self.current_block.add(string, start, end, line) else: # A comment block. block = Comment(start[0], end[0], string) self.blocks.append(block) self.current_block = block def make_index(self): """ Make the index mapping lines of actual code to their associated prefix comments. """ for prev, block in zip(self.blocks[:-1], self.blocks[1:]): if not block.is_comment: self.index[block.start_lineno] = prev def search_for_comment(self, lineno, default=None): """ Find the comment block just before the given line number. Returns None (or the specified default) if there is no such block. """ if not self.index: self.make_index() block = self.index.get(lineno, None) text = getattr(block, 'text', default) return text def strip_comment_marker(text): """ Strip # markers at the front of a block of comment text. """ lines = [] for line in text.splitlines(): lines.append(line.lstrip('#')) text = textwrap.dedent('\n'.join(lines)) return text def get_class_traits(klass): """ Yield all of the documentation for trait definitions on a class object. """ # FIXME: gracefully handle errors here or in the caller? source = inspect.getsource(klass) cb = CommentBlocker() cb.process_file(StringIO(source)) mod_ast = compiler.parse(source) class_ast = mod_ast.node.nodes[0] for node in class_ast.code.nodes: # FIXME: handle other kinds of assignments? if isinstance(node, compiler.ast.Assign): name = node.nodes[0].name rhs = unparse(node.expr).strip() doc = strip_comment_marker(cb.search_for_comment(node.lineno, default='')) yield name, rhs, doc astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/compiler_unparse.py0000644000077000000240000006024412354456432030472 0ustar adamstaff00000000000000""" Turn compiler.ast structures back into executable python code. The unparse method takes a compiler.ast tree and transforms it back into valid python code. It is incomplete and currently only works for import statements, function calls, function definitions, assignments, and basic expressions. Inspired by python-2.5-svn/Demo/parser/unparse.py fixme: We may want to move to using _ast trees because the compiler for them is about 6 times faster than compiler.compile. """ from __future__ import division, absolute_import, print_function import sys from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add if sys.version_info[0] >= 3: from io import StringIO else: from StringIO import StringIO def unparse(ast, single_line_functions=False): s = StringIO() UnparseCompilerAst(ast, s, single_line_functions) return s.getvalue().lstrip() op_precedence = { 'compiler.ast.Power':3, 'compiler.ast.Mul':2, 'compiler.ast.Div':2, 'compiler.ast.Add':1, 'compiler.ast.Sub':1 } class UnparseCompilerAst: """ Methods in this class recursively traverse an AST and output source code for the abstract syntax; original formatting is disregarged. """ ######################################################################### # object interface. ######################################################################### def __init__(self, tree, file = sys.stdout, single_line_functions=False): """ Unparser(tree, file=sys.stdout) -> None. Print the source for tree to file. """ self.f = file self._single_func = single_line_functions self._do_indent = True self._indent = 0 self._dispatch(tree) self._write("\n") self.f.flush() ######################################################################### # Unparser private interface. ######################################################################### ### format, output, and dispatch methods ################################ def _fill(self, text = ""): "Indent a piece of text, according to the current indentation level" if self._do_indent: self._write("\n"+" "*self._indent + text) else: self._write(text) def _write(self, text): "Append a piece of text to the current line." self.f.write(text) def _enter(self): "Print ':', and increase the indentation." self._write(": ") self._indent += 1 def _leave(self): "Decrease the indentation level." self._indent -= 1 def _dispatch(self, tree): "_dispatcher function, _dispatching tree type T to method _T." if isinstance(tree, list): for t in tree: self._dispatch(t) return meth = getattr(self, "_"+tree.__class__.__name__) if tree.__class__.__name__ == 'NoneType' and not self._do_indent: return meth(tree) ######################################################################### # compiler.ast unparsing methods. # # There should be one method per concrete grammar type. They are # organized in alphabetical order. ######################################################################### def _Add(self, t): self.__binary_op(t, '+') def _And(self, t): self._write(" (") for i, node in enumerate(t.nodes): self._dispatch(node) if i != len(t.nodes)-1: self._write(") and (") self._write(")") def _AssAttr(self, t): """ Handle assigning an attribute of an object """ self._dispatch(t.expr) self._write('.'+t.attrname) def _Assign(self, t): """ Expression Assignment such as "a = 1". This only handles assignment in expressions. Keyword assignment is handled separately. """ self._fill() for target in t.nodes: self._dispatch(target) self._write(" = ") self._dispatch(t.expr) if not self._do_indent: self._write('; ') def _AssName(self, t): """ Name on left hand side of expression. Treat just like a name on the right side of an expression. """ self._Name(t) def _AssTuple(self, t): """ Tuple on left hand side of an expression. """ # _write each elements, separated by a comma. for element in t.nodes[:-1]: self._dispatch(element) self._write(", ") # Handle the last one without writing comma last_element = t.nodes[-1] self._dispatch(last_element) def _AugAssign(self, t): """ +=,-=,*=,/=,**=, etc. operations """ self._fill() self._dispatch(t.node) self._write(' '+t.op+' ') self._dispatch(t.expr) if not self._do_indent: self._write(';') def _Bitand(self, t): """ Bit and operation. """ for i, node in enumerate(t.nodes): self._write("(") self._dispatch(node) self._write(")") if i != len(t.nodes)-1: self._write(" & ") def _Bitor(self, t): """ Bit or operation """ for i, node in enumerate(t.nodes): self._write("(") self._dispatch(node) self._write(")") if i != len(t.nodes)-1: self._write(" | ") def _CallFunc(self, t): """ Function call. """ self._dispatch(t.node) self._write("(") comma = False for e in t.args: if comma: self._write(", ") else: comma = True self._dispatch(e) if t.star_args: if comma: self._write(", ") else: comma = True self._write("*") self._dispatch(t.star_args) if t.dstar_args: if comma: self._write(", ") else: comma = True self._write("**") self._dispatch(t.dstar_args) self._write(")") def _Compare(self, t): self._dispatch(t.expr) for op, expr in t.ops: self._write(" " + op + " ") self._dispatch(expr) def _Const(self, t): """ A constant value such as an integer value, 3, or a string, "hello". """ self._dispatch(t.value) def _Decorators(self, t): """ Handle function decorators (eg. @has_units) """ for node in t.nodes: self._dispatch(node) def _Dict(self, t): self._write("{") for i, (k, v) in enumerate(t.items): self._dispatch(k) self._write(": ") self._dispatch(v) if i < len(t.items)-1: self._write(", ") self._write("}") def _Discard(self, t): """ Node for when return value is ignored such as in "foo(a)". """ self._fill() self._dispatch(t.expr) def _Div(self, t): self.__binary_op(t, '/') def _Ellipsis(self, t): self._write("...") def _From(self, t): """ Handle "from xyz import foo, bar as baz". """ # fixme: Are From and ImportFrom handled differently? self._fill("from ") self._write(t.modname) self._write(" import ") for i, (name,asname) in enumerate(t.names): if i != 0: self._write(", ") self._write(name) if asname is not None: self._write(" as "+asname) def _Function(self, t): """ Handle function definitions """ if t.decorators is not None: self._fill("@") self._dispatch(t.decorators) self._fill("def "+t.name + "(") defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults) for i, arg in enumerate(zip(t.argnames, defaults)): self._write(arg[0]) if arg[1] is not None: self._write('=') self._dispatch(arg[1]) if i < len(t.argnames)-1: self._write(', ') self._write(")") if self._single_func: self._do_indent = False self._enter() self._dispatch(t.code) self._leave() self._do_indent = True def _Getattr(self, t): """ Handle getting an attribute of an object """ if isinstance(t.expr, (Div, Mul, Sub, Add)): self._write('(') self._dispatch(t.expr) self._write(')') else: self._dispatch(t.expr) self._write('.'+t.attrname) def _If(self, t): self._fill() for i, (compare,code) in enumerate(t.tests): if i == 0: self._write("if ") else: self._write("elif ") self._dispatch(compare) self._enter() self._fill() self._dispatch(code) self._leave() self._write("\n") if t.else_ is not None: self._write("else") self._enter() self._fill() self._dispatch(t.else_) self._leave() self._write("\n") def _IfExp(self, t): self._dispatch(t.then) self._write(" if ") self._dispatch(t.test) if t.else_ is not None: self._write(" else (") self._dispatch(t.else_) self._write(")") def _Import(self, t): """ Handle "import xyz.foo". """ self._fill("import ") for i, (name,asname) in enumerate(t.names): if i != 0: self._write(", ") self._write(name) if asname is not None: self._write(" as "+asname) def _Keyword(self, t): """ Keyword value assignment within function calls and definitions. """ self._write(t.name) self._write("=") self._dispatch(t.expr) def _List(self, t): self._write("[") for i,node in enumerate(t.nodes): self._dispatch(node) if i < len(t.nodes)-1: self._write(", ") self._write("]") def _Module(self, t): if t.doc is not None: self._dispatch(t.doc) self._dispatch(t.node) def _Mul(self, t): self.__binary_op(t, '*') def _Name(self, t): self._write(t.name) def _NoneType(self, t): self._write("None") def _Not(self, t): self._write('not (') self._dispatch(t.expr) self._write(')') def _Or(self, t): self._write(" (") for i, node in enumerate(t.nodes): self._dispatch(node) if i != len(t.nodes)-1: self._write(") or (") self._write(")") def _Pass(self, t): self._write("pass\n") def _Printnl(self, t): self._fill("print ") if t.dest: self._write(">> ") self._dispatch(t.dest) self._write(", ") comma = False for node in t.nodes: if comma: self._write(', ') else: comma = True self._dispatch(node) def _Power(self, t): self.__binary_op(t, '**') def _Return(self, t): self._fill("return ") if t.value: if isinstance(t.value, Tuple): text = ', '.join([ name.name for name in t.value.asList() ]) self._write(text) else: self._dispatch(t.value) if not self._do_indent: self._write('; ') def _Slice(self, t): self._dispatch(t.expr) self._write("[") if t.lower: self._dispatch(t.lower) self._write(":") if t.upper: self._dispatch(t.upper) #if t.step: # self._write(":") # self._dispatch(t.step) self._write("]") def _Sliceobj(self, t): for i, node in enumerate(t.nodes): if i != 0: self._write(":") if not (isinstance(node, Const) and node.value is None): self._dispatch(node) def _Stmt(self, tree): for node in tree.nodes: self._dispatch(node) def _Sub(self, t): self.__binary_op(t, '-') def _Subscript(self, t): self._dispatch(t.expr) self._write("[") for i, value in enumerate(t.subs): if i != 0: self._write(",") self._dispatch(value) self._write("]") def _TryExcept(self, t): self._fill("try") self._enter() self._dispatch(t.body) self._leave() for handler in t.handlers: self._fill('except ') self._dispatch(handler[0]) if handler[1] is not None: self._write(', ') self._dispatch(handler[1]) self._enter() self._dispatch(handler[2]) self._leave() if t.else_: self._fill("else") self._enter() self._dispatch(t.else_) self._leave() def _Tuple(self, t): if not t.nodes: # Empty tuple. self._write("()") else: self._write("(") # _write each elements, separated by a comma. for element in t.nodes[:-1]: self._dispatch(element) self._write(", ") # Handle the last one without writing comma last_element = t.nodes[-1] self._dispatch(last_element) self._write(")") def _UnaryAdd(self, t): self._write("+") self._dispatch(t.expr) def _UnarySub(self, t): self._write("-") self._dispatch(t.expr) def _With(self, t): self._fill('with ') self._dispatch(t.expr) if t.vars: self._write(' as ') self._dispatch(t.vars.name) self._enter() self._dispatch(t.body) self._leave() self._write('\n') def _int(self, t): self._write(repr(t)) def __binary_op(self, t, symbol): # Check if parenthesis are needed on left side and then dispatch has_paren = False left_class = str(t.left.__class__) if (left_class in op_precedence.keys() and op_precedence[left_class] < op_precedence[str(t.__class__)]): has_paren = True if has_paren: self._write('(') self._dispatch(t.left) if has_paren: self._write(')') # Write the appropriate symbol for operator self._write(symbol) # Check if parenthesis are needed on the right side and then dispatch has_paren = False right_class = str(t.right.__class__) if (right_class in op_precedence.keys() and op_precedence[right_class] < op_precedence[str(t.__class__)]): has_paren = True if has_paren: self._write('(') self._dispatch(t.right) if has_paren: self._write(')') def _float(self, t): # if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001' # We prefer str here. self._write(str(t)) def _str(self, t): self._write(repr(t)) def _tuple(self, t): self._write(str(t)) ######################################################################### # These are the methods from the _ast modules unparse. # # As our needs to handle more advanced code increase, we may want to # modify some of the methods below so that they work for compiler.ast. ######################################################################### # # stmt # def _Expr(self, tree): # self._fill() # self._dispatch(tree.value) # # def _Import(self, t): # self._fill("import ") # first = True # for a in t.names: # if first: # first = False # else: # self._write(", ") # self._write(a.name) # if a.asname: # self._write(" as "+a.asname) # ## def _ImportFrom(self, t): ## self._fill("from ") ## self._write(t.module) ## self._write(" import ") ## for i, a in enumerate(t.names): ## if i == 0: ## self._write(", ") ## self._write(a.name) ## if a.asname: ## self._write(" as "+a.asname) ## # XXX(jpe) what is level for? ## # # def _Break(self, t): # self._fill("break") # # def _Continue(self, t): # self._fill("continue") # # def _Delete(self, t): # self._fill("del ") # self._dispatch(t.targets) # # def _Assert(self, t): # self._fill("assert ") # self._dispatch(t.test) # if t.msg: # self._write(", ") # self._dispatch(t.msg) # # def _Exec(self, t): # self._fill("exec ") # self._dispatch(t.body) # if t.globals: # self._write(" in ") # self._dispatch(t.globals) # if t.locals: # self._write(", ") # self._dispatch(t.locals) # # def _Print(self, t): # self._fill("print ") # do_comma = False # if t.dest: # self._write(">>") # self._dispatch(t.dest) # do_comma = True # for e in t.values: # if do_comma:self._write(", ") # else:do_comma=True # self._dispatch(e) # if not t.nl: # self._write(",") # # def _Global(self, t): # self._fill("global") # for i, n in enumerate(t.names): # if i != 0: # self._write(",") # self._write(" " + n) # # def _Yield(self, t): # self._fill("yield") # if t.value: # self._write(" (") # self._dispatch(t.value) # self._write(")") # # def _Raise(self, t): # self._fill('raise ') # if t.type: # self._dispatch(t.type) # if t.inst: # self._write(", ") # self._dispatch(t.inst) # if t.tback: # self._write(", ") # self._dispatch(t.tback) # # # def _TryFinally(self, t): # self._fill("try") # self._enter() # self._dispatch(t.body) # self._leave() # # self._fill("finally") # self._enter() # self._dispatch(t.finalbody) # self._leave() # # def _excepthandler(self, t): # self._fill("except ") # if t.type: # self._dispatch(t.type) # if t.name: # self._write(", ") # self._dispatch(t.name) # self._enter() # self._dispatch(t.body) # self._leave() # # def _ClassDef(self, t): # self._write("\n") # self._fill("class "+t.name) # if t.bases: # self._write("(") # for a in t.bases: # self._dispatch(a) # self._write(", ") # self._write(")") # self._enter() # self._dispatch(t.body) # self._leave() # # def _FunctionDef(self, t): # self._write("\n") # for deco in t.decorators: # self._fill("@") # self._dispatch(deco) # self._fill("def "+t.name + "(") # self._dispatch(t.args) # self._write(")") # self._enter() # self._dispatch(t.body) # self._leave() # # def _For(self, t): # self._fill("for ") # self._dispatch(t.target) # self._write(" in ") # self._dispatch(t.iter) # self._enter() # self._dispatch(t.body) # self._leave() # if t.orelse: # self._fill("else") # self._enter() # self._dispatch(t.orelse) # self._leave # # def _While(self, t): # self._fill("while ") # self._dispatch(t.test) # self._enter() # self._dispatch(t.body) # self._leave() # if t.orelse: # self._fill("else") # self._enter() # self._dispatch(t.orelse) # self._leave # # # expr # def _Str(self, tree): # self._write(repr(tree.s)) ## # def _Repr(self, t): # self._write("`") # self._dispatch(t.value) # self._write("`") # # def _Num(self, t): # self._write(repr(t.n)) # # def _ListComp(self, t): # self._write("[") # self._dispatch(t.elt) # for gen in t.generators: # self._dispatch(gen) # self._write("]") # # def _GeneratorExp(self, t): # self._write("(") # self._dispatch(t.elt) # for gen in t.generators: # self._dispatch(gen) # self._write(")") # # def _comprehension(self, t): # self._write(" for ") # self._dispatch(t.target) # self._write(" in ") # self._dispatch(t.iter) # for if_clause in t.ifs: # self._write(" if ") # self._dispatch(if_clause) # # def _IfExp(self, t): # self._dispatch(t.body) # self._write(" if ") # self._dispatch(t.test) # if t.orelse: # self._write(" else ") # self._dispatch(t.orelse) # # unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} # def _UnaryOp(self, t): # self._write(self.unop[t.op.__class__.__name__]) # self._write("(") # self._dispatch(t.operand) # self._write(")") # # binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%", # "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&", # "FloorDiv":"//", "Pow": "**"} # def _BinOp(self, t): # self._write("(") # self._dispatch(t.left) # self._write(")" + self.binop[t.op.__class__.__name__] + "(") # self._dispatch(t.right) # self._write(")") # # boolops = {_ast.And: 'and', _ast.Or: 'or'} # def _BoolOp(self, t): # self._write("(") # self._dispatch(t.values[0]) # for v in t.values[1:]: # self._write(" %s " % self.boolops[t.op.__class__]) # self._dispatch(v) # self._write(")") # # def _Attribute(self,t): # self._dispatch(t.value) # self._write(".") # self._write(t.attr) # ## def _Call(self, t): ## self._dispatch(t.func) ## self._write("(") ## comma = False ## for e in t.args: ## if comma: self._write(", ") ## else: comma = True ## self._dispatch(e) ## for e in t.keywords: ## if comma: self._write(", ") ## else: comma = True ## self._dispatch(e) ## if t.starargs: ## if comma: self._write(", ") ## else: comma = True ## self._write("*") ## self._dispatch(t.starargs) ## if t.kwargs: ## if comma: self._write(", ") ## else: comma = True ## self._write("**") ## self._dispatch(t.kwargs) ## self._write(")") # # # slice # def _Index(self, t): # self._dispatch(t.value) # # def _ExtSlice(self, t): # for i, d in enumerate(t.dims): # if i != 0: # self._write(': ') # self._dispatch(d) # # # others # def _arguments(self, t): # first = True # nonDef = len(t.args)-len(t.defaults) # for a in t.args[0:nonDef]: # if first:first = False # else: self._write(", ") # self._dispatch(a) # for a,d in zip(t.args[nonDef:], t.defaults): # if first:first = False # else: self._write(", ") # self._dispatch(a), # self._write("=") # self._dispatch(d) # if t.vararg: # if first:first = False # else: self._write(", ") # self._write("*"+t.vararg) # if t.kwarg: # if first:first = False # else: self._write(", ") # self._write("**"+t.kwarg) # ## def _keyword(self, t): ## self._write(t.arg) ## self._write("=") ## self._dispatch(t.value) # # def _Lambda(self, t): # self._write("lambda ") # self._dispatch(t.args) # self._write(": ") # self._dispatch(t.body) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/docscrape.py0000644000077000000240000003771312354456432027073 0ustar adamstaff00000000000000"""Extract reference documentation from the NumPy source tree. """ from __future__ import division, absolute_import, print_function import inspect import textwrap import re import pydoc from warnings import warn import collections import sys class Reader(object): """A line-based string reader. """ def __init__(self, data): """ Parameters ---------- data : str String with lines separated by '\n'. """ if isinstance(data,list): self._str = data else: self._str = data.split('\n') # store string as list of lines self.reset() def __getitem__(self, n): return self._str[n] def reset(self): self._l = 0 # current line nr def read(self): if not self.eof(): out = self[self._l] self._l += 1 return out else: return '' def seek_next_non_empty_line(self): for l in self[self._l:]: if l.strip(): break else: self._l += 1 def eof(self): return self._l >= len(self._str) def read_to_condition(self, condition_func): start = self._l for line in self[start:]: if condition_func(line): return self[start:self._l] self._l += 1 if self.eof(): return self[start:self._l+1] return [] def read_to_next_empty_line(self): self.seek_next_non_empty_line() def is_empty(line): return not line.strip() return self.read_to_condition(is_empty) def read_to_next_unindented_line(self): def is_unindented(line): return (line.strip() and (len(line.lstrip()) == len(line))) return self.read_to_condition(is_unindented) def peek(self,n=0): if self._l + n < len(self._str): return self[self._l + n] else: return '' def is_empty(self): return not ''.join(self._str).strip() class NumpyDocString(object): def __init__(self, docstring, config={}): docstring = textwrap.dedent(docstring).split('\n') self._doc = Reader(docstring) self._parsed_data = { 'Signature': '', 'Summary': [''], 'Extended Summary': [], 'Parameters': [], 'Returns': [], 'Raises': [], 'Warns': [], 'Other Parameters': [], 'Attributes': [], 'Methods': [], 'See Also': [], 'Notes': [], 'Warnings': [], 'References': '', 'Examples': '', 'index': {} } self._parse() def __getitem__(self,key): return self._parsed_data[key] def __setitem__(self,key,val): if key not in self._parsed_data: warn("Unknown section %s" % key) else: self._parsed_data[key] = val def _is_at_section(self): self._doc.seek_next_non_empty_line() if self._doc.eof(): return False l1 = self._doc.peek().strip() # e.g. Parameters if l1.startswith('.. index::'): return True l2 = self._doc.peek(1).strip() # ---------- or ========== return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1)) def _strip(self,doc): i = 0 j = 0 for i,line in enumerate(doc): if line.strip(): break for j,line in enumerate(doc[::-1]): if line.strip(): break return doc[i:len(doc)-j] def _read_to_next_section(self): section = self._doc.read_to_next_empty_line() while not self._is_at_section() and not self._doc.eof(): if not self._doc.peek(-1).strip(): # previous line was empty section += [''] section += self._doc.read_to_next_empty_line() return section def _read_sections(self): while not self._doc.eof(): data = self._read_to_next_section() name = data[0].strip() if name.startswith('..'): # index section yield name, data[1:] elif len(data) < 2: yield StopIteration else: yield name, self._strip(data[2:]) def _parse_param_list(self,content): r = Reader(content) params = [] while not r.eof(): header = r.read().strip() if ' : ' in header: arg_name, arg_type = header.split(' : ')[:2] else: arg_name, arg_type = header, '' desc = r.read_to_next_unindented_line() desc = dedent_lines(desc) params.append((arg_name,arg_type,desc)) return params _name_rgx = re.compile(r"^\s*(:(?P\w+):`(?P[a-zA-Z0-9_.-]+)`|" r" (?P[a-zA-Z0-9_.-]+))\s*", re.X) def _parse_see_also(self, content): """ func_name : Descriptive text continued text another_func_name : Descriptive text func_name1, func_name2, :meth:`func_name`, func_name3 """ items = [] def parse_item_name(text): """Match ':role:`name`' or 'name'""" m = self._name_rgx.match(text) if m: g = m.groups() if g[1] is None: return g[3], None else: return g[2], g[1] raise ValueError("%s is not a item name" % text) def push_item(name, rest): if not name: return name, role = parse_item_name(name) items.append((name, list(rest), role)) del rest[:] current_func = None rest = [] for line in content: if not line.strip(): continue m = self._name_rgx.match(line) if m and line[m.end():].strip().startswith(':'): push_item(current_func, rest) current_func, line = line[:m.end()], line[m.end():] rest = [line.split(':', 1)[1].strip()] if not rest[0]: rest = [] elif not line.startswith(' '): push_item(current_func, rest) current_func = None if ',' in line: for func in line.split(','): if func.strip(): push_item(func, []) elif line.strip(): current_func = line elif current_func is not None: rest.append(line.strip()) push_item(current_func, rest) return items def _parse_index(self, section, content): """ .. index: default :refguide: something, else, and more """ def strip_each_in(lst): return [s.strip() for s in lst] out = {} section = section.split('::') if len(section) > 1: out['default'] = strip_each_in(section[1].split(','))[0] for line in content: line = line.split(':') if len(line) > 2: out[line[1]] = strip_each_in(line[2].split(',')) return out def _parse_summary(self): """Grab signature (if given) and summary""" if self._is_at_section(): return # If several signatures present, take the last one while True: summary = self._doc.read_to_next_empty_line() summary_str = " ".join([s.strip() for s in summary]).strip() if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str): self['Signature'] = summary_str if not self._is_at_section(): continue break if summary is not None: self['Summary'] = summary if not self._is_at_section(): self['Extended Summary'] = self._read_to_next_section() def _parse(self): self._doc.reset() self._parse_summary() for (section,content) in self._read_sections(): if not section.startswith('..'): section = ' '.join([s.capitalize() for s in section.split(' ')]) if section in ('Parameters', 'Returns', 'Raises', 'Warns', 'Other Parameters', 'Attributes', 'Methods'): self[section] = self._parse_param_list(content) elif section.startswith('.. index::'): self['index'] = self._parse_index(section, content) elif section == 'See Also': self['See Also'] = self._parse_see_also(content) else: self[section] = content # string conversion routines def _str_header(self, name, symbol='-'): return [name, len(name)*symbol] def _str_indent(self, doc, indent=4): out = [] for line in doc: out += [' '*indent + line] return out def _str_signature(self): if self['Signature']: return [self['Signature'].replace('*','\*')] + [''] else: return [''] def _str_summary(self): if self['Summary']: return self['Summary'] + [''] else: return [] def _str_extended_summary(self): if self['Extended Summary']: return self['Extended Summary'] + [''] else: return [] def _str_param_list(self, name): out = [] if self[name]: out += self._str_header(name) for param,param_type,desc in self[name]: if param_type: out += ['%s : %s' % (param, param_type)] else: out += [param] out += self._str_indent(desc) out += [''] return out def _str_section(self, name): out = [] if self[name]: out += self._str_header(name) out += self[name] out += [''] return out def _str_see_also(self, func_role): if not self['See Also']: return [] out = [] out += self._str_header("See Also") last_had_desc = True for func, desc, role in self['See Also']: if role: link = ':%s:`%s`' % (role, func) elif func_role: link = ':%s:`%s`' % (func_role, func) else: link = "`%s`_" % func if desc or last_had_desc: out += [''] out += [link] else: out[-1] += ", %s" % link if desc: out += self._str_indent([' '.join(desc)]) last_had_desc = True else: last_had_desc = False out += [''] return out def _str_index(self): idx = self['index'] out = [] out += ['.. index:: %s' % idx.get('default','')] for section, references in idx.items(): if section == 'default': continue out += [' :%s: %s' % (section, ', '.join(references))] return out def __str__(self, func_role=''): out = [] out += self._str_signature() out += self._str_summary() out += self._str_extended_summary() for param_list in ('Parameters', 'Returns', 'Other Parameters', 'Raises', 'Warns'): out += self._str_param_list(param_list) out += self._str_section('Warnings') out += self._str_see_also(func_role) for s in ('Notes','References','Examples'): out += self._str_section(s) for param_list in ('Attributes', 'Methods'): out += self._str_param_list(param_list) out += self._str_index() return '\n'.join(out) def indent(str,indent=4): indent_str = ' '*indent if str is None: return indent_str lines = str.split('\n') return '\n'.join(indent_str + l for l in lines) def dedent_lines(lines): """Deindent a list of lines maximally""" return textwrap.dedent("\n".join(lines)).split("\n") def header(text, style='-'): return text + '\n' + style*len(text) + '\n' class FunctionDoc(NumpyDocString): def __init__(self, func, role='func', doc=None, config={}): self._f = func self._role = role # e.g. "func" or "meth" if doc is None: if func is None: raise ValueError("No function or docstring given") doc = inspect.getdoc(func) or '' NumpyDocString.__init__(self, doc) if not self['Signature'] and func is not None: func, func_name = self.get_func() try: # try to read signature if sys.version_info[0] >= 3: argspec = inspect.getfullargspec(func) else: argspec = inspect.getargspec(func) argspec = inspect.formatargspec(*argspec) argspec = argspec.replace('*','\*') signature = '%s%s' % (func_name, argspec) except TypeError as e: signature = '%s()' % func_name self['Signature'] = signature def get_func(self): func_name = getattr(self._f, '__name__', self.__class__.__name__) if inspect.isclass(self._f): func = getattr(self._f, '__call__', self._f.__init__) else: func = self._f return func, func_name def __str__(self): out = '' func, func_name = self.get_func() signature = self['Signature'].replace('*', '\*') roles = {'func': 'function', 'meth': 'method'} if self._role: if self._role not in roles: print("Warning: invalid role %s" % self._role) out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''), func_name) out += super(FunctionDoc, self).__str__(func_role=self._role) return out class ClassDoc(NumpyDocString): extra_public_methods = ['__call__'] def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc, config={}): if not inspect.isclass(cls) and cls is not None: raise ValueError("Expected a class or None, but got %r" % cls) self._cls = cls if modulename and not modulename.endswith('.'): modulename += '.' self._mod = modulename if doc is None: if cls is None: raise ValueError("No class or documentation string given") doc = pydoc.getdoc(cls) NumpyDocString.__init__(self, doc) if config.get('show_class_members', True): def splitlines_x(s): if not s: return [] else: return s.splitlines() for field, items in [('Methods', self.methods), ('Attributes', self.properties)]: if not self[field]: doc_list = [] for name in sorted(items): try: doc_item = pydoc.getdoc(getattr(self._cls, name)) doc_list.append((name, '', splitlines_x(doc_item))) except AttributeError: pass # method doesn't exist self[field] = doc_list @property def methods(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) if ((not name.startswith('_') or name in self.extra_public_methods) and isinstance(func, collections.Callable))] @property def properties(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) if not name.startswith('_') and (func is None or isinstance(func, property) or inspect.isgetsetdescriptor(func))] astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/docscrape_sphinx.py0000644000077000000240000002233512354456432030456 0ustar adamstaff00000000000000from __future__ import division, absolute_import, print_function import sys, re, inspect, textwrap, pydoc import sphinx import collections from .docscrape import NumpyDocString, FunctionDoc, ClassDoc if sys.version_info[0] >= 3: sixu = lambda s: s else: sixu = lambda s: unicode(s, 'unicode_escape') class SphinxDocString(NumpyDocString): def __init__(self, docstring, config={}): NumpyDocString.__init__(self, docstring, config=config) self.load_config(config) def load_config(self, config): self.use_plots = config.get('use_plots', False) self.class_members_toctree = config.get('class_members_toctree', True) # string conversion routines def _str_header(self, name, symbol='`'): return ['.. rubric:: ' + name, ''] def _str_field_list(self, name): return [':' + name + ':'] def _str_indent(self, doc, indent=4): out = [] for line in doc: out += [' '*indent + line] return out def _str_signature(self): return [''] if self['Signature']: return ['``%s``' % self['Signature']] + [''] else: return [''] def _str_summary(self): return self['Summary'] + [''] def _str_extended_summary(self): return self['Extended Summary'] + [''] def _str_returns(self): out = [] if self['Returns']: out += self._str_field_list('Returns') out += [''] for param, param_type, desc in self['Returns']: if param_type: out += self._str_indent(['**%s** : %s' % (param.strip(), param_type)]) else: out += self._str_indent([param.strip()]) if desc: out += [''] out += self._str_indent(desc, 8) out += [''] return out def _str_param_list(self, name): out = [] if self[name]: out += self._str_field_list(name) out += [''] for param, param_type, desc in self[name]: if param_type: out += self._str_indent(['**%s** : %s' % (param.strip(), param_type)]) else: out += self._str_indent(['**%s**' % param.strip()]) if desc: out += [''] out += self._str_indent(desc, 8) out += [''] return out @property def _obj(self): if hasattr(self, '_cls'): return self._cls elif hasattr(self, '_f'): return self._f return None def _str_member_list(self, name): """ Generate a member listing, autosummary:: table where possible, and a table where not. """ out = [] if self[name]: out += ['.. rubric:: %s' % name, ''] prefix = getattr(self, '_name', '') if prefix: prefix = '~%s.' % prefix autosum = [] others = [] for param, param_type, desc in self[name]: param = param.strip() # Check if the referenced member can have a docstring or not param_obj = getattr(self._obj, param, None) if not (callable(param_obj) or isinstance(param_obj, property) or inspect.isgetsetdescriptor(param_obj)): param_obj = None if param_obj and (pydoc.getdoc(param_obj) or not desc): # Referenced object has a docstring autosum += [" %s%s" % (prefix, param)] else: others.append((param, param_type, desc)) if autosum: out += ['.. autosummary::'] if self.class_members_toctree: out += [' :toctree:'] out += [''] + autosum if others: maxlen_0 = max(3, max([len(x[0]) for x in others])) hdr = sixu("=")*maxlen_0 + sixu(" ") + sixu("=")*10 fmt = sixu('%%%ds %%s ') % (maxlen_0,) out += ['', hdr] for param, param_type, desc in others: desc = sixu(" ").join(x.strip() for x in desc).strip() if param_type: desc = "(%s) %s" % (param_type, desc) out += [fmt % (param.strip(), desc)] out += [hdr] out += [''] return out def _str_section(self, name): out = [] if self[name]: out += self._str_header(name) out += [''] content = textwrap.dedent("\n".join(self[name])).split("\n") out += content out += [''] return out def _str_see_also(self, func_role): out = [] if self['See Also']: see_also = super(SphinxDocString, self)._str_see_also(func_role) out = ['.. seealso::', ''] out += self._str_indent(see_also[2:]) return out def _str_warnings(self): out = [] if self['Warnings']: out = ['.. warning::', ''] out += self._str_indent(self['Warnings']) return out def _str_index(self): idx = self['index'] out = [] if len(idx) == 0: return out out += ['.. index:: %s' % idx.get('default','')] for section, references in idx.items(): if section == 'default': continue elif section == 'refguide': out += [' single: %s' % (', '.join(references))] else: out += [' %s: %s' % (section, ','.join(references))] return out def _str_references(self): out = [] if self['References']: out += self._str_header('References') if isinstance(self['References'], str): self['References'] = [self['References']] out.extend(self['References']) out += [''] # Latex collects all references to a separate bibliography, # so we need to insert links to it if sphinx.__version__ >= "0.6": out += ['.. only:: latex',''] else: out += ['.. latexonly::',''] items = [] for line in self['References']: m = re.match(r'.. \[([a-z0-9._-]+)\]', line, re.I) if m: items.append(m.group(1)) out += [' ' + ", ".join(["[%s]_" % item for item in items]), ''] return out def _str_examples(self): examples_str = "\n".join(self['Examples']) if (self.use_plots and 'import matplotlib' in examples_str and 'plot::' not in examples_str): out = [] out += self._str_header('Examples') out += ['.. plot::', ''] out += self._str_indent(self['Examples']) out += [''] return out else: return self._str_section('Examples') def __str__(self, indent=0, func_role="obj"): out = [] out += self._str_signature() out += self._str_index() + [''] out += self._str_summary() out += self._str_extended_summary() out += self._str_param_list('Parameters') out += self._str_returns() for param_list in ('Other Parameters', 'Raises', 'Warns'): out += self._str_param_list(param_list) out += self._str_warnings() out += self._str_see_also(func_role) out += self._str_section('Notes') out += self._str_references() out += self._str_examples() for param_list in ('Attributes', 'Methods'): out += self._str_member_list(param_list) out = self._str_indent(out,indent) return '\n'.join(out) class SphinxFunctionDoc(SphinxDocString, FunctionDoc): def __init__(self, obj, doc=None, config={}): self.load_config(config) FunctionDoc.__init__(self, obj, doc=doc, config=config) class SphinxClassDoc(SphinxDocString, ClassDoc): def __init__(self, obj, doc=None, func_doc=None, config={}): self.load_config(config) ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config) class SphinxObjDoc(SphinxDocString): def __init__(self, obj, doc=None, config={}): self._f = obj self.load_config(config) SphinxDocString.__init__(self, doc, config=config) def get_doc_object(obj, what=None, doc=None, config={}): if what is None: if inspect.isclass(obj): what = 'class' elif inspect.ismodule(obj): what = 'module' elif isinstance(obj, collections.Callable): what = 'function' else: what = 'object' if what == 'class': return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, config=config) elif what in ('function', 'method'): return SphinxFunctionDoc(obj, doc=doc, config=config) else: if doc is None: doc = pydoc.getdoc(obj) return SphinxObjDoc(obj, doc, config=config) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/doctest.py0000644000077000000240000000243612425434461026564 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This is a set of three directives that allow us to insert metadata about doctests into the .rst files so the testing framework knows which tests to skip. This is quite different from the doctest extension in Sphinx itself, which actually does something. For astropy, all of the testing is centrally managed from py.test and Sphinx is not used for running tests. """ import re from docutils.nodes import literal_block from sphinx.util.compat import Directive class DoctestSkipDirective(Directive): has_content = True def run(self): # Check if there is any valid argument, and skip it. Currently only # 'win32' is supported in astropy.tests.pytest_plugins. if re.match('win32', self.content[0]): self.content = self.content[2:] code = '\n'.join(self.content) return [literal_block(code, code)] class DoctestRequiresDirective(DoctestSkipDirective): # This is silly, but we really support an unbounded number of # optional arguments optional_arguments = 64 def setup(app): app.add_directive('doctest-requires', DoctestRequiresDirective) app.add_directive('doctest-skip', DoctestSkipDirective) app.add_directive('doctest-skip-all', DoctestSkipDirective) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/edit_on_github.py0000644000077000000240000001340712401041777030100 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This extension makes it easy to edit documentation on github. It adds links associated with each docstring that go to the corresponding view source page on Github. From there, the user can push the "Edit" button, edit the docstring, and submit a pull request. It has the following configuration options (to be set in the project's ``conf.py``): * ``edit_on_github_project`` The name of the github project, in the form "username/projectname". * ``edit_on_github_branch`` The name of the branch to edit. If this is a released version, this should be a git tag referring to that version. For a dev version, it often makes sense for it to be "master". It may also be a git hash. * ``edit_on_github_source_root`` The location within the source tree of the root of the Python package. Defaults to "lib". * ``edit_on_github_doc_root`` The location within the source tree of the root of the documentation source. Defaults to "doc", but it may make sense to set it to "doc/source" if the project uses a separate source directory. * ``edit_on_github_docstring_message`` The phrase displayed in the links to edit a docstring. Defaults to "[edit on github]". * ``edit_on_github_page_message`` The phrase displayed in the links to edit a RST page. Defaults to "[edit this page on github]". * ``edit_on_github_help_message`` The phrase displayed as a tooltip on the edit links. Defaults to "Push the Edit button on the next page" * ``edit_on_github_skip_regex`` When the path to the .rst file matches this regular expression, no "edit this page on github" link will be added. Defaults to ``"_.*"``. """ import inspect import os import re import sys from docutils import nodes from sphinx import addnodes def import_object(modname, name): """ Import the object given by *modname* and *name* and return it. If not found, or the import fails, returns None. """ try: __import__(modname) mod = sys.modules[modname] obj = mod for part in name.split('.'): obj = getattr(obj, part) return obj except: return None def get_url_base(app): return 'http://github.com/%s/tree/%s/' % ( app.config.edit_on_github_project, app.config.edit_on_github_branch) def doctree_read(app, doctree): # Get the configuration parameters if app.config.edit_on_github_project == 'REQUIRED': raise ValueError( "The edit_on_github_project configuration variable must be " "provided in the conf.py") source_root = app.config.edit_on_github_source_root url = get_url_base(app) docstring_message = app.config.edit_on_github_docstring_message # Handle the docstring-editing links for objnode in doctree.traverse(addnodes.desc): if objnode.get('domain') != 'py': continue names = set() for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue modname = signode.get('module') if not modname: continue fullname = signode.get('fullname') if fullname in names: # only one link per name, please continue names.add(fullname) obj = import_object(modname, fullname) anchor = None if obj is not None: try: lines, lineno = inspect.getsourcelines(obj) except: pass else: anchor = '#L%d' % lineno if anchor: real_modname = inspect.getmodule(obj).__name__ path = '%s%s%s.py%s' % ( url, source_root, real_modname.replace('.', '/'), anchor) onlynode = addnodes.only(expr='html') onlynode += nodes.reference( reftitle=app.config.edit_on_github_help_message, refuri=path) onlynode[0] += nodes.inline( '', '', nodes.raw('', ' ', format='html'), nodes.Text(docstring_message), classes=['edit-on-github', 'viewcode-link']) signode += onlynode def html_page_context(app, pagename, templatename, context, doctree): if (templatename == 'page.html' and not re.match(app.config.edit_on_github_skip_regex, pagename)): doc_root = app.config.edit_on_github_doc_root if doc_root != '' and not doc_root.endswith('/'): doc_root += '/' doc_path = os.path.relpath(doctree.get('source'), app.builder.srcdir) url = get_url_base(app) page_message = app.config.edit_on_github_page_message context['edit_on_github'] = url + doc_root + doc_path context['edit_on_github_page_message'] = ( app.config.edit_on_github_page_message) def setup(app): app.add_config_value('edit_on_github_project', 'REQUIRED', True) app.add_config_value('edit_on_github_branch', 'master', True) app.add_config_value('edit_on_github_source_root', 'lib', True) app.add_config_value('edit_on_github_doc_root', 'doc', True) app.add_config_value('edit_on_github_docstring_message', '[edit on github]', True) app.add_config_value('edit_on_github_page_message', 'Edit This Page on Github', True) app.add_config_value('edit_on_github_help_message', 'Push the Edit button on the next page', True) app.add_config_value('edit_on_github_skip_regex', '_.*', True) app.connect('doctree-read', doctree_read) app.connect('html-page-context', html_page_context) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/numpydoc.py0000644000077000000240000001441412354456432026757 0ustar adamstaff00000000000000""" ======== numpydoc ======== Sphinx extension that handles docstrings in the Numpy standard format. [1] It will: - Convert Parameters etc. sections to field lists. - Convert See Also section to a See also entry. - Renumber references. - Extract the signature from the docstring, if it can't be determined otherwise. .. [1] https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt """ from __future__ import division, absolute_import, print_function import os, sys, re, pydoc import sphinx import inspect import collections if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") from .docscrape_sphinx import get_doc_object, SphinxDocString from sphinx.util.compat import Directive if sys.version_info[0] >= 3: sixu = lambda s: s else: sixu = lambda s: unicode(s, 'unicode_escape') def mangle_docstrings(app, what, name, obj, options, lines, reference_offset=[0]): cfg = dict(use_plots=app.config.numpydoc_use_plots, show_class_members=app.config.numpydoc_show_class_members, class_members_toctree=app.config.numpydoc_class_members_toctree, ) if what == 'module': # Strip top title title_re = re.compile(sixu('^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*'), re.I|re.S) lines[:] = title_re.sub(sixu(''), sixu("\n").join(lines)).split(sixu("\n")) else: doc = get_doc_object(obj, what, sixu("\n").join(lines), config=cfg) if sys.version_info[0] >= 3: doc = str(doc) else: doc = unicode(doc) lines[:] = doc.split(sixu("\n")) if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \ obj.__name__: if hasattr(obj, '__module__'): v = dict(full_name=sixu("%s.%s") % (obj.__module__, obj.__name__)) else: v = dict(full_name=obj.__name__) lines += [sixu(''), sixu('.. htmlonly::'), sixu('')] lines += [sixu(' %s') % x for x in (app.config.numpydoc_edit_link % v).split("\n")] # replace reference numbers so that there are no duplicates references = [] for line in lines: line = line.strip() m = re.match(sixu('^.. \\[([a-z0-9_.-])\\]'), line, re.I) if m: references.append(m.group(1)) # start renaming from the longest string, to avoid overwriting parts references.sort(key=lambda x: -len(x)) if references: for i, line in enumerate(lines): for r in references: if re.match(sixu('^\\d+$'), r): new_r = sixu("R%d") % (reference_offset[0] + int(r)) else: new_r = sixu("%s%d") % (r, reference_offset[0]) lines[i] = lines[i].replace(sixu('[%s]_') % r, sixu('[%s]_') % new_r) lines[i] = lines[i].replace(sixu('.. [%s]') % r, sixu('.. [%s]') % new_r) reference_offset[0] += len(references) def mangle_signature(app, what, name, obj, options, sig, retann): # Do not try to inspect classes that don't define `__init__` if (inspect.isclass(obj) and (not hasattr(obj, '__init__') or 'initializes x; see ' in pydoc.getdoc(obj.__init__))): return '', '' if not (isinstance(obj, collections.Callable) or hasattr(obj, '__argspec_is_invalid_')): return if not hasattr(obj, '__doc__'): return doc = SphinxDocString(pydoc.getdoc(obj)) if doc['Signature']: sig = re.sub(sixu("^[^(]*"), sixu(""), doc['Signature']) return sig, sixu('') def setup(app, get_doc_object_=get_doc_object): if not hasattr(app, 'add_config_value'): return # probably called by nose, better bail out global get_doc_object get_doc_object = get_doc_object_ app.connect('autodoc-process-docstring', mangle_docstrings) app.connect('autodoc-process-signature', mangle_signature) app.add_config_value('numpydoc_edit_link', None, False) app.add_config_value('numpydoc_use_plots', None, False) app.add_config_value('numpydoc_show_class_members', True, True) app.add_config_value('numpydoc_class_members_toctree', True, True) # Extra mangling domains app.add_domain(NumpyPythonDomain) app.add_domain(NumpyCDomain) #------------------------------------------------------------------------------ # Docstring-mangling domains #------------------------------------------------------------------------------ from docutils.statemachine import ViewList from sphinx.domains.c import CDomain from sphinx.domains.python import PythonDomain class ManglingDomainBase(object): directive_mangling_map = {} def __init__(self, *a, **kw): super(ManglingDomainBase, self).__init__(*a, **kw) self.wrap_mangling_directives() def wrap_mangling_directives(self): for name, objtype in list(self.directive_mangling_map.items()): self.directives[name] = wrap_mangling_directive( self.directives[name], objtype) class NumpyPythonDomain(ManglingDomainBase, PythonDomain): name = 'np' directive_mangling_map = { 'function': 'function', 'class': 'class', 'exception': 'class', 'method': 'function', 'classmethod': 'function', 'staticmethod': 'function', 'attribute': 'attribute', } indices = [] class NumpyCDomain(ManglingDomainBase, CDomain): name = 'np-c' directive_mangling_map = { 'function': 'function', 'member': 'attribute', 'macro': 'function', 'type': 'class', 'var': 'object', } def wrap_mangling_directive(base_directive, objtype): class directive(base_directive): def run(self): env = self.state.document.settings.env name = None if self.arguments: m = re.match(r'^(.*\s+)?(.*?)(\(.*)?', self.arguments[0]) name = m.group(2).strip() if not name: name = self.arguments[0] lines = list(self.content) mangle_docstrings(env.app, objtype, name, None, None, lines) self.content = ViewList(lines, self.content.parent) return base_directive.run(self) return directive astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/phantom_import.py0000644000077000000240000001333612354456432030163 0ustar adamstaff00000000000000""" ============== phantom_import ============== Sphinx extension to make directives from ``sphinx.ext.autodoc`` and similar extensions to use docstrings loaded from an XML file. This extension loads an XML file in the Pydocweb format [1] and creates a dummy module that contains the specified docstrings. This can be used to get the current docstrings from a Pydocweb instance without needing to rebuild the documented module. .. [1] http://code.google.com/p/pydocweb """ from __future__ import division, absolute_import, print_function import imp, sys, compiler, types, os, inspect, re def setup(app): app.connect('builder-inited', initialize) app.add_config_value('phantom_import_file', None, True) def initialize(app): fn = app.config.phantom_import_file if (fn and os.path.isfile(fn)): print("[numpydoc] Phantom importing modules from", fn, "...") import_phantom_module(fn) #------------------------------------------------------------------------------ # Creating 'phantom' modules from an XML description #------------------------------------------------------------------------------ def import_phantom_module(xml_file): """ Insert a fake Python module to sys.modules, based on a XML file. The XML file is expected to conform to Pydocweb DTD. The fake module will contain dummy objects, which guarantee the following: - Docstrings are correct. - Class inheritance relationships are correct (if present in XML). - Function argspec is *NOT* correct (even if present in XML). Instead, the function signature is prepended to the function docstring. - Class attributes are *NOT* correct; instead, they are dummy objects. Parameters ---------- xml_file : str Name of an XML file to read """ import lxml.etree as etree object_cache = {} tree = etree.parse(xml_file) root = tree.getroot() # Sort items so that # - Base classes come before classes inherited from them # - Modules come before their contents all_nodes = dict([(n.attrib['id'], n) for n in root]) def _get_bases(node, recurse=False): bases = [x.attrib['ref'] for x in node.findall('base')] if recurse: j = 0 while True: try: b = bases[j] except IndexError: break if b in all_nodes: bases.extend(_get_bases(all_nodes[b])) j += 1 return bases type_index = ['module', 'class', 'callable', 'object'] def base_cmp(a, b): x = cmp(type_index.index(a.tag), type_index.index(b.tag)) if x != 0: return x if a.tag == 'class' and b.tag == 'class': a_bases = _get_bases(a, recurse=True) b_bases = _get_bases(b, recurse=True) x = cmp(len(a_bases), len(b_bases)) if x != 0: return x if a.attrib['id'] in b_bases: return -1 if b.attrib['id'] in a_bases: return 1 return cmp(a.attrib['id'].count('.'), b.attrib['id'].count('.')) nodes = root.getchildren() nodes.sort(base_cmp) # Create phantom items for node in nodes: name = node.attrib['id'] doc = (node.text or '').decode('string-escape') + "\n" if doc == "\n": doc = "" # create parent, if missing parent = name while True: parent = '.'.join(parent.split('.')[:-1]) if not parent: break if parent in object_cache: break obj = imp.new_module(parent) object_cache[parent] = obj sys.modules[parent] = obj # create object if node.tag == 'module': obj = imp.new_module(name) obj.__doc__ = doc sys.modules[name] = obj elif node.tag == 'class': bases = [object_cache[b] for b in _get_bases(node) if b in object_cache] bases.append(object) init = lambda self: None init.__doc__ = doc obj = type(name, tuple(bases), {'__doc__': doc, '__init__': init}) obj.__name__ = name.split('.')[-1] elif node.tag == 'callable': funcname = node.attrib['id'].split('.')[-1] argspec = node.attrib.get('argspec') if argspec: argspec = re.sub('^[^(]*', '', argspec) doc = "%s%s\n\n%s" % (funcname, argspec, doc) obj = lambda: 0 obj.__argspec_is_invalid_ = True if sys.version_info[0] >= 3: obj.__name__ = funcname else: obj.func_name = funcname obj.__name__ = name obj.__doc__ = doc if inspect.isclass(object_cache[parent]): obj.__objclass__ = object_cache[parent] else: class Dummy(object): pass obj = Dummy() obj.__name__ = name obj.__doc__ = doc if inspect.isclass(object_cache[parent]): obj.__get__ = lambda: None object_cache[name] = obj if parent: if inspect.ismodule(object_cache[parent]): obj.__module__ = parent setattr(object_cache[parent], name.split('.')[-1], obj) # Populate items for node in root: obj = object_cache.get(node.attrib['id']) if obj is None: continue for ref in node.findall('ref'): if node.tag == 'class': if ref.attrib['ref'].startswith(node.attrib['id'] + '.'): setattr(obj, ref.attrib['name'], object_cache.get(ref.attrib['ref'])) else: setattr(obj, ref.attrib['name'], object_cache.get(ref.attrib['ref'])) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/smart_resolver.py0000644000077000000240000000717612425434461030174 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ The classes in the astropy docs are documented by their API location, which is not necessarily where they are defined in the source. This causes a problem when certain automated features of the doc build, such as the inheritance diagrams or the `Bases` list of a class reference a class by its canonical location rather than its "user" location. In the `autodoc-process-docstring` event, a mapping from the actual name to the API name is maintained. Later, in the `missing-reference` event, unresolved references are looked up in this dictionary and corrected if possible. """ from docutils.nodes import literal, reference def process_docstring(app, what, name, obj, options, lines): if isinstance(obj, type): env = app.env if not hasattr(env, 'class_name_mapping'): env.class_name_mapping = {} mapping = env.class_name_mapping mapping[obj.__module__ + '.' + obj.__name__] = name def missing_reference_handler(app, env, node, contnode): if not hasattr(env, 'class_name_mapping'): env.class_name_mapping = {} mapping = env.class_name_mapping reftype = node['reftype'] reftarget = node['reftarget'] if reftype in ('obj', 'class', 'exc', 'meth'): reftarget = node['reftarget'] suffix = '' if reftarget not in mapping: if '.' in reftarget: front, suffix = reftarget.rsplit('.', 1) else: suffix = reftarget if suffix.startswith('_') and not suffix.startswith('__'): # If this is a reference to a hidden class or method, # we can't link to it, but we don't want to have a # nitpick warning. return node[0].deepcopy() if reftype in ('obj', 'meth') and '.' in reftarget: if front in mapping: reftarget = front suffix = '.' + suffix if (reftype in ('class', ) and '.' in reftarget and reftarget not in mapping): if '.' in front: reftarget, _ = front.rsplit('.', 1) suffix = '.' + suffix reftarget = reftarget + suffix prefix = reftarget.rsplit('.')[0] if (reftarget not in mapping and prefix in env.intersphinx_named_inventory): if reftarget in env.intersphinx_named_inventory[prefix]['py:class']: newtarget = env.intersphinx_named_inventory[prefix]['py:class'][reftarget][2] if not node['refexplicit'] and \ '~' not in node.rawsource: contnode = literal(text=reftarget) newnode = reference('', '', internal=True) newnode['reftitle'] = reftarget newnode['refuri'] = newtarget newnode.append(contnode) return newnode if reftarget in mapping: newtarget = mapping[reftarget] + suffix if not node['refexplicit'] and not '~' in node.rawsource: contnode = literal(text=newtarget) newnode = env.domains['py'].resolve_xref( env, node['refdoc'], app.builder, 'class', newtarget, node, contnode) if newnode is not None: newnode['reftitle'] = reftarget return newnode def setup(app): app.connect('autodoc-process-docstring', process_docstring) app.connect('missing-reference', missing_reference_handler) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/templates/0000755000077000000240000000000012505171566026541 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/0000755000077000000240000000000012505171566032137 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst0000644000077000000240000000025212354456432033602 0ustar adamstaff00000000000000{% if referencefile %} .. include:: {{ referencefile }} {% endif %} {{ objname }} {{ underline }} .. currentmodule:: {{ module }} .. auto{{ objtype }}:: {{ objname }} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/class.rst0000644000077000000240000000221112354456432033772 0ustar adamstaff00000000000000{% if referencefile %} .. include:: {{ referencefile }} {% endif %} {{ objname }} {{ underline }} .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} :show-inheritance: {% if '__init__' in methods %} {% set caught_result = methods.remove('__init__') %} {% endif %} {% block attributes_summary %} {% if attributes %} .. rubric:: Attributes Summary .. autosummary:: {% for item in attributes %} ~{{ name }}.{{ item }} {%- endfor %} {% endif %} {% endblock %} {% block methods_summary %} {% if methods %} .. rubric:: Methods Summary .. autosummary:: {% for item in methods %} ~{{ name }}.{{ item }} {%- endfor %} {% endif %} {% endblock %} {% block attributes_documentation %} {% if attributes %} .. rubric:: Attributes Documentation {% for item in attributes %} .. autoattribute:: {{ item }} {%- endfor %} {% endif %} {% endblock %} {% block methods_documentation %} {% if methods %} .. rubric:: Methods Documentation {% for item in methods %} .. automethod:: {{ item }} {%- endfor %} {% endif %} {% endblock %} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/templates/autosummary_core/module.rst0000644000077000000240000000127712354456432034165 0ustar adamstaff00000000000000{% if referencefile %} .. include:: {{ referencefile }} {% endif %} {{ objname }} {{ underline }} .. automodule:: {{ fullname }} {% block functions %} {% if functions %} .. rubric:: Functions .. autosummary:: {% for item in functions %} {{ item }} {%- endfor %} {% endif %} {% endblock %} {% block classes %} {% if classes %} .. rubric:: Classes .. autosummary:: {% for item in classes %} {{ item }} {%- endfor %} {% endif %} {% endblock %} {% block exceptions %} {% if exceptions %} .. rubric:: Exceptions .. autosummary:: {% for item in exceptions %} {{ item }} {%- endfor %} {% endif %} {% endblock %} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tests/0000755000077000000240000000000012505171566025705 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tests/__init__.py0000644000077000000240000000334112401041777030012 0ustar adamstaff00000000000000import os import subprocess as sp import sys from textwrap import dedent import pytest @pytest.fixture def cython_testpackage(tmpdir, request): """ Creates a trivial Cython package for use with tests. """ test_pkg = tmpdir.mkdir('test_pkg') test_pkg.mkdir('_eva_').ensure('__init__.py') test_pkg.join('_eva_').join('unit02.pyx').write(dedent("""\ def pilot(): \"\"\"Returns the pilot of Eva Unit-02.\"\"\" return True """)) import astropy_helpers test_pkg.join('setup.py').write(dedent("""\ import sys sys.path.insert(0, {0!r}) from os.path import join from setuptools import setup, Extension from astropy_helpers.setup_helpers import register_commands NAME = '_eva_' VERSION = 0.1 RELEASE = True cmdclassd = register_commands(NAME, VERSION, RELEASE) setup( name=NAME, version=VERSION, cmdclass=cmdclassd, ext_modules=[Extension('_eva_.unit02', [join('_eva_', 'unit02.pyx')])] ) """.format(os.path.dirname(astropy_helpers.__path__[0])))) test_pkg.chdir() # Build the Cython module in a subprocess; otherwise strange things can # happen with Cython's global module state sp.call([sys.executable, 'setup.py', 'build_ext', '--inplace']) sys.path.insert(0, str(test_pkg)) import _eva_.unit02 def cleanup(test_pkg=test_pkg): for modname in ['_eva_', '_eva_.unit02']: try: del sys.modules[modname] except KeyError: pass sys.path.remove(str(test_pkg)) request.addfinalizer(cleanup) return test_pkg astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodapi.py0000644000077000000240000001636412464715714031475 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import sys import pytest from . import * from ....tests import * from ....utils import iteritems pytest.importorskip('sphinx') # skips these tests if sphinx not present class FakeConfig(object): """ Mocks up a sphinx configuration setting construct for automodapi tests """ def __init__(self, **kwargs): for k, v in iteritems(kwargs): setattr(self, k, v) class FakeApp(object): """ Mocks up a `sphinx.application.Application` object for automodapi tests """ # Some default config values _defaults = { 'automodapi_toctreedirnm': 'api', 'automodapi_writereprocessed': False } def __init__(self, **configs): config = self._defaults.copy() config.update(configs) self.config = FakeConfig(**config) self.info = [] self.warnings = [] def info(self, msg, loc): self.info.append((msg, loc)) def warn(self, msg, loc): self.warnings.append((msg, loc)) am_replacer_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.tests.test_automodapi {options} This comes after """ am_replacer_basic_expected = """ This comes before astropy_helpers.sphinx.ext.tests.test_automodapi Module ------------------------------------------------------- .. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :functions-only: :toctree: api/ Classes ^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :classes-only: :toctree: api/ Class Inheritance Diagram ^^^^^^^^^^^^^^^^^^^^^^^^^ .. automod-diagram:: astropy_helpers.sphinx.ext.tests.test_automodapi :private-bases: :parts: 1 {empty} This comes after """.format(empty='').replace('/', os.sep) # the .format is necessary for editors that remove empty-line whitespace def test_am_replacer_basic(): """ Tests replacing an ".. automodapi::" with the automodapi no-option template """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_str.format(options=''), fakeapp) assert result == am_replacer_basic_expected am_replacer_noinh_expected = """ This comes before astropy_helpers.sphinx.ext.tests.test_automodapi Module ------------------------------------------------------- .. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :functions-only: :toctree: api/ Classes ^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :classes-only: :toctree: api/ This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_noinh(): """ Tests replacing an ".. automodapi::" with no-inheritance-diagram option """ from ..automodapi import automodapi_replace fakeapp = FakeApp() ops = ['', ':no-inheritance-diagram:'] ostr = '\n '.join(ops) result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp) assert result == am_replacer_noinh_expected am_replacer_titleandhdrs_expected = """ This comes before astropy_helpers.sphinx.ext.tests.test_automodapi Module &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& .. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi Functions ********* .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :functions-only: :toctree: api/ Classes ******* .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :classes-only: :toctree: api/ Class Inheritance Diagram ************************* .. automod-diagram:: astropy_helpers.sphinx.ext.tests.test_automodapi :private-bases: :parts: 1 {empty} This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_titleandhdrs(): """ Tests replacing an ".. automodapi::" entry with title-setting and header character options. """ from ..automodapi import automodapi_replace fakeapp = FakeApp() ops = ['', ':title: A new title', ':headings: &*'] ostr = '\n '.join(ops) result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp) assert result == am_replacer_titleandhdrs_expected am_replacer_nomain_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.automodapi :no-main-docstr: This comes after """ am_replacer_nomain_expected = """ This comes before astropy_helpers.sphinx.ext.automodapi Module -------------------------------------------- Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.automodapi :functions-only: :toctree: api/ This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_nomain(): """ Tests replacing an ".. automodapi::" with "no-main-docstring" . """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_nomain_str, fakeapp) assert result == am_replacer_nomain_expected am_replacer_skip_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.automodapi :skip: something1 :skip: something2 This comes after """ am_replacer_skip_expected = """ This comes before astropy_helpers.sphinx.ext.automodapi Module -------------------------------------------- .. automodule:: astropy_helpers.sphinx.ext.automodapi Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.automodapi :functions-only: :toctree: api/ :skip: something1,something2 This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_skip(): """ Tests using the ":skip: option in an ".. automodapi::" . """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_skip_str, fakeapp) assert result == am_replacer_skip_expected am_replacer_invalidop_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.automodapi :invalid-option: This comes after """ def test_am_replacer_invalidop(): """ Tests that a sphinx warning is produced with an invalid option. """ from ..automodapi import automodapi_replace fakeapp = FakeApp() automodapi_replace(am_replacer_invalidop_str, fakeapp) expected_warnings = [('Found additional options invalid-option in ' 'automodapi.', None)] assert fakeapp.warnings == expected_warnings am_replacer_cython_str = """ This comes before .. automodapi:: _eva_.unit02 {options} This comes after """ am_replacer_cython_expected = """ This comes before _eva_.unit02 Module ------------------- .. automodule:: _eva_.unit02 Functions ^^^^^^^^^ .. automodsumm:: _eva_.unit02 :functions-only: :toctree: api/ This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_cython(cython_testpackage): """ Tests replacing an ".. automodapi::" for a Cython module. """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_cython_str.format(options=''), fakeapp) assert result == am_replacer_cython_expected astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_automodsumm.py0000644000077000000240000000461212464715714031676 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import sys import pytest from . import * from ....tests import * from ....utils import iteritems pytest.importorskip('sphinx') # skips these tests if sphinx not present class FakeEnv(object): """ Mocks up a sphinx env setting construct for automodapi tests """ def __init__(self, **kwargs): for k, v in iteritems(kwargs): setattr(self, k, v) class FakeBuilder(object): """ Mocks up a sphinx builder setting construct for automodapi tests """ def __init__(self, **kwargs): self.env = FakeEnv(**kwargs) class FakeApp(object): """ Mocks up a `sphinx.application.Application` object for automodapi tests """ def __init__(self, srcdir, automodapipresent=True): self.builder = FakeBuilder(srcdir=srcdir) self.info = [] self.warnings = [] self._extensions = [] if automodapipresent: self._extensions.append('astropy_helpers.sphinx.ext.automodapi') def info(self, msg, loc): self.info.append((msg, loc)) def warn(self, msg, loc): self.warnings.append((msg, loc)) ams_to_asmry_str = """ Before .. automodsumm:: astropy_helpers.sphinx.ext.automodsumm :p: And After """ ams_to_asmry_expected = """\ .. currentmodule:: astropy_helpers.sphinx.ext.automodsumm .. autosummary:: :p: Automoddiagram Automodsumm automodsumm_to_autosummary_lines generate_automodsumm_docs process_automodsumm_generation setup""" def test_ams_to_asmry(tmpdir): from ..automodsumm import automodsumm_to_autosummary_lines fi = tmpdir.join('automodsumm.rst') fi.write(ams_to_asmry_str) fakeapp = FakeApp(srcdir='') resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp) assert '\n'.join(resultlines) == ams_to_asmry_expected ams_cython_str = """ Before .. automodsumm:: _eva_.unit02 :functions-only: :p: And After """ ams_cython_expected = """\ .. currentmodule:: _eva_.unit02 .. autosummary:: :p: pilot""" def test_ams_cython(tmpdir, cython_testpackage): from ..automodsumm import automodsumm_to_autosummary_lines fi = tmpdir.join('automodsumm.rst') fi.write(ams_cython_str) fakeapp = FakeApp(srcdir='') resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp) assert '\n'.join(resultlines) == ams_cython_expected astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_docscrape.py0000644000077000000240000004327112354456432031270 0ustar adamstaff00000000000000# -*- encoding:utf-8 -*- from __future__ import division, absolute_import, print_function import sys, textwrap from ..docscrape import NumpyDocString, FunctionDoc, ClassDoc from ..docscrape_sphinx import SphinxDocString, SphinxClassDoc if sys.version_info[0] >= 3: sixu = lambda s: s else: sixu = lambda s: unicode(s, 'unicode_escape') doc_txt = '''\ numpy.multivariate_normal(mean, cov, shape=None, spam=None) Draw values from a multivariate normal distribution with specified mean and covariance. The multivariate normal or Gaussian distribution is a generalisation of the one-dimensional normal distribution to higher dimensions. Parameters ---------- mean : (N,) ndarray Mean of the N-dimensional distribution. .. math:: (1+2+3)/3 cov : (N, N) ndarray Covariance matrix of the distribution. shape : tuple of ints Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). Returns ------- out : ndarray The drawn samples, arranged according to `shape`. If the shape given is (m,n,...), then the shape of `out` is is (m,n,...,N). In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. list of str This is not a real return value. It exists to test anonymous return values. Other Parameters ---------------- spam : parrot A parrot off its mortal coil. Raises ------ RuntimeError Some error Warns ----- RuntimeWarning Some warning Warnings -------- Certain warnings apply. Notes ----- Instead of specifying the full covariance matrix, popular approximations include: - Spherical covariance (`cov` is a multiple of the identity matrix) - Diagonal covariance (`cov` has non-negative elements only on the diagonal) This geometrical property can be seen in two dimensions by plotting generated data-points: >>> mean = [0,0] >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis >>> x,y = multivariate_normal(mean,cov,5000).T >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show() Note that the covariance matrix must be symmetric and non-negative definite. References ---------- .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic Processes," 3rd ed., McGraw-Hill Companies, 1991 .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification," 2nd ed., Wiley, 2001. See Also -------- some, other, funcs otherfunc : relationship Examples -------- >>> mean = (1,2) >>> cov = [[1,0],[1,0]] >>> x = multivariate_normal(mean,cov,(3,3)) >>> print x.shape (3, 3, 2) The following is probably true, given that 0.6 is roughly twice the standard deviation: >>> print list( (x[0,0,:] - mean) < 0.6 ) [True, True] .. index:: random :refguide: random;distributions, random;gauss ''' doc = NumpyDocString(doc_txt) def test_signature(): assert doc['Signature'].startswith('numpy.multivariate_normal(') assert doc['Signature'].endswith('spam=None)') def test_summary(): assert doc['Summary'][0].startswith('Draw values') assert doc['Summary'][-1].endswith('covariance.') def test_extended_summary(): assert doc['Extended Summary'][0].startswith('The multivariate normal') def test_parameters(): assert len(doc['Parameters']) == 3 assert [n for n,_,_ in doc['Parameters']] == ['mean','cov','shape'] arg, arg_type, desc = doc['Parameters'][1] assert arg_type == '(N, N) ndarray' assert desc[0].startswith('Covariance matrix') assert doc['Parameters'][0][-1][-2] == ' (1+2+3)/3' def test_other_parameters(): assert len(doc['Other Parameters']) == 1 assert [n for n,_,_ in doc['Other Parameters']] == ['spam'] arg, arg_type, desc = doc['Other Parameters'][0] assert arg_type == 'parrot' assert desc[0].startswith('A parrot off its mortal coil') def test_returns(): assert len(doc['Returns']) == 2 arg, arg_type, desc = doc['Returns'][0] assert arg == 'out' assert arg_type == 'ndarray' assert desc[0].startswith('The drawn samples') assert desc[-1].endswith('distribution.') arg, arg_type, desc = doc['Returns'][1] assert arg == 'list of str' assert arg_type == '' assert desc[0].startswith('This is not a real') assert desc[-1].endswith('anonymous return values.') def test_notes(): assert doc['Notes'][0].startswith('Instead') assert doc['Notes'][-1].endswith('definite.') assert len(doc['Notes']) == 17 def test_references(): assert doc['References'][0].startswith('..') assert doc['References'][-1].endswith('2001.') def test_examples(): assert doc['Examples'][0].startswith('>>>') assert doc['Examples'][-1].endswith('True]') def test_index(): assert doc['index']['default'] == 'random' assert len(doc['index']) == 2 assert len(doc['index']['refguide']) == 2 def non_blank_line_by_line_compare(a,b): a = textwrap.dedent(a) b = textwrap.dedent(b) a = [l.rstrip() for l in a.split('\n') if l.strip()] b = [l.rstrip() for l in b.split('\n') if l.strip()] for n,line in enumerate(a): if not line == b[n]: raise AssertionError("Lines %s of a and b differ: " "\n>>> %s\n<<< %s\n" % (n,line,b[n])) def test_str(): non_blank_line_by_line_compare(str(doc), """numpy.multivariate_normal(mean, cov, shape=None, spam=None) Draw values from a multivariate normal distribution with specified mean and covariance. The multivariate normal or Gaussian distribution is a generalisation of the one-dimensional normal distribution to higher dimensions. Parameters ---------- mean : (N,) ndarray Mean of the N-dimensional distribution. .. math:: (1+2+3)/3 cov : (N, N) ndarray Covariance matrix of the distribution. shape : tuple of ints Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). Returns ------- out : ndarray The drawn samples, arranged according to `shape`. If the shape given is (m,n,...), then the shape of `out` is is (m,n,...,N). In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. list of str This is not a real return value. It exists to test anonymous return values. Other Parameters ---------------- spam : parrot A parrot off its mortal coil. Raises ------ RuntimeError Some error Warns ----- RuntimeWarning Some warning Warnings -------- Certain warnings apply. See Also -------- `some`_, `other`_, `funcs`_ `otherfunc`_ relationship Notes ----- Instead of specifying the full covariance matrix, popular approximations include: - Spherical covariance (`cov` is a multiple of the identity matrix) - Diagonal covariance (`cov` has non-negative elements only on the diagonal) This geometrical property can be seen in two dimensions by plotting generated data-points: >>> mean = [0,0] >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis >>> x,y = multivariate_normal(mean,cov,5000).T >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show() Note that the covariance matrix must be symmetric and non-negative definite. References ---------- .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic Processes," 3rd ed., McGraw-Hill Companies, 1991 .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification," 2nd ed., Wiley, 2001. Examples -------- >>> mean = (1,2) >>> cov = [[1,0],[1,0]] >>> x = multivariate_normal(mean,cov,(3,3)) >>> print x.shape (3, 3, 2) The following is probably true, given that 0.6 is roughly twice the standard deviation: >>> print list( (x[0,0,:] - mean) < 0.6 ) [True, True] .. index:: random :refguide: random;distributions, random;gauss""") def test_sphinx_str(): sphinx_doc = SphinxDocString(doc_txt) non_blank_line_by_line_compare(str(sphinx_doc), """ .. index:: random single: random;distributions, random;gauss Draw values from a multivariate normal distribution with specified mean and covariance. The multivariate normal or Gaussian distribution is a generalisation of the one-dimensional normal distribution to higher dimensions. :Parameters: **mean** : (N,) ndarray Mean of the N-dimensional distribution. .. math:: (1+2+3)/3 **cov** : (N, N) ndarray Covariance matrix of the distribution. **shape** : tuple of ints Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). :Returns: **out** : ndarray The drawn samples, arranged according to `shape`. If the shape given is (m,n,...), then the shape of `out` is is (m,n,...,N). In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. list of str This is not a real return value. It exists to test anonymous return values. :Other Parameters: **spam** : parrot A parrot off its mortal coil. :Raises: **RuntimeError** Some error :Warns: **RuntimeWarning** Some warning .. warning:: Certain warnings apply. .. seealso:: :obj:`some`, :obj:`other`, :obj:`funcs` :obj:`otherfunc` relationship .. rubric:: Notes Instead of specifying the full covariance matrix, popular approximations include: - Spherical covariance (`cov` is a multiple of the identity matrix) - Diagonal covariance (`cov` has non-negative elements only on the diagonal) This geometrical property can be seen in two dimensions by plotting generated data-points: >>> mean = [0,0] >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis >>> x,y = multivariate_normal(mean,cov,5000).T >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show() Note that the covariance matrix must be symmetric and non-negative definite. .. rubric:: References .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic Processes," 3rd ed., McGraw-Hill Companies, 1991 .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification," 2nd ed., Wiley, 2001. .. only:: latex [1]_, [2]_ .. rubric:: Examples >>> mean = (1,2) >>> cov = [[1,0],[1,0]] >>> x = multivariate_normal(mean,cov,(3,3)) >>> print x.shape (3, 3, 2) The following is probably true, given that 0.6 is roughly twice the standard deviation: >>> print list( (x[0,0,:] - mean) < 0.6 ) [True, True] """) doc2 = NumpyDocString(""" Returns array of indices of the maximum values of along the given axis. Parameters ---------- a : {array_like} Array to look in. axis : {None, integer} If None, the index is into the flattened array, otherwise along the specified axis""") def test_parameters_without_extended_description(): assert len(doc2['Parameters']) == 2 doc3 = NumpyDocString(""" my_signature(*params, **kwds) Return this and that. """) def test_escape_stars(): signature = str(doc3).split('\n')[0] signature == 'my_signature(\*params, \*\*kwds)' doc4 = NumpyDocString( """a.conj() Return an array with all complex-valued elements conjugated.""") def test_empty_extended_summary(): assert doc4['Extended Summary'] == [] doc5 = NumpyDocString( """ a.something() Raises ------ LinAlgException If array is singular. Warns ----- SomeWarning If needed """) def test_raises(): assert len(doc5['Raises']) == 1 name,_,desc = doc5['Raises'][0] assert name == 'LinAlgException' assert desc == ['If array is singular.'] def test_warns(): assert len(doc5['Warns']) == 1 name,_,desc = doc5['Warns'][0] assert name == 'SomeWarning' assert desc == ['If needed'] def test_see_also(): doc6 = NumpyDocString( """ z(x,theta) See Also -------- func_a, func_b, func_c func_d : some equivalent func foo.func_e : some other func over multiple lines func_f, func_g, :meth:`func_h`, func_j, func_k :obj:`baz.obj_q` :class:`class_j`: fubar foobar """) assert len(doc6['See Also']) == 12 for func, desc, role in doc6['See Also']: if func in ('func_a', 'func_b', 'func_c', 'func_f', 'func_g', 'func_h', 'func_j', 'func_k', 'baz.obj_q'): assert(not desc) else: assert(desc) if func == 'func_h': assert role == 'meth' elif func == 'baz.obj_q': assert role == 'obj' elif func == 'class_j': assert role == 'class' else: assert role is None if func == 'func_d': assert desc == ['some equivalent func'] elif func == 'foo.func_e': assert desc == ['some other func over', 'multiple lines'] elif func == 'class_j': assert desc == ['fubar', 'foobar'] def test_see_also_print(): class Dummy(object): """ See Also -------- func_a, func_b func_c : some relationship goes here func_d """ pass obj = Dummy() s = str(FunctionDoc(obj, role='func')) assert(':func:`func_a`, :func:`func_b`' in s) assert(' some relationship' in s) assert(':func:`func_d`' in s) doc7 = NumpyDocString(""" Doc starts on second line. """) def test_empty_first_line(): assert doc7['Summary'][0].startswith('Doc starts') def test_no_summary(): str(SphinxDocString(""" Parameters ----------""")) def test_unicode(): doc = SphinxDocString(""" öäöäöäöäöåååå öäöäöäööäååå Parameters ---------- ååå : äää ööö Returns ------- ååå : ööö äää """) assert isinstance(doc['Summary'][0], str) assert doc['Summary'][0] == 'öäöäöäöäöåååå' def test_plot_examples(): cfg = dict(use_plots=True) doc = SphinxDocString(""" Examples -------- >>> import matplotlib.pyplot as plt >>> plt.plot([1,2,3],[4,5,6]) >>> plt.show() """, config=cfg) assert 'plot::' in str(doc), str(doc) doc = SphinxDocString(""" Examples -------- .. plot:: import matplotlib.pyplot as plt plt.plot([1,2,3],[4,5,6]) plt.show() """, config=cfg) assert str(doc).count('plot::') == 1, str(doc) def test_class_members(): class Dummy(object): """ Dummy class. """ def spam(self, a, b): """Spam\n\nSpam spam.""" pass def ham(self, c, d): """Cheese\n\nNo cheese.""" pass @property def spammity(self): """Spammity index""" return 0.95 class Ignorable(object): """local class, to be ignored""" pass for cls in (ClassDoc, SphinxClassDoc): doc = cls(Dummy, config=dict(show_class_members=False)) assert 'Methods' not in str(doc), (cls, str(doc)) assert 'spam' not in str(doc), (cls, str(doc)) assert 'ham' not in str(doc), (cls, str(doc)) assert 'spammity' not in str(doc), (cls, str(doc)) assert 'Spammity index' not in str(doc), (cls, str(doc)) doc = cls(Dummy, config=dict(show_class_members=True)) assert 'Methods' in str(doc), (cls, str(doc)) assert 'spam' in str(doc), (cls, str(doc)) assert 'ham' in str(doc), (cls, str(doc)) assert 'spammity' in str(doc), (cls, str(doc)) if cls is SphinxClassDoc: assert '.. autosummary::' in str(doc), str(doc) else: assert 'Spammity index' in str(doc), str(doc) def test_duplicate_signature(): # Duplicate function signatures occur e.g. in ufuncs, when the # automatic mechanism adds one, and a more detailed comes from the # docstring itself. doc = NumpyDocString( """ z(x1, x2) z(a, theta) """) assert doc['Signature'].strip() == 'z(a, theta)' class_doc_txt = """ Foo Parameters ---------- f : callable ``f(t, y, *f_args)`` Aaa. jac : callable ``jac(t, y, *jac_args)`` Bbb. Attributes ---------- t : float Current time. y : ndarray Current variable values. Methods ------- a b c Examples -------- For usage examples, see `ode`. """ def test_class_members_doc(): doc = ClassDoc(None, class_doc_txt) non_blank_line_by_line_compare(str(doc), """ Foo Parameters ---------- f : callable ``f(t, y, *f_args)`` Aaa. jac : callable ``jac(t, y, *jac_args)`` Bbb. Examples -------- For usage examples, see `ode`. Attributes ---------- t : float Current time. y : ndarray Current variable values. Methods ------- a b c .. index:: """) def test_class_members_doc_sphinx(): doc = SphinxClassDoc(None, class_doc_txt) non_blank_line_by_line_compare(str(doc), """ Foo :Parameters: **f** : callable ``f(t, y, *f_args)`` Aaa. **jac** : callable ``jac(t, y, *jac_args)`` Bbb. .. rubric:: Examples For usage examples, see `ode`. .. rubric:: Attributes === ========== t (float) Current time. y (ndarray) Current variable values. === ========== .. rubric:: Methods === ========== a b c === ========== """) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tests/test_utils.py0000644000077000000240000000174312401041777030456 0ustar adamstaff00000000000000#namedtuple is needed for find_mod_objs so it can have a non-local module import sys from collections import namedtuple import pytest from ..utils import find_mod_objs PY3 = sys.version_info[0] >= 3 pytestmark = pytest.mark.skipif("PY3") def test_find_mod_objs(): lnms, fqns, objs = find_mod_objs('astropy_helpers') # this import is after the above call intentionally to make sure # find_mod_objs properly imports astropy on its own import astropy_helpers # just check for astropy.test ... other things might be added, so we # shouldn't check that it's the only thing assert lnms == [] lnms, fqns, objs = find_mod_objs( 'astropy_helpers.sphinx.ext.tests.test_utils', onlylocals=False) assert namedtuple in objs lnms, fqns, objs = find_mod_objs( 'astropy_helpers.sphinx.ext.tests.test_utils', onlylocals=True) assert 'namedtuple' not in lnms assert 'collections.namedtuple' not in fqns assert namedtuple not in objs astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/tocdepthfix.py0000644000077000000240000000124512354456432027440 0ustar adamstaff00000000000000from sphinx import addnodes def fix_toc_entries(app, doctree): # Get the docname; I don't know why this isn't just passed in to the # callback # This seems a bit unreliable as it's undocumented, but it's not "private" # either: docname = app.builder.env.temp_data['docname'] if app.builder.env.metadata[docname].get('tocdepth', 0) != 0: # We need to reprocess any TOC nodes in the doctree and make sure all # the files listed in any TOCs are noted for treenode in doctree.traverse(addnodes.toctree): app.builder.env.note_toctree(docname, treenode) def setup(app): app.connect('doctree-read', fix_toc_entries) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/traitsdoc.py0000644000077000000240000001026112354456432027111 0ustar adamstaff00000000000000""" ========= traitsdoc ========= Sphinx extension that handles docstrings in the Numpy standard format, [1] and support Traits [2]. This extension can be used as a replacement for ``numpydoc`` when support for Traits is required. .. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard .. [2] http://code.enthought.com/projects/traits/ """ from __future__ import division, absolute_import, print_function import inspect import os import pydoc import collections from . import docscrape from . import docscrape_sphinx from .docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString from . import numpydoc from . import comment_eater class SphinxTraitsDoc(SphinxClassDoc): def __init__(self, cls, modulename='', func_doc=SphinxFunctionDoc): if not inspect.isclass(cls): raise ValueError("Initialise using a class. Got %r" % cls) self._cls = cls if modulename and not modulename.endswith('.'): modulename += '.' self._mod = modulename self._name = cls.__name__ self._func_doc = func_doc docstring = pydoc.getdoc(cls) docstring = docstring.split('\n') # De-indent paragraph try: indent = min(len(s) - len(s.lstrip()) for s in docstring if s.strip()) except ValueError: indent = 0 for n,line in enumerate(docstring): docstring[n] = docstring[n][indent:] self._doc = docscrape.Reader(docstring) self._parsed_data = { 'Signature': '', 'Summary': '', 'Description': [], 'Extended Summary': [], 'Parameters': [], 'Returns': [], 'Raises': [], 'Warns': [], 'Other Parameters': [], 'Traits': [], 'Methods': [], 'See Also': [], 'Notes': [], 'References': '', 'Example': '', 'Examples': '', 'index': {} } self._parse() def _str_summary(self): return self['Summary'] + [''] def _str_extended_summary(self): return self['Description'] + self['Extended Summary'] + [''] def __str__(self, indent=0, func_role="func"): out = [] out += self._str_signature() out += self._str_index() + [''] out += self._str_summary() out += self._str_extended_summary() for param_list in ('Parameters', 'Traits', 'Methods', 'Returns','Raises'): out += self._str_param_list(param_list) out += self._str_see_also("obj") out += self._str_section('Notes') out += self._str_references() out += self._str_section('Example') out += self._str_section('Examples') out = self._str_indent(out,indent) return '\n'.join(out) def looks_like_issubclass(obj, classname): """ Return True if the object has a class or superclass with the given class name. Ignores old-style classes. """ t = obj if t.__name__ == classname: return True for klass in t.__mro__: if klass.__name__ == classname: return True return False def get_doc_object(obj, what=None, config=None): if what is None: if inspect.isclass(obj): what = 'class' elif inspect.ismodule(obj): what = 'module' elif isinstance(obj, collections.Callable): what = 'function' else: what = 'object' if what == 'class': doc = SphinxTraitsDoc(obj, '', func_doc=SphinxFunctionDoc, config=config) if looks_like_issubclass(obj, 'HasTraits'): for name, trait, comment in comment_eater.get_class_traits(obj): # Exclude private traits. if not name.startswith('_'): doc['Traits'].append((name, trait, comment.splitlines())) return doc elif what in ('function', 'method'): return SphinxFunctionDoc(obj, '', config=config) else: return SphinxDocString(pydoc.getdoc(obj), config=config) def setup(app): # init numpydoc numpydoc.setup(app, get_doc_object) astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/utils.py0000644000077000000240000000443312354456432026261 0ustar adamstaff00000000000000import inspect import sys def find_mod_objs(modname, onlylocals=False): """ Returns all the public attributes of a module referenced by name. .. note:: The returned list *not* include subpackages or modules of `modname`,nor does it include private attributes (those that beginwith '_' or are not in `__all__`). Parameters ---------- modname : str The name of the module to search. onlylocals : bool If True, only attributes that are either members of `modname` OR one of its modules or subpackages will be included. Returns ------- localnames : list of str A list of the names of the attributes as they are named in the module `modname` . fqnames : list of str A list of the full qualified names of the attributes (e.g., ``astropy.utils.misc.find_mod_objs``). For attributes that are simple variables, this is based on the local name, but for functions or classes it can be different if they are actually defined elsewhere and just referenced in `modname`. objs : list of objects A list of the actual attributes themselves (in the same order as the other arguments) """ __import__(modname) mod = sys.modules[modname] if hasattr(mod, '__all__'): pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__] else: pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_'] # filter out modules and pull the names and objs out ismodule = inspect.ismodule localnames = [k for k, v in pkgitems if not ismodule(v)] objs = [v for k, v in pkgitems if not ismodule(v)] # fully qualified names can be determined from the object's module fqnames = [] for obj, lnm in zip(objs, localnames): if hasattr(obj, '__module__') and hasattr(obj, '__name__'): fqnames.append(obj.__module__ + '.' + obj.__name__) else: fqnames.append(modname + '.' + lnm) if onlylocals: valids = [fqn.startswith(modname) for fqn in fqnames] localnames = [e for i, e in enumerate(localnames) if valids[i]] fqnames = [e for i, e in enumerate(fqnames) if valids[i]] objs = [e for i, e in enumerate(objs) if valids[i]] return localnames, fqnames, objs astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/ext/viewcode.py0000644000077000000240000001743712425434461026733 0ustar adamstaff00000000000000# -*- coding: utf-8 -*- """ sphinx.ext.viewcode ~~~~~~~~~~~~~~~~~~~ Add links to module code in Python object descriptions. :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. Patched using patch in https://bitbucket.org/birkenfeld/sphinx/issue/623/extension-viewcode-fails-with-function on 21 Aug 2013 by Kyle H Barbary """ from docutils import nodes from sphinx import addnodes from sphinx.locale import _ from sphinx.pycode import ModuleAnalyzer from sphinx.util.nodes import make_refnode import sys import traceback if sys.version < '3': text_type = unicode else: text_type = str from ...utils import iteritems def doctree_read(app, doctree): env = app.builder.env if not hasattr(env, '_viewcode_modules'): env._viewcode_modules = {} def get_full_modname(modname, attribute): try: __import__(modname) except Exception as error: if not app.quiet: app.info(traceback.format_exc().rstrip()) app.warn('viewcode can\'t import %s, failed with error "%s"' % (modname, error)) return None module = sys.modules[modname] try: # Allow an attribute to have multiple parts and incidentially allow # repeated .s in the attribute. attr = attribute.split('.') value = module for attr in attribute.split('.'): if attr: value = getattr(value, attr) except AttributeError: app.warn('Didn\'t find %s in %s' % (attribute, module.__name__)) return None else: return getattr(value, '__module__', None) def has_tag(modname, fullname, docname, refname): entry = env._viewcode_modules.get(modname, None) if entry is None: try: analyzer = ModuleAnalyzer.for_module(modname) except Exception: env._viewcode_modules[modname] = False return analyzer.find_tags() if not isinstance(analyzer.code, text_type): code = analyzer.code.decode(analyzer.encoding) else: code = analyzer.code entry = code, analyzer.tags, {}, refname env._viewcode_modules[modname] = entry elif entry is False: return _, tags, used, _ = entry if fullname in tags: used[fullname] = docname return True for objnode in doctree.traverse(addnodes.desc): if objnode.get('domain') != 'py': continue names = set() for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue modname = signode.get('module') fullname = signode.get('fullname') refname = modname if env.config.viewcode_import: modname = get_full_modname(modname, fullname) if not modname: continue if not has_tag(modname, fullname, env.docname, refname): continue if fullname in names: # only one link per name, please continue names.add(fullname) pagename = '_modules/' + modname.replace('.', '/') onlynode = addnodes.only(expr='html') onlynode += addnodes.pending_xref( '', reftype='viewcode', refdomain='std', refexplicit=False, reftarget=pagename, refid=fullname, refdoc=env.docname) onlynode[0] += nodes.inline('', _('[source]'), classes=['viewcode-link']) signode += onlynode def missing_reference(app, env, node, contnode): # resolve our "viewcode" reference nodes -- they need special treatment if node['reftype'] == 'viewcode': return make_refnode(app.builder, node['refdoc'], node['reftarget'], node['refid'], contnode) def collect_pages(app): env = app.builder.env if not hasattr(env, '_viewcode_modules'): return highlighter = app.builder.highlighter urito = app.builder.get_relative_uri modnames = set(env._viewcode_modules) app.builder.info(' (%d module code pages)' % len(env._viewcode_modules), nonl=1) for modname, entry in iteritems(env._viewcode_modules): if not entry: continue code, tags, used, refname = entry # construct a page name for the highlighted source pagename = '_modules/' + modname.replace('.', '/') # highlight the source using the builder's highlighter highlighted = highlighter.highlight_block(code, 'python', linenos=False) # split the code into lines lines = highlighted.splitlines() # split off wrap markup from the first line of the actual code before, after = lines[0].split('
')
        lines[0:1] = [before + '
', after]
        # nothing to do for the last line; it always starts with 
anyway # now that we have code lines (starting at index 1), insert anchors for # the collected tags (HACK: this only works if the tag boundaries are # properly nested!) maxindex = len(lines) - 1 for name, docname in iteritems(used): type, start, end = tags[name] backlink = urito(pagename, docname) + '#' + refname + '.' + name lines[start] = ( '
%s' % (name, backlink, _('[docs]')) + lines[start]) lines[min(end - 1, maxindex)] += '
' # try to find parents (for submodules) parents = [] parent = modname while '.' in parent: parent = parent.rsplit('.', 1)[0] if parent in modnames: parents.append({ 'link': urito(pagename, '_modules/' + parent.replace('.', '/')), 'title': parent}) parents.append({'link': urito(pagename, '_modules/index'), 'title': _('Module code')}) parents.reverse() # putting it all together context = { 'parents': parents, 'title': modname, 'body': _('

Source code for %s

') % modname + \ '\n'.join(lines) } yield (pagename, context, 'page.html') if not modnames: return app.builder.info(' _modules/index') html = ['\n'] # the stack logic is needed for using nested lists for submodules stack = [''] for modname in sorted(modnames): if modname.startswith(stack[-1]): stack.append(modname + '.') html.append('
    ') else: stack.pop() while not modname.startswith(stack[-1]): stack.pop() html.append('
') stack.append(modname + '.') html.append('
  • %s
  • \n' % ( urito('_modules/index', '_modules/' + modname.replace('.', '/')), modname)) html.append('' * (len(stack) - 1)) context = { 'title': _('Overview: module code'), 'body': _('

    All modules for which code is available

    ') + \ ''.join(html), } yield ('_modules/index', context, 'page.html') def setup(app): app.add_config_value('viewcode_import', True, False) app.connect('doctree-read', doctree_read) app.connect('html-collect-pages', collect_pages) app.connect('missing-reference', missing_reference) #app.add_config_value('viewcode_include_modules', [], 'env') #app.add_config_value('viewcode_exclude_modules', [], 'env') astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/local/0000755000077000000240000000000012505171566025035 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/local/python3links.inv0000644000077000000240000000050012354456432030213 0ustar adamstaff00000000000000# Sphinx inventory version 2 # Project: Python # Version: 3.4 # The remainder of this file is compressed using zlib. xœ¥‘Á‚0 †ï{ /zØŒWïxÖÄ€Yflص ¼½0Ð  ‰—-ë¾ÿë–æOšî\°ÕT9›ÈSbª3쎟šW%Õf—VŠ{UƒcJQh54Ëì·8…BR¸ü š66žàyJ›Ìû-FÓ# áÅàIõG×€]k¼ ƒjÅ …vV3"XR#xu {ô:è×-Ñ÷!{\3i šiÁ?Ý"F)ú¿2¨Û°Fýã}PÎQ)¬,í'è>õ×ð7astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/local/python3links.txt0000644000077000000240000000140312354456432030241 0ustar adamstaff00000000000000# Sphinx inventory version 2 # Project: Python # Version: 3.4 # The remainder of this file should be compressed using zlib. bytes py:function -1 library/functions.html#bytes - TimeoutError py:exception -1 library/exceptions.html#TimeoutError - object py:function -1 library/functions.html#object - object py:class -1 library/functions.html#object - urllib.request.urlopen py:function -1 library/urllib.request.html#urllib.request.urlopen - concurrent.futures.Future py:class -1 library/concurrent.futures.html#concurrent.futures.Future - concurrent.futures.ThreadPoolExecutor py:class -1 library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor - queue.Queue py:class -1 library/queue.html#queue.Queue - print() py:function -1 library/functions.html#print - astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/setup_package.py0000644000077000000240000000050412354456432027127 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst def get_package_data(): # Install the theme files return { 'astropy_helpers.sphinx': [ 'ext/templates/*/*', 'local/*.inv', 'themes/bootstrap-astropy/*.*', 'themes/bootstrap-astropy/static/*.*']} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/0000755000077000000240000000000012505171566025230 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/0000755000077000000240000000000012505171566030744 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.html0000644000077000000240000000011112354456432033571 0ustar adamstaff00000000000000

    Table of Contents

    {{ toctree(maxdepth=-1, titles_only=true) }} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html0000644000077000000240000000655012354456432033155 0ustar adamstaff00000000000000{% extends "basic/layout.html" %} {# Collapsible sidebar script from default/layout.html in Sphinx #} {% set script_files = script_files + ['_static/sidebar.js'] %} {# Add the google webfonts needed for the logo #} {% block extrahead %} {% if not embedded %}{% endif %} {% endblock %} {% block header %}
    {{ theme_logotext1 }}{{ theme_logotext2 }}{{ theme_logotext3 }}
    • Index
    • Modules
    • {% block sidebarsearch %} {% include "searchbox.html" %} {% endblock %}
    {% endblock %} {% block relbar1 %} {% endblock %} {# Silence the bottom relbar. #} {% block relbar2 %}{% endblock %} {%- block footer %}

    {%- if edit_on_github %} {{ edit_on_github_page_message }}   {%- endif %} {%- if show_source and has_source and sourcename %} {{ _('Page Source') }} {%- endif %}   Back to Top

    {%- if show_copyright %} {%- if hasdoc('copyright') %} {% trans path=pathto('copyright'), copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}
    {%- else %} {% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}
    {%- endif %} {%- endif %} {%- if show_sphinx %} {% trans sphinx_version=sphinx_version|e %}Created using Sphinx {{ sphinx_version }}.{% endtrans %}   {%- endif %} {%- if last_updated %} {% trans last_updated=last_updated|e %}Last built {{ last_updated }}.{% endtrans %}
    {%- endif %}

    {%- endblock %} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.html0000644000077000000240000000004212354456432033426 0ustar adamstaff00000000000000

    Page Contents

    {{ toc }} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.html0000644000077000000240000000042012354456432033604 0ustar adamstaff00000000000000{%- if pagename != "search" %}
    {%- endif %} astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/0000755000077000000240000000000012505171566032233 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.pngastroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_link0000644000077000000240000000327512354456432034703 0ustar adamstaff00000000000000‰PNG  IHDR[â8A bKGDÿÿÿ ½§“ oFFsvek pHYs × ×B(›x vpAg\@0¢Ð¬IDATXÃå˜iŒ_SÆϘÚ+Új‹fF« BH‘XbOÐέ†ª}‰-Z¤Abû¢$¤Öi…V#¸T•ZCÕ– µIi™ÚU”d¦ª÷ý›;·÷?™)Ó*OrsïyÏsÏûžçžóžs®è!ج’ôLOùÙ`[À–=é`œ3|¼±;»1`{ÛͶﱽÔv]mú«ßØÞX°=˜l¦y’Zjs„á@30ŒlÈ<,éÝ’ÆöÆ @+ð60SÒ϶ûÇG½í‰ñü¡¤mo œ¬‘t—íþÀ%À `¶¤4üÔ pÐX<,’Ô1¦„:`•R~qÂPà` ð.°0kœÐ¨WJéŒs¶@R>)é÷ÎÀ´Ntž$éS`6p6pTØím¢5…—ÿÆHš“s8˜Éã{à@`»¿ ÷J:×v=ð%``/à9`çàœ/iší~À\`ÿbŸ{ƒçœH7KBäÝ€§"Æ“o€f¥´:¡/°hRÊʱ' J™\"ö`ànàÜ*ý[!©ÍöåÀ”ˆÿ `'I­ØÆö¶µ}Ÿí ¶o´Ý9÷#Ûg›Ùþ6ì l²}’í—m¿h[¶›lO·ýeð~ŽòtÛgE;õnÇÛkmϳ=Ëö^ÑÎKQ¿&âš~*¸² Ò NøÑ §ìµNxÊ ×æl30¡L-'ÌwÂ~¥uö ÛOÒ lOŒ˜Ïm)†ÙÞ©`»"×±ÁakÈÙšs\"5äߟ[m,ˆÝfû˜Bý±¹ú 9{ígÃþ[Œþ¼Ø“ªØà„'(Ê8á}'ëðú;aqÑ^{N•:l_q-ãÔHZ"éëx©.„Ü5ÇkŠû×ÀOñ|[ì86—„¤_Y?Ü-éé‚í¸¸ÿB6m‰8×wDqkÚ×… ÚÊ(eY´5$ʯwdz"ðD%¿—iZMh²´1/éѪbÛîmûZÛŸ‘åÒ¸0Çë] ŒV’-Ž_Ù¾9öÕ냲…ª1îK%­)Ôå®AÝðÓBûº08­À9•lî *±íN¶à'’ž M/ÎØÛÛo×;·GcJ=IÏÛ€€þÀeÀ›¶û®§àÕ:T6’܆ò}ÖæÊ³€£œP à„F 7°¸“6J}Kú h,ÌÐa¡S‡ÎŒŠV`¤¤‹%½üXU é[I—»WEÀÿˆÔ°<îM¶‹;¤Á¹çeÝh³1ÏWÊjà% 2úF3;I!±ËF6’Z ¦âÇ¥†ÈcÀrIKªtªÝ›=¢"€¤VIS€rªà·¸°½Y7Å®ï·ÎÈù8/ŠmÀü®4æ„}Õdg‡<¦çÄóhàÁ.4§.p*Úv»ø*žw·}=YJ9ÖÝÙ¼,²=øì”…9ú;À @_`†í¹ÀÊ.þ'IÉöê#{lï |Hv868·Hú¦ðÞÞNRòûï-ÈRãÍ%£öM Þ ûµJÿšQÕÐVCvNé öŒ¶¸&ìk"À“ÉrrÉv$Ä•Ç:ŽŒidi¥8%®WiµU!i­íÑÀcáçÒ\õÀý¹XóÌsÂL²…w7`2°¸o?)8áNàqàÖ.ŠØd{rxS˜yÙ¾ÓÞ¸˜,¡¯î—ôží1À²³ýòàöŽúß‘”æåOtÁ\ V $MSë©A{UÒGeÑFºj&;öö#›IIZg‹dK| ó€=ÉÆJYTM'lE¶»¤”–ÎÔ‹³Äé]ü(¯Hú üMq¨¹h=ÞÛÏ ¯lˆkþ~›<&wmGÿk±pYº™½!üõäÿì%âÿÈ#ÀædëÀX¥·h=…ÿ’ØSß»À3p5™Ø‹óÛĞƟ ½§pÅ%tEXtdate:create2012-10-18T20:57:33+02:00¢p_f%tEXtdate:modify2012-10-18T20:57:33+02:00Ó-çÚtEXtSoftwarewww.inkscape.org›î<IEND®B`‚././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.icoastroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo0000644000077000000240000000217612354456432034705 0ustar adamstaff00000000000000 h(  × × $ý'ýüùü* ümîïþ“dmýƒüU$ýýý#ý"ý!ý%ý"ý1ü2ý üª ýû‘šþÿÿÿÿþ4Eýþüÿýîý•ýü'ý.þ-þ%ü 3üüá6ýÿàäþýõøþüG\ýûüûüý üþüÿ üí&üH )ý,ý=þû'ý¶+ýÿÝâþøÇÓþþ#ýÿ!ýþl…ýþ¨´þþœªþýKiýú!ýþ$ýý/ýP.ý-ý@þC$ýÿwþý÷úþþ 3ýþ DþÿåëþÿúûÿÿÁÎþÿÐÚþþÿÿÿÿÅÐþü;þÿ-ýñ=þ%3þ>þˆ4ýÿØáþü•«þþ$ýÿÏÚþÿÉ×þÿ4ýÿ"ýÿ"ýÿ RþþáêþÿÅÒþú6ýÿ;þ¨.ýBý¨JþÿøúþüRþþTþÿÿÿÿÿ0aþÿIxþÿ¼Îþÿœ¸þÿ Býÿ UþþÿÿÿþW‚þÿ8ýöTþ-Lý RþÿõùþüX‰þþ_þÿöøþÿ´Ëþÿÿÿÿÿûüþÿÿÿÿÿœ»þÿ5ýÿ¿Ðþþ°ÉþüAýÿSþt\þtOýÿÈÛþü®ÉþþCýÿ»Òþÿÿÿÿÿÿÿÿÿ¶Ïþÿ¡ÂþÿÐàþÿBýÿ˜¸þþÏàþüNýÿZþ mþ-XýöNþÿÿÿÿþKþþWýÿWšþÿGþÿ\ýÿÔãþÿ¢ÆþÿIýÿ®Ëþþ¿×þüVýÿdþ¨oýmþ¨dýÿŠ»þúÿÿÿÿ¢Çþþ@ŽþÿN–þÿÔåþÿíõþÿuþÿdýÿð÷þþy°þü_ýÿoþˆuþsþ%uþñmýÿR¢þüÕéþÿûþþþùýþÿ´Øþÿþÿ{þÿ»Úþþëôþþ~ýýqýÿvþC{þþ}þP€þývþþvþú ‚þý€þþtþþoþþ¬Ôþÿÿÿÿþ¼þøtþÿ€þ¶ÿiý}þˆÿ…ÿH‰ÿí‰ÿÿ†ÿþ…ÿý ŒÿûNªÿû—Îþü[²þý‹ÿÿ†ÿá…þ…ÿyýxý€þÿŽþþ”‘þî‘þÿ‘þþ:«þþ þÿ‡ÿúþªþšÿ‡þÿ…ÿ„ÿƒÿ‰ÿ“ÿ˜ÿ—ÿU—ÿ€ÿˆšÿl¤ÿ*zÿ~þ…þ‚þ$@ €€€€@ P$ ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.pngastroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo0000644000077000000240000000353412354456432034704 0ustar adamstaff00000000000000‰PNG  IHDR szzôsBIT|dˆ pHYsÓÇòŽtEXtSoftwarewww.inkscape.org›î<ÙIDATX…Å—PT×Ç?÷ñc‘P° ˆ „FƒUBìȘ&Ådi”I# ±ÒÄJhC2æÇŒ5ÑÔtw:íÛª5ÑÒSÒÆª©é„Ú¡%¨ZÉF2Vk­JFŒ`ÁŠ(JdÙ÷öÝþqaß., É?½3gæ½sÏïýžûΞº®óÿ\Ñ_ÄÉ•ìÎ#šÅHŠl ø2pèZ€Ý8ØãéÔ¯KL”Wš;†AC°È‹h4¥z>ÕÀ$?ñôé—#¹hJ~‹»œ›´`;&y˜#D²ËÂß b0¨Â¤Åu‹»2RìqKàJr'âã7˜<6.´;`Îã2Ò‹@‹†Ž&°Ìa‹$`›+Æâ1ôWB]Ç, w.rÆM¶|»r€Þh?G6B—m"ù‘GêÕïKàƒ…“œ0º#Ñ&¢: WBÅaˆË°mL6¸pÏ€+àΔƒx¥Áti@D1Çä;«áz§ v³ú7zCýrׇóE9ÎÐäš ‹,“é_Gÿ±hbÞˆy•ˆ;¾Ñ Ðñ!,e÷ÙUÄ—¦AÚlˆO†„©ˆ€-^;V€¬…~ï;MçÅðKxUZùK%:Lü剜"¸ë9äžáT½rÝë†3WCúWaá8úè9ô³`p4XW·;KšxBjó«ËwÙÉ¥„Ö÷á“ýÐÚׇ.WêLDå_e5Êw`ÎDîzFíG;ßz9ì¾?@ÈghI^Ž ÄâUˆ¥›Ô³áƒÆMÈl…+çíãÇÄs%bñZˆK„»Ÿ‚Ão@ûÅ`ó!8¹ò—À¬o‚)Ô!ÔÊpu¹4W›;Uü0ˆ0×i'÷Ý@V— ë\Ð}>üÖßôÁž Èu Àôƒˆï¾ ¦übdëÇ‘‰Yáþ>rµ¡z—c0iØI,\1D‹‰ÜX §)‡Ìùׇˆ×üˆ__…Šm cáB3ì߬|f̃¹ÙI.œ²KŸ;ò“NÖ¤AqÐ!~*Üùr8Þg)ã¬BÄß…¬;!*â'#î©DÔôÁürdÓN;Ql’ à|(€Ùá Xôj®€[Ã`aPy÷ã* ÷ר—¦Ô¥h¹bâO½¶Î 9el¢­ïë 0HÆi¦a29HáReÜÝ 5*Ã@ä)}豄 ¢cU5ö»aÙIr mý0›Jú€nARÂPÊør‡j­&5â“+Þðçõ£AL:éµKðAƒÍ\îÿ´ž eà'_Œ໩âlg'ò›Èm/!7|ü¾p7z‘¯T@ß5å—0 KÕÞ¹Àg†öƒ ú@/fHN|ׯ@b bÁÃÈú8X‹lü,yf} ºÚ ®ú•ˆU; )U1·o»bSµ j€~Ú¦‚aS2!&A”8¼/‡‚û ¿Ž7ªhu¯Ž.@ùó0¿D=¿_oo nIøý/© Ió”è70è¦FÞ§¬&%ÀýÁ¶,Ô*}t â—ƒ{Ë#ÿ$'Ï@ütbÅËʾç?ÈuO„Ú j&Á¡DèºÎK î-T㎉E4| )épá,ò;·Ûí³ôˆµ¿…¨!ÊÎ7ÿ¼Èö3ˆiÙ0ý6X°“Ô¾¹ò8önðôB°ÚSjOEÑšÅNi 0ýÈÚ-ˆg<0c&”T@Ãe]· ùßKˆ» .²ó ;©Þzäæç¡³-Tû³™R[åt:iºÝy±è„·‹,, å4âÑçÝEBÛY8{Z5˜öðîFô÷A¬¦¤ƒÐK]àä?‘úÓð»upíjèLñ©,ñ<«÷…" ^?aReÁ ÀAO/¬YŽØü–±áHKCî}K7ÿÙ¼V='N†´ èhß@$.:4Á}žr½säFp"jÊw^ùÆqo?%Š…føä$¢äâþ2HÍ€÷€°O6àƒžËà75E)iנس\o™FÌ„ë*õj¬þ”î{YU†¬¢üI´¿…ܹ㠦!bò¦¦Qà©Ð[Ç¢&âX¾¶Æ])àWHTÿ]º í…ŸAÖ­Ê`Їu×W ëâXq;¤dÍúgõÚ± "20¼Ö¯Ð·k·að:µobÝ3¹u‹2pÄ!}rô¸nÒ,TjÝäN$9Là¿¡k“{rÀâAMP*a¦Öri.©išÜ[ï—ËÊÎ h“Ш™ì÷¼¨7O$éç0 Ë•Lg§$3ó3Çãÿ¼ G®ÿ.Á½8<ßÇIEND®B`‚././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.cssastroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-as0000644000077000000240000002647012425434461034602 0ustar adamstaff00000000000000/*! * Bootstrap v1.4.0 * * Copyright 2011 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Heavily modified by Kyle Barbary for the AstroPy Project for use with Sphinx. */ @import url("basic.css"); body { background-color: #ffffff; margin: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: normal; line-height: 18px; color: #404040; } /* Hyperlinks ----------------------------------------------------------------*/ a { color: #0069d6; text-decoration: none; line-height: inherit; font-weight: inherit; } a:hover { color: #00438a; text-decoration: underline; } /* Typography ----------------------------------------------------------------*/ h1,h2,h3,h4,h5,h6 { color: #404040; margin: 0.7em 0 0 0; line-height: 1.5em; } h1 { font-size: 24px; margin: 0; } h2 { font-size: 21px; line-height: 1.2em; margin: 1em 0 0.5em 0; border-bottom: 1px solid #404040; } h3 { font-size: 18px; } h4 { font-size: 16px; } h5 { font-size: 14px; } h6 { font-size: 13px; text-transform: uppercase; } p { font-size: 13px; font-weight: normal; line-height: 18px; margin-top: 0px; margin-bottom: 9px; } ul, ol { margin-left: 0; padding: 0 0 0 25px; } ul ul, ul ol, ol ol, ol ul { margin-bottom: 0; } ul { list-style: disc; } ol { list-style: decimal; } li { line-height: 18px; color: #404040; } ul.unstyled { list-style: none; margin-left: 0; } dl { margin-bottom: 18px; } dl dt, dl dd { line-height: 18px; } dl dd { margin-left: 9px; } hr { margin: 20px 0 19px; border: 0; border-bottom: 1px solid #eee; } strong { font-style: inherit; font-weight: bold; } em { font-style: italic; font-weight: inherit; line-height: inherit; } .muted { color: #bfbfbf; } address { display: block; line-height: 18px; margin-bottom: 18px; } code, pre { padding: 0 3px 2px; font-family: monospace; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } tt { font-family: monospace; } code { color: rgba(0, 0, 0, 0.75); padding: 1px 3px; } pre { display: block; padding: 8.5px; margin: 0 0 18px; line-height: 18px; border: 1px solid #ddd; border: 1px solid rgba(0, 0, 0, 0.12); -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; white-space: pre; white-space: pre-wrap; word-wrap: break-word; } img { margin: 9px 0; } /* format inline code with a rounded box */ tt { margin: 0 2px; padding: 0 5px; border: 1px solid #ddd; border: 1px solid rgba(0, 0, 0, 0.12); border-radius: 3px; } /* all code has same box background color, even in headers */ h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt, pre, code, tt { background-color: #f8f8f8; } /* override box for links & other sphinx-specifc stuff */ tt.xref, a tt, tt.descname, tt.descclassname { padding: 0 1px 0 1px; border: none; } /* override box for related bar at the top of the page */ .related tt { border: none; padding: 0 1px 0 1px; background-color: transparent; font-weight: bold; } th { background-color: #dddddd; } .viewcode-back { font-family: sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; } table.docutils { border-spacing: 5px; border-collapse: separate; } /* Topbar --------------------------------------------------------------------*/ div.topbar { height: 40px; position: absolute; top: 0; left: 0; right: 0; z-index: 10000; padding: 0px 10px; background-color: #222; background-color: #222222; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); background-image: -moz-linear-gradient(top, #333333, #222222); background-image: -ms-linear-gradient(top, #333333, #222222); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); background-image: -webkit-linear-gradient(top, #333333, #222222); background-image: -o-linear-gradient(top, #333333, #222222); background-image: linear-gradient(top, #333333, #222222); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); } div.topbar a.brand { font-family: 'Source Sans Pro', sans-serif; font-size: 26px; color: #ffffff; font-weight: 600; text-decoration: none; float: left; display: block; height: 32px; padding: 8px 12px 0px 45px; margin-left: -10px; background: transparent url("astropy_logo_32.png") no-repeat 10px 4px; } #logotext1 { } #logotext2 { font-weight:200; color: #ff5000; } #logotext3 { font-weight:200; } div.topbar .brand:hover, div.topbar ul li a.homelink:hover { background-color: #333; background-color: rgba(255, 255, 255, 0.05); } div.topbar ul { font-size: 110%; list-style: none; margin: 0; padding: 0 0 0 10px; float: right; color: #bfbfbf; text-align: center; text-decoration: none; height: 100%; } div.topbar ul li { float: left; display: inline; height: 30px; margin: 5px; padding: 0px; } div.topbar ul li a { color: #bfbfbf; text-decoration: none; padding: 5px; display: block; height: auto; text-align: center; vertical-align: middle; border-radius: 4px; } div.topbar ul li a:hover { color: #ffffff; text-decoration: none; } div.topbar ul li a.homelink { width: 112px; display: block; height: 20px; padding: 5px 0px; background: transparent url("astropy_linkout_20.png") no-repeat 10px 5px; } div.topbar form { text-align: left; margin: 0 0 0 5px; position: relative; filter: alpha(opacity=100); -khtml-opacity: 1; -moz-opacity: 1; opacity: 1; } div.topbar input { background-color: #444; background-color: rgba(255, 255, 255, 0.3); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: normal; font-weight: 13px; line-height: 1; padding: 4px 9px; color: #ffffff; color: rgba(255, 255, 255, 0.75); border: 1px solid #111; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; transition: none; } div.topbar input:-moz-placeholder { color: #e6e6e6; } div.topbar input::-webkit-input-placeholder { color: #e6e6e6; } div.topbar input:hover { background-color: #bfbfbf; background-color: rgba(255, 255, 255, 0.5); color: #ffffff; } div.topbar input:focus, div.topbar input.focused { outline: 0; background-color: #ffffff; color: #404040; text-shadow: 0 1px 0 #ffffff; border: 0; padding: 5px 10px; -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); } /* Relation bar (breadcrumbs, prev, next) ------------------------------------*/ div.related { height: 21px; width: auto; margin: 0 10px; position: absolute; top: 42px; clear: both; left: 0; right: 0; z-index: 10000; font-size: 100%; vertical-align: middle; background-color: #fff; border-bottom: 1px solid #bbb; } div.related ul { padding: 0; margin: 0; } /* Footer --------------------------------------------------------------------*/ footer { display: block; margin: 10px 10px 0px; padding: 10px 0 0 0; border-top: 1px solid #bbb; } .pull-right { float: right; width: 30em; text-align: right; } /* Sphinx sidebar ------------------------------------------------------------*/ div.sphinxsidebar { font-size: inherit; border-radius: 3px; background-color: #eee; border: 1px solid #bbb; } div.sphinxsidebarwrapper { padding: 0px 0px 0px 5px; } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; font-size: 1.4em; font-weight: normal; margin: 5px 0px 0px 5px; padding: 0; line-height: 1.6em; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 0px 0px 0px 5px; padding: 0; } div.sphinxsidebar ul ul { margin-left: 15px; list-style-type: disc; } /* If showing the global TOC (toctree), color the current page differently */ div.sphinxsidebar a.current { color: #404040; } div.sphinxsidebar a.current:hover { color: #404040; } /* document, documentwrapper, body, bodywrapper ----------------------------- */ div.document { margin-top: 72px; margin-left: 10px; margin-right: 10px; } div.documentwrapper { float: left; width: 100%; } div.body { background-color: #ffffff; padding: 0 0 0px 20px; } div.bodywrapper { margin: 0 0 0 230px; max-width: 55em; } /* Header links ------------------------------------------------------------- */ a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } a.headerlink:hover { background-color: #0069d6; color: white; text-docoration: none; } /* Admonitions and warnings ------------------------------------------------- */ /* Shared by admonitions and warnings */ div.admonition, div.warning { padding: 0px; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } div.admonition p, div.warning p { margin: 0.5em 1em 0.5em 1em; padding: 0; } div.admonition pre, div.warning pre { margin: 0.4em 1em 0.4em 1em; } div.admonition p.admonition-title, div.warning p.admonition-title { margin: 0; padding: 0.1em 0 0.1em 0.5em; color: white; font-weight: bold; font-size: 1.1em; } div.admonition ul, div.admonition ol, div.warning ul, div.warning ol { margin: 0.1em 0.5em 0.5em 3em; padding: 0; } /* Admonitions only */ div.admonition { border: 1px solid #609060; background-color: #e9ffe9; } div.admonition p.admonition-title { background-color: #70A070; } /* Warnings only */ div.warning { border: 1px solid #900000; background-color: #ffe9e9; } div.warning p.admonition-title { background-color: #b04040; } /* Figures ------------------------------------------------------------------ */ .figure.align-center { clear: none; } /* This is a div for containing multiple figures side-by-side, for use with * .. container:: figures */ div.figures { border: 1px solid #CCCCCC; background-color: #F8F8F8; margin: 1em; text-align: center; } div.figures .figure { clear: none; float: none; display: inline-block; border: none; margin-left: 0.5em; margin-right: 0.5em; } .field-list th { white-space: nowrap; } table.field-list { border-spacing: 0px; margin-left: 1px; border-left: 5px solid rgb(238, 238, 238) !important; } table.field-list th.field-name { display: inline-block; padding: 1px 8px 1px 5px; white-space: nowrap; background-color: rgb(238, 238, 238); border-radius: 0 3px 3px 0; -webkit-border-radius: 0 3px 3px 0; } ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.jsastroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.j0000644000077000000240000000467712354456432034632 0ustar adamstaff00000000000000$(document).ready(function() { /* Add a [>>>] button on the top-right corner of code samples to hide * the >>> and ... prompts and the output and thus make the code * copyable. */ var div = $('.highlight-python .highlight,' + '.highlight-python3 .highlight') var pre = div.find('pre'); // get the styles from the current theme pre.parent().parent().css('position', 'relative'); var hide_text = 'Hide the prompts and output'; var show_text = 'Show the prompts and output'; var border_width = pre.css('border-top-width'); var border_style = pre.css('border-top-style'); var border_color = pre.css('border-top-color'); var button_styles = { 'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0', 'border-color': border_color, 'border-style': border_style, 'border-width': border_width, 'color': border_color, 'text-size': '75%', 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em', 'border-radius': '0 3px 0 0' } // create and add the button to all the code blocks that contain >>> div.each(function(index) { var jthis = $(this); if (jthis.find('.gp').length > 0) { var button = $('>>>'); button.css(button_styles) button.attr('title', hide_text); jthis.prepend(button); } // tracebacks (.gt) contain bare text elements that need to be // wrapped in a span to work with .nextUntil() (see later) jthis.find('pre:has(.gt)').contents().filter(function() { return ((this.nodeType == 3) && (this.data.trim().length > 0)); }).wrap(''); }); // define the behavior of the button when it's clicked $('.copybutton').toggle( function() { var button = $(this); button.parent().find('.go, .gp, .gt').hide(); button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden'); button.css('text-decoration', 'line-through'); button.attr('title', show_text); }, function() { var button = $(this); button.parent().find('.go, .gp, .gt').show(); button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible'); button.css('text-decoration', 'none'); button.attr('title', hide_text); }); }); astroquery-0.2.4/astropy_helpers/astropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.js0000644000077000000240000001155312354456432034207 0ustar adamstaff00000000000000/* * sidebar.js * ~~~~~~~~~~ * * This script makes the Sphinx sidebar collapsible. * * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton * used to collapse and expand the sidebar. * * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden * and the width of the sidebar and the margin-left of the document * are decreased. When the sidebar is expanded the opposite happens. * This script saves a per-browser/per-session cookie used to * remember the position of the sidebar among the pages. * Once the browser is closed the cookie is deleted and the position * reset to the default (expanded). * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ $(function() { // global elements used by the functions. // the 'sidebarbutton' element is defined as global after its // creation, in the add_sidebar_button function var bodywrapper = $('.bodywrapper'); var sidebar = $('.sphinxsidebar'); var sidebarwrapper = $('.sphinxsidebarwrapper'); // for some reason, the document has no sidebar; do not run into errors if (!sidebar.length) return; // original margin-left of the bodywrapper and width of the sidebar // with the sidebar expanded var bw_margin_expanded = bodywrapper.css('margin-left'); var ssb_width_expanded = sidebar.width(); // margin-left of the bodywrapper and width of the sidebar // with the sidebar collapsed var bw_margin_collapsed = 12; var ssb_width_collapsed = 12; // custom colors var dark_color = '#404040'; var light_color = '#505050'; function sidebar_is_collapsed() { return sidebarwrapper.is(':not(:visible)'); } function toggle_sidebar() { if (sidebar_is_collapsed()) expand_sidebar(); else collapse_sidebar(); } function collapse_sidebar() { sidebarwrapper.hide(); sidebar.css('width', ssb_width_collapsed); bodywrapper.css('margin-left', bw_margin_collapsed); sidebarbutton.css({ 'margin-left': '-1px', 'height': bodywrapper.height(), 'border-radius': '3px' }); sidebarbutton.find('span').text('»'); sidebarbutton.attr('title', _('Expand sidebar')); document.cookie = 'sidebar=collapsed'; } function expand_sidebar() { bodywrapper.css('margin-left', bw_margin_expanded); sidebar.css('width', ssb_width_expanded); sidebarwrapper.show(); sidebarbutton.css({ 'margin-left': ssb_width_expanded - 12, 'height': bodywrapper.height(), 'border-radius': '0px 3px 3px 0px' }); sidebarbutton.find('span').text('«'); sidebarbutton.attr('title', _('Collapse sidebar')); document.cookie = 'sidebar=expanded'; } function add_sidebar_button() { sidebarwrapper.css({ 'float': 'left', 'margin-right': '0', 'width': ssb_width_expanded - 18 }); // create the button sidebar.append('
    «
    '); var sidebarbutton = $('#sidebarbutton'); // find the height of the viewport to center the '<<' in the page var viewport_height; if (window.innerHeight) viewport_height = window.innerHeight; else viewport_height = $(window).height(); var sidebar_offset = sidebar.offset().top; var sidebar_height = Math.max(bodywrapper.height(), sidebar.height()); sidebarbutton.find('span').css({ 'font-family': '"Lucida Grande",Arial,sans-serif', 'display': 'block', 'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10, 'width': 12, 'position': 'fixed', 'text-align': 'center' }); sidebarbutton.click(toggle_sidebar); sidebarbutton.attr('title', _('Collapse sidebar')); sidebarbutton.css({ 'color': '#FFFFFF', 'background-color': light_color, 'border': '1px solid ' + light_color, 'border-radius': '0px 3px 3px 0px', 'font-size': '1.2em', 'cursor': 'pointer', 'height': sidebar_height, 'padding-top': '1px', 'margin': '-1px', 'margin-left': ssb_width_expanded - 12 }); sidebarbutton.hover( function () { $(this).css('background-color', dark_color); }, function () { $(this).css('background-color', light_color); } ); } function set_position_from_cookie() { if (!document.cookie) return; var items = document.cookie.split(';'); for(var k=0; k /*************************************************************************** * Macros for determining the compiler version. * * These are borrowed from boost, and majorly abridged to include only * the compilers we care about. ***************************************************************************/ #ifndef PY3K #if PY_MAJOR_VERSION >= 3 #define PY3K 1 #else #define PY3K 0 #endif #endif #define STRINGIZE(X) DO_STRINGIZE(X) #define DO_STRINGIZE(X) #X #if defined __clang__ /* Clang C++ emulates GCC, so it has to appear early. */ # define COMPILER "Clang version " __clang_version__ #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) /* Intel */ # if defined(__INTEL_COMPILER) # define INTEL_VERSION __INTEL_COMPILER # elif defined(__ICL) # define INTEL_VERSION __ICL # elif defined(__ICC) # define INTEL_VERSION __ICC # elif defined(__ECC) # define INTEL_VERSION __ECC # endif # define COMPILER "Intel C compiler version " STRINGIZE(INTEL_VERSION) #elif defined(__GNUC__) /* gcc */ # define COMPILER "GCC version " __VERSION__ #elif defined(__SUNPRO_CC) /* Sun Workshop Compiler */ # define COMPILER "Sun compiler version " STRINGIZE(__SUNPRO_CC) #elif defined(_MSC_VER) /* Microsoft Visual C/C++ Must be last since other compilers define _MSC_VER for compatibility as well */ # if _MSC_VER < 1200 # define COMPILER_VERSION 5.0 # elif _MSC_VER < 1300 # define COMPILER_VERSION 6.0 # elif _MSC_VER == 1300 # define COMPILER_VERSION 7.0 # elif _MSC_VER == 1310 # define COMPILER_VERSION 7.1 # elif _MSC_VER == 1400 # define COMPILER_VERSION 8.0 # elif _MSC_VER == 1500 # define COMPILER_VERSION 9.0 # elif _MSC_VER == 1600 # define COMPILER_VERSION 10.0 # else # define COMPILER_VERSION _MSC_VER # endif # define COMPILER "Microsoft Visual C++ version " STRINGIZE(COMPILER_VERSION) #else /* Fallback */ # define COMPILER "Unknown compiler" #endif /*************************************************************************** * Module-level ***************************************************************************/ struct module_state { /* The Sun compiler can't handle empty structs */ #if defined(__SUNPRO_C) || defined(_MSC_VER) int _dummy; #endif }; #if PY3K static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_compiler", NULL, sizeof(struct module_state), NULL, NULL, NULL, NULL, NULL }; #define INITERROR return NULL PyMODINIT_FUNC PyInit__compiler(void) #else #define INITERROR return PyMODINIT_FUNC init_compiler(void) #endif { PyObject* m; #if PY3K m = PyModule_Create(&moduledef); #else m = Py_InitModule3("_compiler", NULL, NULL); #endif if (m == NULL) INITERROR; PyModule_AddStringConstant(m, "compiler", COMPILER); #if PY3K return m; #endif } astroquery-0.2.4/astropy_helpers/astropy_helpers/src/setup_package.py0000644000077000000240000000011312354456432026401 0ustar adamstaff00000000000000def get_package_data(): return {'astropy_helpers.src': ['compiler.c']} astroquery-0.2.4/astropy_helpers/astropy_helpers/test_helpers.py0000644000077000000240000002065212464715714025515 0ustar adamstaff00000000000000from __future__ import (absolute_import, division, print_function, unicode_literals) import os import shutil import subprocess import sys import tempfile from distutils.core import Command from .compat import _fix_user_options PY3 = sys.version_info[0] == 3 class AstropyTest(Command, object): description = 'Run the tests for this package' user_options = [ ('package=', 'P', "The name of a specific package to test, e.g. 'io.fits' or 'utils'. " "If nothing is specified, all default tests are run."), ('test-path=', 't', 'Specify a test location by path. If a relative path to a .py file, ' 'it is relative to the built package, so e.g., a leading "astropy/" ' 'is necessary. If a relative path to a .rst file, it is relative to ' 'the directory *below* the --docs-path directory, so a leading ' '"docs/" is usually necessary. May also be an absolute path.'), ('verbose-results', 'V', 'Turn on verbose output from pytest.'), ('plugins=', 'p', 'Plugins to enable when running pytest.'), ('pastebin=', 'b', "Enable pytest pastebin output. Either 'all' or 'failed'."), ('args=', 'a', 'Additional arguments to be passed to pytest.'), ('remote-data', 'R', 'Run tests that download remote data.'), ('pep8', '8', 'Enable PEP8 checking and disable regular tests. ' 'Requires the pytest-pep8 plugin.'), ('pdb', 'd', 'Start the interactive Python debugger on errors.'), ('coverage', 'c', 'Create a coverage report. Requires the coverage package.'), ('open-files', 'o', 'Fail if any tests leave files open.'), ('parallel=', 'j', 'Run the tests in parallel on the specified number of ' 'CPUs. If negative, all the cores on the machine will be ' 'used. Requires the pytest-xdist plugin.'), ('docs-path=', None, 'The path to the documentation .rst files. If not provided, and ' 'the current directory contains a directory called "docs", that ' 'will be used.'), ('skip-docs', None, "Don't test the documentation .rst files.") ] user_options = _fix_user_options(user_options) package_name = '' def initialize_options(self): self.package = None self.test_path = None self.verbose_results = False self.plugins = None self.pastebin = None self.args = None self.remote_data = False self.pep8 = False self.pdb = False self.coverage = False self.open_files = False self.parallel = 0 self.docs_path = None self.skip_docs = False def finalize_options(self): # Normally we would validate the options here, but that's handled in # run_tests pass def run(self): try: import astropy except ImportError: raise ImportError( "The 'test' command requires the astropy package to be " "installed and importable.") self.reinitialize_command('build', inplace=False) self.run_command('build') build_cmd = self.get_finalized_command('build') new_path = os.path.abspath(build_cmd.build_lib) if self.docs_path is None: if os.path.exists('docs'): self.docs_path = os.path.abspath('docs') else: self.docs_path = os.path.abspath(self.docs_path) # Copy the build to a temporary directory for the purposes of testing # - this avoids creating pyc and __pycache__ directories inside the # build directory tmp_dir = tempfile.mkdtemp(prefix=self.package_name + '-test-') testing_path = os.path.join(tmp_dir, os.path.basename(new_path)) shutil.copytree(new_path, testing_path) shutil.copy('setup.cfg', testing_path) cmd_pre = '' cmd_post = '' try: if self.coverage: if self.parallel != 0: raise ValueError( "--coverage can not be used with --parallel") try: import coverage except ImportError: raise ImportError( "--coverage requires that the coverage package is " "installed.") # Don't use get_pkg_data_filename here, because it # requires importing astropy.config and thus screwing # up coverage results for those packages. coveragerc = os.path.join( testing_path, self.package_name, 'tests', 'coveragerc') # We create a coveragerc that is specific to the version # of Python we're running, so that we can mark branches # as being specifically for Python 2 or Python 3 with open(coveragerc, 'r') as fd: coveragerc_content = fd.read() if PY3: ignore_python_version = '2' else: ignore_python_version = '3' coveragerc_content = coveragerc_content.replace( "{ignore_python_version}", ignore_python_version).replace( "{packagename}", self.package_name) tmp_coveragerc = os.path.join(tmp_dir, 'coveragerc') with open(tmp_coveragerc, 'wb') as tmp: tmp.write(coveragerc_content.encode('utf-8')) cmd_pre = ( 'import coverage; ' 'cov = coverage.coverage(data_file="{0}", config_file="{1}"); ' 'cov.start();'.format( os.path.abspath(".coverage"), tmp_coveragerc)) cmd_post = ( 'cov.stop(); ' 'from astropy.tests.helper import _save_coverage; ' '_save_coverage(cov, result, "{0}", "{1}");'.format( os.path.abspath('.'), testing_path)) if PY3: set_flag = "import builtins; builtins._ASTROPY_TEST_ = True" else: set_flag = "import __builtin__; __builtin__._ASTROPY_TEST_ = True" cmd = ('{cmd_pre}{0}; import {1.package_name}, sys; result = (' '{1.package_name}.test(' 'package={1.package!r}, ' 'test_path={1.test_path!r}, ' 'args={1.args!r}, ' 'plugins={1.plugins!r}, ' 'verbose={1.verbose_results!r}, ' 'pastebin={1.pastebin!r}, ' 'remote_data={1.remote_data!r}, ' 'pep8={1.pep8!r}, ' 'pdb={1.pdb!r}, ' 'open_files={1.open_files!r}, ' 'parallel={1.parallel!r}, ' 'docs_path={1.docs_path!r}, ' 'skip_docs={1.skip_docs!r})); ' '{cmd_post}' 'sys.exit(result)') cmd = cmd.format(set_flag, self, cmd_pre=cmd_pre, cmd_post=cmd_post) # Run the tests in a subprocess--this is necessary since # new extension modules may have appeared, and this is the # easiest way to set up a new environment # Remove temporary directory # On Python 3.x prior to 3.3, the creation of .pyc files # is not atomic. py.test jumps through some hoops to make # this work by parsing import statements and carefully # importing files atomically. However, it can't detect # when __import__ is used, so its carefulness still fails. # The solution here (admittedly a bit of a hack), is to # turn off the generation of .pyc files altogether by # passing the `-B` switch to `python`. This does mean # that each core will have to compile .py file to bytecode # itself, rather than getting lucky and borrowing the work # already done by another core. Compilation is an # insignificant fraction of total testing time, though, so # it's probably not worth worrying about. retcode = subprocess.call([sys.executable, '-B', '-c', cmd], cwd=testing_path, close_fds=False) finally: shutil.rmtree(tmp_dir) raise SystemExit(retcode) astroquery-0.2.4/astropy_helpers/astropy_helpers/tests/0000755000077000000240000000000012505171566023574 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers/tests/__init__.py0000644000077000000240000000700712425434461025706 0ustar adamstaff00000000000000import os import subprocess as sp import sys import pytest PACKAGE_DIR = os.path.dirname(__file__) def run_cmd(cmd, args, path=None, raise_error=True): """ Runs a shell command with the given argument list. Changes directory to ``path`` if given, otherwise runs the command in the current directory. Returns a 3-tuple of (stdout, stderr, exit code) If ``raise_error=True`` raise an exception on non-zero exit codes. """ if path is not None: # Transparently support py.path objects path = str(path) p = sp.Popen([cmd] + list(args), stdout=sp.PIPE, stderr=sp.PIPE, cwd=path) streams = tuple(s.decode('latin1').strip() for s in p.communicate()) return_code = p.returncode if raise_error and return_code != 0: raise RuntimeError( "The command `{0}` with args {1!r} exited with code {2}.\n" "Stdout:\n\n{3}\n\nStderr:\n\n{4}".format( cmd, list(args), return_code, streams[0], streams[1])) return streams + (return_code,) @pytest.fixture(scope='function', autouse=True) def reset_setup_helpers(request): """ Saves and restores the global state of the astropy_helpers.setup_helpers module between tests. """ mod = __import__('astropy_helpers.setup_helpers', fromlist=['']) old_state = mod._module_state.copy() def finalizer(old_state=old_state): mod = sys.modules.get('astropy_helpers.setup_helpers') if mod is not None: mod._module_state.update(old_state) request.addfinalizer(finalizer) @pytest.fixture(scope='function', autouse=True) def reset_distutils_log(): """ This is a setup/teardown fixture that ensures the log-level of the distutils log is always set to a default of WARN, since different settings could affect tests that check the contents of stdout. """ from distutils import log log.set_threshold(log.WARN) TEST_PACKAGE_SETUP_PY = """\ #!/usr/bin/env python from setuptools import setup NAME = 'astropy-helpers-test' VERSION = {version!r} setup(name=NAME, version=VERSION, packages=['_astropy_helpers_test_'], zip_safe=False) """ @pytest.fixture def testpackage(tmpdir, version='0.1'): """ This fixture creates a simplified package called _astropy_helpers_test_ used primarily for testing ah_boostrap, but without using the astropy_helpers package directly and getting it confused with the astropy_helpers package already under test. """ source = tmpdir.mkdir('testpkg') with source.as_cwd(): source.mkdir('_astropy_helpers_test_') init = source.join('_astropy_helpers_test_', '__init__.py') init.write('__version__ = {0!r}'.format(version)) setup_py = TEST_PACKAGE_SETUP_PY.format(version=version) source.join('setup.py').write(setup_py) # Make the new test package into a git repo run_cmd('git', ['init']) run_cmd('git', ['add', '--all']) run_cmd('git', ['commit', '-m', 'test package']) return source def cleanup_import(package_name): """Remove all references to package_name from sys.modules""" for k in list(sys.modules): if not isinstance(k, str): # Some things will actually do this =_= continue elif k.startswith('astropy_helpers.tests'): # Don't delete imported test modules or else the tests will break, # badly continue if k == package_name or k.startswith(package_name + '.'): del sys.modules[k] astroquery-0.2.4/astropy_helpers/astropy_helpers/tests/test_ah_bootstrap.py0000644000077000000240000003345612425434461027702 0ustar adamstaff00000000000000# -*- coding: utf-8 -*- import glob import os import textwrap import sys from distutils.version import StrictVersion import setuptools from setuptools.package_index import PackageIndex from setuptools.sandbox import run_setup import pytest from . import * from ..utils import silence TEST_SETUP_PY = """\ #!/usr/bin/env python from __future__ import print_function import os import sys import ah_bootstrap # reset the name of the package installed by ah_boostrap to # _astropy_helpers_test_--this will prevent any confusion by pkg_resources with # any already installed packages named astropy_helpers # We also disable auto-upgrade by default ah_bootstrap.DIST_NAME = 'astropy-helpers-test' ah_bootstrap.PACKAGE_NAME = '_astropy_helpers_test_' ah_bootstrap.AUTO_UPGRADE = False ah_bootstrap.DOWNLOAD_IF_NEEDED = False try: ah_bootstrap.use_astropy_helpers({args}) finally: ah_bootstrap.DIST_NAME = 'astropy-helpers' ah_bootstrap.PACKAGE_NAME = 'astropy_helpers' ah_bootstrap.AUTO_UPGRADE = True ah_bootstrap.DOWNLOAD_IF_NEEDED = True import _astropy_helpers_test_ filename = os.path.abspath(_astropy_helpers_test_.__file__) filename = filename.replace('.pyc', '.py') # More consistent this way print(filename) """ # The behavior checked in some of the tests depends on the version of # setuptools try: SETUPTOOLS_VERSION = StrictVersion(setuptools.__version__).version except: # Broken setuptools? ¯\_(ツ)_/¯ SETUPTOOLS_VERSION = (0, 0, 0) def test_bootstrap_from_submodule(tmpdir, testpackage, capsys): """ Tests importing _astropy_helpers_test_ from a submodule in a git repository. This tests actually performing a fresh clone of the repository without the submodule initialized, and that importing astropy_helpers in that context works transparently after calling `ah_boostrap.use_astropy_helpers`. """ orig_repo = tmpdir.mkdir('orig') # Ensure ah_bootstrap is imported from the local directory import ah_bootstrap with orig_repo.as_cwd(): run_cmd('git', ['init']) # Write a test setup.py that uses ah_bootstrap; it also ensures that # any previous reference to astropy_helpers is first wiped from # sys.modules orig_repo.join('setup.py').write(TEST_SETUP_PY.format(args='')) run_cmd('git', ['add', 'setup.py']) # Add our own clone of the astropy_helpers repo as a submodule named # astropy_helpers run_cmd('git', ['submodule', 'add', str(testpackage), '_astropy_helpers_test_']) run_cmd('git', ['commit', '-m', 'test repository']) os.chdir(str(tmpdir)) # Creates a clone of our test repo in the directory 'clone' run_cmd('git', ['clone', 'orig', 'clone']) os.chdir('clone') run_setup('setup.py', []) stdout, stderr = capsys.readouterr() path = stdout.strip() # Ensure that the astropy_helpers used by the setup.py is the one that # was imported from git submodule a = os.path.normcase(path) b = os.path.normcase(str(tmpdir.join('clone', '_astropy_helpers_test_', '_astropy_helpers_test_', '__init__.py'))) assert a == b def test_bootstrap_from_submodule_no_locale(tmpdir, testpackage, capsys, monkeypatch): """ Regression test for https://github.com/astropy/astropy/issues/2749 Runs test_bootstrap_from_submodule but with missing locale/langauge settings. """ for varname in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'): monkeypatch.delenv(varname, raising=False) test_bootstrap_from_submodule(tmpdir, testpackage, capsys) def test_bootstrap_from_submodule_bad_locale(tmpdir, testpackage, capsys, monkeypatch): """ Additional regression test for https://github.com/astropy/astropy/issues/2749 """ for varname in ('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'): monkeypatch.delenv(varname, raising=False) # Test also with bad LC_CTYPE a la http://bugs.python.org/issue18378 monkeypatch.setenv('LC_CTYPE', 'UTF-8') test_bootstrap_from_submodule(tmpdir, testpackage, capsys) def test_check_submodule_no_git(tmpdir, testpackage): """ Tests that when importing astropy_helpers from a submodule, it is still recognized as a submodule even when using the --no-git option. In particular this ensures that the auto-upgrade feature is not activated. """ orig_repo = tmpdir.mkdir('orig') # Ensure ah_bootstrap is imported from the local directory import ah_bootstrap with orig_repo.as_cwd(): run_cmd('git', ['init']) # Write a test setup.py that uses ah_bootstrap; it also ensures that # any previous reference to astropy_helpers is first wiped from # sys.modules args = 'auto_upgrade=True' orig_repo.join('setup.py').write(TEST_SETUP_PY.format(args=args)) run_cmd('git', ['add', 'setup.py']) # Add our own clone of the astropy_helpers repo as a submodule named # astropy_helpers run_cmd('git', ['submodule', 'add', str(testpackage), '_astropy_helpers_test_']) run_cmd('git', ['commit', '-m', 'test repository']) # Temporarily patch _do_upgrade to fail if called class UpgradeError(Exception): pass def _do_upgrade(*args, **kwargs): raise UpgradeError() orig_do_upgrade = ah_bootstrap._do_upgrade ah_bootstrap._do_upgrade = _do_upgrade try: run_setup('setup.py', ['--no-git']) except UpgradeError: pytest.fail('Attempted to run auto-upgrade despite importing ' '_astropy_helpers_test_ from a git submodule') finally: ah_bootstrap._do_upgrade = orig_do_upgrade def test_bootstrap_from_directory(tmpdir, testpackage, capsys): """ Tests simply bundling a copy of the astropy_helpers source code in its entirety bundled directly in the source package and not in an archive. """ import ah_bootstrap source = tmpdir.mkdir('source') testpackage.copy(source.join('_astropy_helpers_test_')) with source.as_cwd(): source.join('setup.py').write(TEST_SETUP_PY.format(args='')) run_setup('setup.py', []) stdout, stderr = capsys.readouterr() stdout = stdout.splitlines() if stdout: path = stdout[-1].strip() else: path = '' # Ensure that the astropy_helpers used by the setup.py is the one that # was imported from git submodule a = os.path.normcase(path) b = os.path.normcase(str(source.join('_astropy_helpers_test_', '_astropy_helpers_test_', '__init__.py'))) assert a == b def test_bootstrap_from_archive(tmpdir, testpackage, capsys): """ Tests importing _astropy_helpers_test_ from a .tar.gz source archive shipped alongside the package that uses it. """ orig_repo = tmpdir.mkdir('orig') # Ensure ah_bootstrap is imported from the local directory import ah_bootstrap # Make a source distribution of the test package with silence(): run_setup(str(testpackage.join('setup.py')), ['sdist', '--dist-dir=dist', '--formats=gztar']) dist_dir = testpackage.join('dist') for dist_file in dist_dir.visit('*.tar.gz'): dist_file.copy(orig_repo) with orig_repo.as_cwd(): # Write a test setup.py that uses ah_bootstrap; it also ensures that # any previous reference to astropy_helpers is first wiped from # sys.modules args = 'path={0!r}'.format(os.path.basename(str(dist_file))) orig_repo.join('setup.py').write(TEST_SETUP_PY.format(args=args)) run_setup('setup.py', []) stdout, stderr = capsys.readouterr() path = stdout.splitlines()[-1].strip() # Installation from the .tar.gz should have resulted in a .egg # directory that the _astropy_helpers_test_ package was imported from eggs = _get_local_eggs() assert eggs egg = orig_repo.join(eggs[0]) assert os.path.isdir(str(egg)) a = os.path.normcase(path) b = os.path.normcase(str(egg.join('_astropy_helpers_test_', '__init__.py'))) assert a == b def test_download_if_needed(tmpdir, testpackage, capsys): """ Tests the case where astropy_helpers was not actually included in a package, or is otherwise missing, and we need to "download" it. This does not test actually downloading from the internet--this is normally done through setuptools' easy_install command which can also install from a source archive. From the point of view of ah_boostrap the two actions are equivalent, so we can just as easily simulate this by providing a setup.cfg giving the path to a source archive to "download" (as though it were a URL). """ source = tmpdir.mkdir('source') # Ensure ah_bootstrap is imported from the local directory import ah_bootstrap # Make a source distribution of the test package with silence(): run_setup(str(testpackage.join('setup.py')), ['sdist', '--dist-dir=dist', '--formats=gztar']) dist_dir = testpackage.join('dist') with source.as_cwd(): source.join('setup.py').write(TEST_SETUP_PY.format( args='download_if_needed=True')) source.join('setup.cfg').write(textwrap.dedent("""\ [easy_install] find_links = {find_links} """.format(find_links=str(dist_dir)))) run_setup('setup.py', []) stdout, stderr = capsys.readouterr() # Just take the last line--on Python 2.6 distutils logs warning # messages to stdout instead of stderr, causing them to be mixed up # with our expected output path = stdout.splitlines()[-1].strip() # easy_install should have worked by 'installing' astropy_helpers as a # .egg in the current directory eggs = _get_local_eggs() assert eggs egg = source.join(eggs[0]) assert os.path.isdir(str(egg)) a = os.path.normcase(path) b = os.path.normcase(str(egg.join('_astropy_helpers_test_', '__init__.py'))) assert a == b def test_upgrade(tmpdir, capsys): # Run the testpackage fixture manually, since we use it multiple times in # this test to make different versions of _astropy_helpers_test_ orig_dir = testpackage(tmpdir.mkdir('orig')) # Make a test package that uses _astropy_helpers_test_ source = tmpdir.mkdir('source') dist_dir = source.mkdir('dists') orig_dir.copy(source.join('_astropy_helpers_test_')) with source.as_cwd(): setup_py = TEST_SETUP_PY.format(args='auto_upgrade=True') source.join('setup.py').write(setup_py) # This will be used to later to fake downloading the upgrade package source.join('setup.cfg').write(textwrap.dedent("""\ [easy_install] find_links = {find_links} """.format(find_links=str(dist_dir)))) # Make additional "upgrade" versions of the _astropy_helpers_test_ # package--one of them is version 0.2 and the other is version 0.1.1. The # auto-upgrade should ignore version 0.2 but use version 0.1.1. upgrade_dir_1 = testpackage(tmpdir.mkdir('upgrade_1'), version='0.2') upgrade_dir_2 = testpackage(tmpdir.mkdir('upgrade_2'), version='0.1.1') dists = [] # For each upgrade package go ahead and build a source distribution of it # and copy that source distribution to a dist directory we'll use later to # simulate a 'download' for upgrade_dir in [upgrade_dir_1, upgrade_dir_2]: with silence(): run_setup(str(upgrade_dir.join('setup.py')), ['sdist', '--dist-dir=dist', '--formats=gztar']) dists.append(str(upgrade_dir.join('dist'))) for dist_file in upgrade_dir.visit('*.tar.gz'): dist_file.copy(source.join('dists')) # Monkey with the PackageIndex in ah_bootstrap so that it is initialized # with the test upgrade packages, and so that it does not actually go out # to the internet to look for anything import ah_bootstrap class FakePackageIndex(PackageIndex): def __init__(self, *args, **kwargs): PackageIndex.__init__(self, *args, **kwargs) self.to_scan = dists def find_packages(self, requirement): # no-op pass ah_bootstrap.PackageIndex = FakePackageIndex try: with source.as_cwd(): # Now run the source setup.py; this test is similar to # test_download_if_needed, but we explicitly check that the correct # *version* of _astropy_helpers_test_ was used run_setup('setup.py', []) stdout, stderr = capsys.readouterr() path = stdout.splitlines()[-1].strip() eggs = _get_local_eggs() assert eggs egg = source.join(eggs[0]) assert os.path.isdir(str(egg)) a = os.path.normcase(path) b = os.path.normcase(str(egg.join('_astropy_helpers_test_', '__init__.py'))) assert a == b assert 'astropy_helpers_test-0.1.1-' in str(egg) finally: ah_bootstrap.PackageIndex = PackageIndex def _get_local_eggs(path='.'): """ Helper utility used by some tests to get the list of egg archive files in a local directory. """ if SETUPTOOLS_VERSION[0] >= 7: eggs = glob.glob(os.path.join(path, '.eggs', '*.egg')) else: eggs = glob.glob('*.egg') return eggs astroquery-0.2.4/astropy_helpers/astropy_helpers/tests/test_git_helpers.py0000644000077000000240000001216612425434461027515 0ustar adamstaff00000000000000import glob import imp import os import pkgutil import re import sys import tarfile from setuptools.sandbox import run_setup from . import * PY3 = sys.version_info[0] == 3 if PY3: _text_type = str else: _text_type = unicode _DEV_VERSION_RE = re.compile(r'\d+\.\d+(?:\.\d+)?\.dev(\d+)') TEST_VERSION_SETUP_PY = """\ #!/usr/bin/env python from setuptools import setup NAME = '_eva_' VERSION = {version!r} RELEASE = 'dev' not in VERSION from astropy_helpers.git_helpers import get_git_devstr from astropy_helpers.version_helpers import generate_version_py if not RELEASE: VERSION += get_git_devstr(False) generate_version_py(NAME, VERSION, RELEASE, False) setup(name=NAME, version=VERSION, packages=['_eva_']) """ TEST_VERSION_INIT = """\ try: from .version import version as __version__ from .version import githash as __githash__ except ImportError: __version__ = __githash__ = '' """ @pytest.fixture def version_test_package(tmpdir, request, version='42.42.dev'): test_package = tmpdir.mkdir('test_package') test_package.join('setup.py').write( TEST_VERSION_SETUP_PY.format(version=version)) test_package.mkdir('_eva_').join('__init__.py').write(TEST_VERSION_INIT) with test_package.as_cwd(): run_cmd('git', ['init']) run_cmd('git', ['add', '--all']) run_cmd('git', ['commit', '-m', 'test package']) if '' in sys.path: sys.path.remove('') sys.path.insert(0, '') def finalize(): cleanup_import('_eva_') request.addfinalizer(finalize) return test_package def test_update_git_devstr(version_test_package, capsys): """Tests that the commit number in the package's version string updates after git commits even without re-running setup.py. """ with version_test_package.as_cwd(): run_setup('setup.py', ['--version']) stdout, stderr = capsys.readouterr() version = stdout.strip() m = _DEV_VERSION_RE.match(version) assert m, ( "Stdout did not match the version string pattern:" "\n\n{0}\n\nStderr:\n\n{1}".format(stdout, stderr)) revcount = int(m.group(1)) import _eva_ assert _eva_.__version__ == version # Make a silly git commit with open('.test', 'w'): pass run_cmd('git', ['add', '.test']) run_cmd('git', ['commit', '-m', 'test']) import _eva_.version imp.reload(_eva_.version) # Previously this checked packagename.__version__, but in order for that to # be updated we also have to re-import _astropy_init which could be tricky. # Checking directly that the packagename.version module was updated is # sufficient: m = _DEV_VERSION_RE.match(_eva_.version.version) assert m assert int(m.group(1)) == revcount + 1 # This doesn't test astropy_helpers.get_helpers.update_git_devstr directly # since a copy of that function is made in packagename.version (so that it # can work without astropy_helpers installed). In order to get test # coverage on the actual astropy_helpers copy of that function just call it # directly and compare to the value in packagename from astropy_helpers.git_helpers import update_git_devstr newversion = update_git_devstr(version, path=str(version_test_package)) assert newversion == _eva_.version.version def test_installed_git_version(version_test_package, tmpdir, capsys): """ Test for https://github.com/astropy/astropy-helpers/issues/87 Ensures that packages installed with astropy_helpers have a correct copy of the git hash of the installed commit. """ # To test this, it should suffice to build a source dist, unpack it # somewhere outside the git repository, and then do a build and import # from the build directory--no need to "install" as such with version_test_package.as_cwd(): run_setup('setup.py', ['build']) try: import _eva_ githash = _eva_.__githash__ assert githash and isinstance(githash, _text_type) finally: cleanup_import('_eva_') run_setup('setup.py', ['sdist', '--dist-dir=dist', '--formats=gztar']) tgzs = glob.glob(os.path.join('dist', '*.tar.gz')) assert len(tgzs) == 1 tgz = version_test_package.join(tgzs[0]) build_dir = tmpdir.mkdir('build_dir') tf = tarfile.open(str(tgz), mode='r:gz') tf.extractall(str(build_dir)) with build_dir.as_cwd(): pkg_dir = glob.glob('_eva_-*')[0] os.chdir(pkg_dir) run_setup('setup.py', ['build']) try: import _eva_ loader = pkgutil.get_loader('_eva_') # Ensure we are importing the 'packagename' that was just unpacked # into the build_dir if sys.version_info[:2] != (3, 3): # Skip this test on Python 3.3 wherein the SourceFileLoader # has a bug where get_filename() does not return an absolute # path assert loader.get_filename().startswith(str(build_dir)) assert _eva_.__githash__ == githash finally: cleanup_import('_eva_') astroquery-0.2.4/astropy_helpers/astropy_helpers/tests/test_setup_helpers.py0000644000077000000240000001237512464715714030102 0ustar adamstaff00000000000000import sys from textwrap import dedent from setuptools.sandbox import run_setup from .. import setup_helpers from ..setup_helpers import get_package_info, register_commands from . import * def test_cython_autoextensions(tmpdir): """ Regression test for https://github.com/astropy/astropy-helpers/pull/19 Ensures that Cython extensions in sub-packages are discovered and built only once. """ # Make a simple test package test_pkg = tmpdir.mkdir('test_pkg') test_pkg.mkdir('yoda').mkdir('luke') test_pkg.ensure('yoda', '__init__.py') test_pkg.ensure('yoda', 'luke', '__init__.py') test_pkg.join('yoda', 'luke', 'dagobah.pyx').write( """def testfunc(): pass""") # Required, currently, for get_package_info to work register_commands('yoda', '0.0', False) package_info = get_package_info(str(test_pkg)) assert len(package_info['ext_modules']) == 1 assert package_info['ext_modules'][0].name == 'yoda.luke.dagobah' def test_no_cython_buildext(tmpdir): """ Regression test for https://github.com/astropy/astropy-helpers/pull/35 This tests the custom build_ext command installed by astropy_helpers when used with a project that has no Cython extensions (but does have one or more normal C extensions). """ # In order for this test to test the correct code path we need to fool # setup_helpers into thinking we don't have Cython installed setup_helpers._module_state['have_cython'] = False test_pkg = tmpdir.mkdir('test_pkg') test_pkg.mkdir('_eva_').ensure('__init__.py') # TODO: It might be later worth making this particular test package into a # reusable fixture for other build_ext tests # A minimal C extension for testing test_pkg.join('_eva_').join('unit01.c').write(dedent("""\ #include #ifndef PY3K #if PY_MAJOR_VERSION >= 3 #define PY3K 1 #else #define PY3K 0 #endif #endif #if PY3K static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "unit01", NULL, -1, NULL }; PyMODINIT_FUNC PyInit_unit01(void) { return PyModule_Create(&moduledef); } #else PyMODINIT_FUNC initunit01(void) { Py_InitModule3("unit01", NULL, NULL); } #endif """)) test_pkg.join('setup.py').write(dedent("""\ from os.path import join from setuptools import setup, Extension from astropy_helpers.setup_helpers import register_commands NAME = '_eva_' VERSION = 0.1 RELEASE = True cmdclassd = register_commands(NAME, VERSION, RELEASE) setup( name=NAME, version=VERSION, cmdclass=cmdclassd, ext_modules=[Extension('_eva_.unit01', [join('_eva_', 'unit01.c')])] ) """)) test_pkg.chdir() run_setup('setup.py', ['build_ext', '--inplace']) sys.path.insert(0, str(test_pkg)) try: import _eva_.unit01 dirname = os.path.abspath(os.path.dirname(_eva_.unit01.__file__)) assert dirname == str(test_pkg.join('_eva_')) finally: cleanup_import('_eva_') sys.path.remove(str(test_pkg)) @pytest.mark.parametrize('capture_warnings', [False, True]) def test_build_sphinx(tmpdir, capture_warnings): """ Test for build_sphinx """ ah_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) test_pkg = tmpdir.mkdir('test_pkg') test_pkg.mkdir('mypackage') test_pkg.join('mypackage').join('__init__.py').write(dedent("""\ def test_function(): pass """)) docs = test_pkg.mkdir('docs') autosummary = docs.mkdir('_templates').mkdir('autosummary') autosummary.join('base.rst').write('{% extends "autosummary_core/base.rst" %}') autosummary.join('class.rst').write('{% extends "autosummary_core/class.rst" %}') autosummary.join('module.rst').write('{% extends "autosummary_core/module.rst" %}') test_pkg.join('docs').join('conf.py').write(dedent("""\ import sys sys.path.append("../") import warnings with warnings.catch_warnings(): # ignore matplotlib warning warnings.simplefilter("ignore") from astropy_helpers.sphinx.conf import * exclude_patterns.append('_templates') """)) test_pkg.join('docs').join('index.rst').write(dedent("""\ .. automodapi:: mypackage """)) test_pkg.join('setup.py').write(dedent("""\ from os.path import join from setuptools import setup, Extension from astropy_helpers.setup_helpers import register_commands, get_package_info NAME = 'mypackage' VERSION = 0.1 RELEASE = True cmdclassd = register_commands(NAME, VERSION, RELEASE) setup( name=NAME, version=VERSION, cmdclass=cmdclassd, **get_package_info() ) """)) test_pkg.chdir() import shutil shutil.copytree(ah_path, 'astropy_helpers') if capture_warnings: run_setup('setup.py', ['build_sphinx', '-w']) else: run_setup('setup.py', ['build_sphinx']) astroquery-0.2.4/astropy_helpers/astropy_helpers/utils.py0000644000077000000240000001131512464715714024150 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import contextlib import imp import os import sys # Python 3.3's importlib caches filesystem reads for faster imports in the # general case. But sometimes it's necessary to manually invalidate those # caches so that the import system can pick up new generated files. See # https://github.com/astropy/astropy/issues/820 if sys.version_info[:2] >= (3, 3): from importlib import invalidate_caches else: invalidate_caches = lambda: None class _DummyFile(object): """A noop writeable object.""" errors = '' # Required for Python 3.x def write(self, s): pass def flush(self): pass @contextlib.contextmanager def silence(): """A context manager that silences sys.stdout and sys.stderr.""" old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = _DummyFile() sys.stderr = _DummyFile() exception_occurred = False try: yield except: exception_occurred = True # Go ahead and clean up so that exception handling can work normally sys.stdout = old_stdout sys.stderr = old_stderr raise if not exception_occurred: sys.stdout = old_stdout sys.stderr = old_stderr if sys.platform == 'win32': import ctypes def _has_hidden_attribute(filepath): """ Returns True if the given filepath has the hidden attribute on MS-Windows. Based on a post here: http://stackoverflow.com/questions/284115/cross-platform-hidden-file-detection """ if isinstance(filepath, bytes): filepath = filepath.decode(sys.getfilesystemencoding()) try: attrs = ctypes.windll.kernel32.GetFileAttributesW(filepath) assert attrs != -1 result = bool(attrs & 2) except (AttributeError, AssertionError): result = False return result else: def _has_hidden_attribute(filepath): return False def is_path_hidden(filepath): """ Determines if a given file or directory is hidden. Parameters ---------- filepath : str The path to a file or directory Returns ------- hidden : bool Returns `True` if the file is hidden """ name = os.path.basename(os.path.abspath(filepath)) if isinstance(name, bytes): is_dotted = name.startswith(b'.') else: is_dotted = name.startswith('.') return is_dotted or _has_hidden_attribute(filepath) def walk_skip_hidden(top, onerror=None, followlinks=False): """ A wrapper for `os.walk` that skips hidden files and directories. This function does not have the parameter `topdown` from `os.walk`: the directories must always be recursed top-down when using this function. See also -------- os.walk : For a description of the parameters """ for root, dirs, files in os.walk( top, topdown=True, onerror=onerror, followlinks=followlinks): # These lists must be updated in-place so os.walk will skip # hidden directories dirs[:] = [d for d in dirs if not is_path_hidden(d)] files[:] = [f for f in files if not is_path_hidden(f)] yield root, dirs, files def write_if_different(filename, data): """Write `data` to `filename`, if the content of the file is different. Parameters ---------- filename : str The file name to be written to. data : bytes The data to be written to `filename`. """ assert isinstance(data, bytes) if os.path.exists(filename): with open(filename, 'rb') as fd: original_data = fd.read() else: original_data = None if original_data != data: with open(filename, 'wb') as fd: fd.write(data) def import_file(filename): """ Imports a module from a single file as if it doesn't belong to a particular package. """ # Specifying a traditional dot-separated fully qualified name here # results in a number of "Parent module 'astropy' not found while # handling absolute import" warnings. Using the same name, the # namespaces of the modules get merged together. So, this # generates an underscore-separated name which is more likely to # be unique, and it doesn't really matter because the name isn't # used directly here anyway. with open(filename, 'U') as fd: name = '_'.join( os.path.relpath(os.path.splitext(filename)[0]).split(os.sep)[1:]) return imp.load_module(name, fd, filename, ('.py', 'U', 1)) if sys.version_info[0] >= 3: def iteritems(dictionary): return dictionary.items() else: def iteritems(dictionary): return dictionary.iteritems() astroquery-0.2.4/astropy_helpers/astropy_helpers/version.py0000644000077000000240000001242012454670716024474 0ustar adamstaff00000000000000# Autogenerated by Astropy-affiliated package astropy_helpers's setup.py on 2015-01-12 08:03:42.045141 import locale import os import subprocess import warnings def _decode_stdio(stream): try: stdio_encoding = locale.getdefaultlocale()[1] or 'utf-8' except ValueError: stdio_encoding = 'utf-8' try: text = stream.decode(stdio_encoding) except UnicodeDecodeError: # Final fallback text = stream.decode('latin1') return text def update_git_devstr(version, path=None): """ Updates the git revision string if and only if the path is being imported directly from a git working copy. This ensures that the revision number in the version string is accurate. """ try: # Quick way to determine if we're in git or not - returns '' if not devstr = get_git_devstr(sha=True, show_warning=False, path=path) except OSError: return version if not devstr: # Probably not in git so just pass silently return version if 'dev' in version: # update to the current git revision version_base = version.split('.dev', 1)[0] devstr = get_git_devstr(sha=False, show_warning=False, path=path) return version_base + '.dev' + devstr else: #otherwise it's already the true/release version return version def get_git_devstr(sha=False, show_warning=True, path=None): """ Determines the number of revisions in this repository. Parameters ---------- sha : bool If True, the full SHA1 hash will be returned. Otherwise, the total count of commits in the repository will be used as a "revision number". show_warning : bool If True, issue a warning if git returns an error code, otherwise errors pass silently. path : str or None If a string, specifies the directory to look in to find the git repository. If `None`, the current working directory is used. If given a filename it uses the directory containing that file. Returns ------- devversion : str Either a string with the revision number (if `sha` is False), the SHA1 hash of the current commit (if `sha` is True), or an empty string if git version info could not be identified. """ if path is None: path = os.getcwd() if not os.path.isdir(path): path = os.path.abspath(os.path.dirname(path)) if not os.path.exists(os.path.join(path, '.git')): return '' if sha: # Faster for getting just the hash of HEAD cmd = ['rev-parse', 'HEAD'] else: cmd = ['rev-list', '--count', 'HEAD'] def run_git(cmd): try: p = subprocess.Popen(['git'] + cmd, cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate() except OSError as e: if show_warning: warnings.warn('Error running git: ' + str(e)) return (None, '', '') if p.returncode == 128: if show_warning: warnings.warn('No git repository present at {0!r}! Using ' 'default dev version.'.format(path)) return (p.returncode, '', '') if p.returncode == 129: if show_warning: warnings.warn('Your git looks old (does it support {0}?); ' 'consider upgrading to v1.7.2 or ' 'later.'.format(cmd[0])) return (p.returncode, stdout, stderr) elif p.returncode != 0: if show_warning: warnings.warn('Git failed while determining revision ' 'count: {0}'.format(_decode_stdio(stderr))) return (p.returncode, stdout, stderr) return p.returncode, stdout, stderr returncode, stdout, stderr = run_git(cmd) if not sha and returncode == 129: # git returns 129 if a command option failed to parse; in # particular this could happen in git versions older than 1.7.2 # where the --count option is not supported # Also use --abbrev-commit and --abbrev=0 to display the minimum # number of characters needed per-commit (rather than the full hash) cmd = ['rev-list', '--abbrev-commit', '--abbrev=0', 'HEAD'] returncode, stdout, stderr = run_git(cmd) # Fall back on the old method of getting all revisions and counting # the lines if returncode == 0: return str(stdout.count(b'\n')) else: return '' elif sha: return _decode_stdio(stdout)[:40] else: return _decode_stdio(stdout).strip() _last_generated_version = '0.4.4' _last_githash = u'ca3953a76d40fd16a0fe5a01b76ee526bb9a69b1' version = update_git_devstr(_last_generated_version) githash = get_git_devstr(sha=True, show_warning=False, path=__file__) or _last_githash major = 0 minor = 4 bugfix = 4 release = True debug = False try: from ._compiler import compiler except ImportError: compiler = "unknown" try: from .cython_version import cython_version except ImportError: cython_version = "unknown" astroquery-0.2.4/astropy_helpers/astropy_helpers/version_helpers.py0000644000077000000240000001436012425434461026214 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Utilities for generating the version string for Astropy (or an affiliated package) and the version.py module, which contains version info for the package. Within the generated astropy.version module, the `major`, `minor`, and `bugfix` variables hold the respective parts of the version number (bugfix is '0' if absent). The `release` variable is True if this is a release, and False if this is a development version of astropy. For the actual version string, use:: from astropy.version import version or:: from astropy import __version__ """ from __future__ import division import datetime import imp import os import pkgutil import sys from distutils import log from . import git_helpers from .setup_helpers import is_distutils_display_option, get_pkg_version_module from .utils import invalidate_caches PY3 = sys.version_info[0] == 3 def _version_split(version): """ Split a version string into major, minor, and bugfix numbers (with bugfix optional, defaulting to 0). """ for prerel in ('.dev', 'a', 'b', 'rc'): if prerel in version: version = version.split(prerel)[0] versplit = version.split('.') major = int(versplit[0]) minor = int(versplit[1]) bugfix = 0 if len(versplit) < 3 else int(versplit[2]) return major, minor, bugfix # This is used by setup.py to create a new version.py - see that file for # details. Note that the imports have to be absolute, since this is also used # by affiliated packages. _FROZEN_VERSION_PY_TEMPLATE = """ # Autogenerated by {packagename}'s setup.py on {timestamp} {header} major = {major} minor = {minor} bugfix = {bugfix} release = {rel} debug = {debug} try: from ._compiler import compiler except ImportError: compiler = "unknown" try: from .cython_version import cython_version except ImportError: cython_version = "unknown" """[1:] _FROZEN_VERSION_PY_WITH_GIT_HEADER = """ {git_helpers} _last_generated_version = {verstr!r} _last_githash = {githash!r} version = update_git_devstr(_last_generated_version) githash = get_git_devstr(sha=True, show_warning=False, path=__file__) or _last_githash """[1:] def _get_version_py_str(packagename, version, githash, release, debug, uses_git=True): timestamp = str(datetime.datetime.now()) major, minor, bugfix = _version_split(version) if packagename.lower() == 'astropy': packagename = 'Astropy' else: packagename = 'Astropy-affiliated package ' + packagename if uses_git: loader = pkgutil.get_loader(git_helpers) source = loader.get_source(git_helpers.__name__) or '' source_lines = source.splitlines() if not source_lines: log.warn('Cannot get source code for astropy_helpers.git_helpers; ' 'git support disabled.') return _get_version_py_str(packagename, version, release, debug, uses_git=False) idx = 0 for idx, line in enumerate(source_lines): if line.startswith('# BEGIN'): break git_helpers_py = '\n'.join(source_lines[idx + 1:]) if PY3: verstr = version else: # In Python 2 don't pass in a unicode string; otherwise verstr will # be represented with u'' syntax which breaks on Python 3.x with x # < 3. This is only an issue when developing on multiple Python # versions at once verstr = version.encode('utf8') new_githash = git_helpers.get_git_devstr(sha=True, show_warning=False) if new_githash: githash = new_githash header = _FROZEN_VERSION_PY_WITH_GIT_HEADER.format( git_helpers=git_helpers_py, verstr=verstr, githash=githash) else: header = 'version = {0!r}'.format(version) return _FROZEN_VERSION_PY_TEMPLATE.format(packagename=packagename, timestamp=timestamp, header=header, major=major, minor=minor, bugfix=bugfix, rel=release, debug=debug) def generate_version_py(packagename, version, release=None, debug=None, uses_git=True): """Regenerate the version.py module if necessary.""" try: version_module = get_pkg_version_module(packagename) try: last_generated_version = version_module._last_generated_version except AttributeError: last_generated_version = version_module.version try: last_githash = version_module._last_githash except AttributeError: last_githash = '' current_release = version_module.release current_debug = version_module.debug except ImportError: version_module = None last_generated_version = None last_githash = None current_release = None current_debug = None if release is None: # Keep whatever the current value is, if it exists release = bool(current_release) if debug is None: # Likewise, keep whatever the current value is, if it exists debug = bool(current_debug) version_py = os.path.join(packagename, 'version.py') if (last_generated_version != version or current_release != release or current_debug != debug): if '-q' not in sys.argv and '--quiet' not in sys.argv: log.set_threshold(log.INFO) if is_distutils_display_option(): # Always silence unnecessary log messages when display options are # being used log.set_threshold(log.WARN) log.info('Freezing version number to {0}'.format(version_py)) with open(version_py, 'w') as f: # This overwrites the actual version.py f.write(_get_version_py_str(packagename, version, last_githash, release, debug, uses_git=uses_git)) invalidate_caches() if version_module: imp.reload(version_module) astroquery-0.2.4/astropy_helpers/astropy_helpers.egg-info/0000755000077000000240000000000012505171566024124 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/astropy_helpers.egg-info/dependency_links.txt0000644000077000000240000000000112454670716030176 0ustar adamstaff00000000000000 astroquery-0.2.4/astropy_helpers/astropy_helpers.egg-info/not-zip-safe0000644000077000000240000000000112354456432026352 0ustar adamstaff00000000000000 astroquery-0.2.4/astropy_helpers/astropy_helpers.egg-info/PKG-INFO0000644000077000000240000000543112454670716025230 0ustar adamstaff00000000000000Metadata-Version: 1.1 Name: astropy-helpers Version: 0.4.4 Summary: Utilities for building and installing Astropy, Astropy affiliated packages, and their respective documentation. Home-page: http://astropy.org Author: The Astropy Developers Author-email: astropy.team@gmail.com License: BSD Download-URL: http://pypi.python.org/packages/source/a/astropy-helpers/astropy-helpers-0.4.4.tar.gz Description: astropy-helpers =============== This project provides a Python package, ``astropy_helpers``, which includes many build, installation, and documentation-related tools used by the Astropy project, but packaged separately for use by other projects that wish to leverage this work. The motivation behind this package and details of its implementation are in the accepted `Astropy Proposal for Enhancement (APE) 4 `_. ``astropy_helpers`` includes a special "bootstrap" module called ``ah_bootstrap.py`` which is intended to be used by a project's setup.py in order to ensure that the ``astropy_helpers`` package is available for build/installation. This is similar to the ``ez_setup.py`` module that is shipped with some projects to bootstrap `setuptools `_. As described in APE4, the version numbers for ``astropy_helpers`` follow the corresponding major/minor version of the `astropy core package `_, but with an independent sequence of micro (bugfix) version numbers. Hence, the initial release is 0.4, in parallel with Astropy v0.4, which will be the first version of Astropy to use ``astropy-helpers``. For examples of how to implement ``astropy-helpers`` in a project, see the ``setup.py`` and ``setup.cfg`` files of the `Affiliated package template `_. .. image:: https://travis-ci.org/astropy/astropy-helpers.png :target: https://travis-ci.org/astropy/astropy-helpers .. image:: https://coveralls.io/repos/astropy/astropy-helpers/badge.png :target: https://coveralls.io/r/astropy/astropy-helpers Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Archiving :: Packaging astroquery-0.2.4/astropy_helpers/astropy_helpers.egg-info/SOURCES.txt0000644000077000000240000000540512454670716026020 0ustar adamstaff00000000000000CHANGES.rst LICENSE.rst MANIFEST.in README.rst ah_bootstrap.py ez_setup.py setup.cfg setup.py astropy_helpers/__init__.py astropy_helpers/git_helpers.py astropy_helpers/setup_helpers.py astropy_helpers/test_helpers.py astropy_helpers/utils.py astropy_helpers/version.py astropy_helpers/version_helpers.py astropy_helpers.egg-info/PKG-INFO astropy_helpers.egg-info/SOURCES.txt astropy_helpers.egg-info/dependency_links.txt astropy_helpers.egg-info/not-zip-safe astropy_helpers.egg-info/top_level.txt astropy_helpers/compat/__init__.py astropy_helpers/compat/subprocess.py astropy_helpers/compat/_subprocess_py2/__init__.py astropy_helpers/sphinx/__init__.py astropy_helpers/sphinx/conf.py astropy_helpers/sphinx/setup_package.py astropy_helpers/sphinx/ext/__init__.py astropy_helpers/sphinx/ext/astropyautosummary.py astropy_helpers/sphinx/ext/automodapi.py astropy_helpers/sphinx/ext/automodsumm.py astropy_helpers/sphinx/ext/changelog_links.py astropy_helpers/sphinx/ext/comment_eater.py astropy_helpers/sphinx/ext/compiler_unparse.py astropy_helpers/sphinx/ext/docscrape.py astropy_helpers/sphinx/ext/docscrape_sphinx.py astropy_helpers/sphinx/ext/doctest.py astropy_helpers/sphinx/ext/edit_on_github.py astropy_helpers/sphinx/ext/numpydoc.py astropy_helpers/sphinx/ext/phantom_import.py astropy_helpers/sphinx/ext/smart_resolver.py astropy_helpers/sphinx/ext/tocdepthfix.py astropy_helpers/sphinx/ext/traitsdoc.py astropy_helpers/sphinx/ext/utils.py astropy_helpers/sphinx/ext/viewcode.py astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst astropy_helpers/sphinx/ext/templates/autosummary_core/class.rst astropy_helpers/sphinx/ext/templates/autosummary_core/module.rst astropy_helpers/sphinx/ext/tests/__init__.py astropy_helpers/sphinx/ext/tests/test_automodapi.py astropy_helpers/sphinx/ext/tests/test_automodsumm.py astropy_helpers/sphinx/ext/tests/test_docscrape.py astropy_helpers/sphinx/ext/tests/test_utils.py astropy_helpers/sphinx/local/python3links.inv astropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.html astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.html astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.html astropy_helpers/sphinx/themes/bootstrap-astropy/theme.conf astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.png astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.ico astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.css astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.js astropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.js astropy_helpers/src/__init__.py astropy_helpers/src/compiler.c astropy_helpers/src/setup_package.pyastroquery-0.2.4/astropy_helpers/astropy_helpers.egg-info/top_level.txt0000644000077000000240000000002012454670716026652 0ustar adamstaff00000000000000astropy_helpers astroquery-0.2.4/astropy_helpers/build/0000755000077000000240000000000012505171566020306 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/0000755000077000000240000000000012505171566024166 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/0000755000077000000240000000000012505171566027411 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/__init__.py0000644000077000000240000000024312425434461031516 0ustar adamstaff00000000000000try: from .version import version as __version__ from .version import githash as __githash__ except ImportError: __version__ = '' __githash__ = '' astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/0000755000077000000240000000000012505171566030674 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/__init__.py0000644000077000000240000000056012354456432033006 0ustar adamstaff00000000000000def _fix_user_options(options): """ This is for Python 2.x and 3.x compatibility. distutils expects Command options to all be byte strings on Python 2 and Unicode strings on Python 3. """ def to_str_or_none(x): if x is None: return None return str(x) return [tuple(to_str_or_none(x) for x in y) for y in options] ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/_subprocess_py2/astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/_subprocess0000755000077000000240000000000012505171566033144 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000016500000000000011217 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/_subprocess_py2/__init__.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/_subprocess0000644000077000000240000000243212354456432033147 0ustar adamstaff00000000000000from __future__ import absolute_import from subprocess import * def check_output(*popenargs, **kwargs): r"""Run command with arguments and return its output as a byte string. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example:: >>> check_output(["ls", "-l", "/dev/null"]) 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT.:: >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) 'ls: non_existent_file: No such file or directory\n' """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') process = Popen(stdout=PIPE, *popenargs, **kwargs) output, unused_err = process.communicate() retcode = process.poll() if retcode: cmd = kwargs.get("args") if cmd is None: cmd = popenargs[0] raise CalledProcessError(retcode, cmd) return output ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/subprocess.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/compat/subprocess.0000644000077000000240000000105012354456432033061 0ustar adamstaff00000000000000""" A replacement wrapper around the subprocess module that adds check_output (which was only added to Python in 2.7. Instead of importing subprocess, other modules should use this as follows:: from astropy.utils.compat import subprocess This module is safe to import from anywhere within astropy. """ from __future__ import absolute_import, print_function import subprocess # python2.7 and later provide a check_output method if not hasattr(subprocess, 'check_output'): from ._subprocess_py2 import check_output from subprocess import * astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/git_helpers.py0000644000077000000240000001172612453761452032300 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Utilities for retrieving revision information from a project's git repository. """ # Do not remove the following comment; it is used by # astropy_helpers.version_helpers to determine the beginning of the code in # this module # BEGIN import locale import os import subprocess import warnings def _decode_stdio(stream): try: stdio_encoding = locale.getdefaultlocale()[1] or 'utf-8' except ValueError: stdio_encoding = 'utf-8' try: text = stream.decode(stdio_encoding) except UnicodeDecodeError: # Final fallback text = stream.decode('latin1') return text def update_git_devstr(version, path=None): """ Updates the git revision string if and only if the path is being imported directly from a git working copy. This ensures that the revision number in the version string is accurate. """ try: # Quick way to determine if we're in git or not - returns '' if not devstr = get_git_devstr(sha=True, show_warning=False, path=path) except OSError: return version if not devstr: # Probably not in git so just pass silently return version if 'dev' in version: # update to the current git revision version_base = version.split('.dev', 1)[0] devstr = get_git_devstr(sha=False, show_warning=False, path=path) return version_base + '.dev' + devstr else: #otherwise it's already the true/release version return version def get_git_devstr(sha=False, show_warning=True, path=None): """ Determines the number of revisions in this repository. Parameters ---------- sha : bool If True, the full SHA1 hash will be returned. Otherwise, the total count of commits in the repository will be used as a "revision number". show_warning : bool If True, issue a warning if git returns an error code, otherwise errors pass silently. path : str or None If a string, specifies the directory to look in to find the git repository. If `None`, the current working directory is used. If given a filename it uses the directory containing that file. Returns ------- devversion : str Either a string with the revision number (if `sha` is False), the SHA1 hash of the current commit (if `sha` is True), or an empty string if git version info could not be identified. """ if path is None: path = os.getcwd() if not os.path.isdir(path): path = os.path.abspath(os.path.dirname(path)) if not os.path.exists(os.path.join(path, '.git')): return '' if sha: # Faster for getting just the hash of HEAD cmd = ['rev-parse', 'HEAD'] else: cmd = ['rev-list', '--count', 'HEAD'] def run_git(cmd): try: p = subprocess.Popen(['git'] + cmd, cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate() except OSError as e: if show_warning: warnings.warn('Error running git: ' + str(e)) return (None, '', '') if p.returncode == 128: if show_warning: warnings.warn('No git repository present at {0!r}! Using ' 'default dev version.'.format(path)) return (p.returncode, '', '') if p.returncode == 129: if show_warning: warnings.warn('Your git looks old (does it support {0}?); ' 'consider upgrading to v1.7.2 or ' 'later.'.format(cmd[0])) return (p.returncode, stdout, stderr) elif p.returncode != 0: if show_warning: warnings.warn('Git failed while determining revision ' 'count: {0}'.format(_decode_stdio(stderr))) return (p.returncode, stdout, stderr) return p.returncode, stdout, stderr returncode, stdout, stderr = run_git(cmd) if not sha and returncode == 129: # git returns 129 if a command option failed to parse; in # particular this could happen in git versions older than 1.7.2 # where the --count option is not supported # Also use --abbrev-commit and --abbrev=0 to display the minimum # number of characters needed per-commit (rather than the full hash) cmd = ['rev-list', '--abbrev-commit', '--abbrev=0', 'HEAD'] returncode, stdout, stderr = run_git(cmd) # Fall back on the old method of getting all revisions and counting # the lines if returncode == 0: return str(stdout.count(b'\n')) else: return '' elif sha: return _decode_stdio(stdout)[:40] else: return _decode_stdio(stdout).strip() astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/setup_helpers.py0000644000077000000240000015753112453761452032662 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This module contains a number of utilities for use during setup/build/packaging that are useful to astropy as a whole. """ from __future__ import absolute_import, print_function import collections import errno import imp import inspect import os import pkgutil import re import shlex import shutil import subprocess import sys import textwrap from distutils import log, ccompiler, sysconfig from distutils.cmd import DistutilsOptionError from distutils.dist import Distribution from distutils.errors import DistutilsError, DistutilsFileError from distutils.core import Extension from distutils.core import Command from distutils.command.sdist import sdist as DistutilsSdist from distutils.version import StrictVersion from setuptools.command.build_ext import build_ext as SetuptoolsBuildExt from setuptools.command.build_py import build_py as SetuptoolsBuildPy from setuptools.command.install import install as SetuptoolsInstall from setuptools.command.install_lib import install_lib as SetuptoolsInstallLib from setuptools.command.register import register as SetuptoolsRegister from setuptools import find_packages from .test_helpers import AstropyTest from .utils import silence, invalidate_caches, walk_skip_hidden _module_state = { 'adjusted_compiler': False, 'registered_commands': None, 'have_cython': False, 'have_sphinx': False } try: import Cython _module_state['have_cython'] = True except ImportError: pass try: import sphinx from sphinx.setup_command import BuildDoc as SphinxBuildDoc _module_state['have_sphinx'] = True except ValueError as e: # This can occur deep in the bowels of Sphinx's imports by way of docutils # and an occurence of this bug: http://bugs.python.org/issue18378 # In this case sphinx is effectively unusable if 'unknown locale' in e.args[0]: log.warn( "Possible misconfiguration of one of the environment variables " "LC_ALL, LC_CTYPES, LANG, or LANGUAGE. For an example of how to " "configure your system's language environment on OSX see " "http://blog.remibergsma.com/2012/07/10/" "setting-locales-correctly-on-mac-osx-terminal-application/") except ImportError: pass except SyntaxError: # occurs if markupsafe is recent version, which doesn't support Python 3.2 pass PY3 = sys.version_info[0] >= 3 # This adds a new keyword to the setup() function Distribution.skip_2to3 = [] def adjust_compiler(package): """ This function detects broken compilers and switches to another. If the environment variable CC is explicitly set, or a compiler is specified on the commandline, no override is performed -- the purpose here is to only override a default compiler. The specific compilers with problems are: * The default compiler in XCode-4.2, llvm-gcc-4.2, segfaults when compiling wcslib. The set of broken compilers can be updated by changing the compiler_mapping variable. It is a list of 2-tuples where the first in the pair is a regular expression matching the version of the broken compiler, and the second is the compiler to change to. """ compiler_mapping = [ (b'i686-apple-darwin[0-9]*-llvm-gcc-4.2', 'clang') ] if _module_state['adjusted_compiler']: return # Whatever the result of this function is, it only needs to be run once _module_state['adjusted_compiler'] = True if 'CC' in os.environ: # Check that CC is not set to llvm-gcc-4.2 c_compiler = os.environ['CC'] try: version = get_compiler_version(c_compiler) except OSError: msg = textwrap.dedent( """ The C compiler set by the CC environment variable: {compiler:s} cannot be found or executed. """.format(compiler=c_compiler)) log.warn(msg) sys.exit(1) for broken, fixed in compiler_mapping: if re.match(broken, version): msg = textwrap.dedent( """Compiler specified by CC environment variable ({compiler:s}:{version:s}) will fail to compile {pkg:s}. Please set CC={fixed:s} and try again. You can do this, for example, by running: CC={fixed:s} python setup.py where is the command you ran. """.format(compiler=c_compiler, version=version, pkg=package, fixed=fixed)) log.warn(msg) sys.exit(1) # If C compiler is set via CC, and isn't broken, we are good to go. We # should definitely not try accessing the compiler specified by # ``sysconfig.get_config_var('CC')`` lower down, because this may fail # if the compiler used to compile Python is missing (and maybe this is # why the user is setting CC). For example, the official Python 2.7.3 # MacOS X binary was compled with gcc-4.2, which is no longer available # in XCode 4. return if get_distutils_build_option('compiler'): return compiler_type = ccompiler.get_default_compiler() if compiler_type == 'unix': # We have to get the compiler this way, as this is the one that is # used if os.environ['CC'] is not set. It is actually read in from # the Python Makefile. Note that this is not necessarily the same # compiler as returned by ccompiler.new_compiler() c_compiler = sysconfig.get_config_var('CC') try: version = get_compiler_version(c_compiler) except OSError: msg = textwrap.dedent( """ The C compiler used to compile Python {compiler:s}, and which is normally used to compile C extensions, is not available. You can explicitly specify which compiler to use by setting the CC environment variable, for example: CC=gcc python setup.py or if you are using MacOS X, you can try: CC=clang python setup.py """.format(compiler=c_compiler)) log.warn(msg) sys.exit(1) for broken, fixed in compiler_mapping: if re.match(broken, version): os.environ['CC'] = fixed break def get_compiler_version(compiler): process = subprocess.Popen( shlex.split(compiler) + ['--version'], stdout=subprocess.PIPE) output = process.communicate()[0].strip() try: version = output.split()[0] except IndexError: return 'unknown' return version def get_dummy_distribution(): """Returns a distutils Distribution object used to instrument the setup environment before calling the actual setup() function. """ if _module_state['registered_commands'] is None: raise RuntimeError( 'astropy_helpers.setup_helpers.register_commands() must be ' 'called before using ' 'astropy_helpers.setup_helpers.get_dummy_distribution()') # Pre-parse the Distutils command-line options and config files to if # the option is set. dist = Distribution({'script_name': os.path.basename(sys.argv[0]), 'script_args': sys.argv[1:]}) dist.cmdclass.update(_module_state['registered_commands']) with silence(): try: dist.parse_config_files() dist.parse_command_line() except (DistutilsError, AttributeError, SystemExit): # Let distutils handle DistutilsErrors itself AttributeErrors can # get raise for ./setup.py --help SystemExit can be raised if a # display option was used, for example pass return dist def get_distutils_option(option, commands): """ Returns the value of the given distutils option. Parameters ---------- option : str The name of the option commands : list of str The list of commands on which this option is available Returns ------- val : str or None the value of the given distutils option. If the option is not set, returns None. """ dist = get_dummy_distribution() for cmd in commands: cmd_opts = dist.command_options.get(cmd) if cmd_opts is not None and option in cmd_opts: return cmd_opts[option][1] else: return None def get_distutils_build_option(option): """ Returns the value of the given distutils build option. Parameters ---------- option : str The name of the option Returns ------- val : str or None The value of the given distutils build option. If the option is not set, returns None. """ return get_distutils_option(option, ['build', 'build_ext', 'build_clib']) def get_distutils_install_option(option): """ Returns the value of the given distutils install option. Parameters ---------- option : str The name of the option Returns ------- val : str or None The value of the given distutils build option. If the option is not set, returns None. """ return get_distutils_option(option, ['install']) def get_distutils_build_or_install_option(option): """ Returns the value of the given distutils build or install option. Parameters ---------- option : str The name of the option Returns ------- val : str or None The value of the given distutils build or install option. If the option is not set, returns None. """ return get_distutils_option(option, ['build', 'build_ext', 'build_clib', 'install']) def get_compiler_option(): """ Determines the compiler that will be used to build extension modules. Returns ------- compiler : str The compiler option specificied for the build, build_ext, or build_clib command; or the default compiler for the platform if none was specified. """ compiler = get_distutils_build_option('compiler') if compiler is None: return ccompiler.get_default_compiler() return compiler def get_debug_option(packagename): """ Determines if the build is in debug mode. Returns ------- debug : bool True if the current build was started with the debug option, False otherwise. """ try: current_debug = get_pkg_version_module(packagename, fromlist=['debug'])[0] except (ImportError, AttributeError): current_debug = None # Only modify the debug flag if one of the build commands was explicitly # run (i.e. not as a sub-command of something else) dist = get_dummy_distribution() if any(cmd in dist.commands for cmd in ['build', 'build_ext']): debug = bool(get_distutils_build_option('debug')) else: debug = bool(current_debug) if current_debug is not None and current_debug != debug: build_ext_cmd = dist.get_command_class('build_ext') build_ext_cmd.force_rebuild = True return debug # TODO: Move this into astropy_helpers.version_helpers once the dependency of # version_helpers on *this* module has been resolved (IOW, once these modules # have been refactored to reduce their interdependency) def get_pkg_version_module(packagename, fromlist=None): """Returns the package's .version module generated by `astropy_helpers.version_helpers.generate_version_py`. Raises an ImportError if the version module is not found. If ``fromlist`` is an iterable, return a tuple of the members of the version module corresponding to the member names given in ``fromlist``. Raises an `AttributeError` if any of these module members are not found. """ if not fromlist: # Due to a historical quirk of Python's import implementation, # __import__ will not return submodules of a package if 'fromlist' is # empty. # TODO: For Python 3.1 and up it may be preferable to use importlib # instead of the __import__ builtin return __import__(packagename + '.version', fromlist=['']) else: mod = __import__(packagename + '.version', fromlist=fromlist) return tuple(getattr(mod, member) for member in fromlist) def register_commands(package, version, release): if _module_state['registered_commands'] is not None: return _module_state['registered_commands'] _module_state['registered_commands'] = registered_commands = { 'test': generate_test_command(package), # Use distutils' sdist because it respects package_data. # setuptools/distributes sdist requires duplication of information in # MANIFEST.in 'sdist': DistutilsSdist, # The exact form of the build_ext command depends on whether or not # we're building a release version 'build_ext': generate_build_ext_command(package, release), # We have a custom build_py to generate the default configuration file 'build_py': AstropyBuildPy, # Since install can (in some circumstances) be run without # first building, we also need to override install and # install_lib. See #2223 'install': AstropyInstall, 'install_lib': AstropyInstallLib, 'register': AstropyRegister } if _module_state['have_sphinx']: registered_commands['build_sphinx'] = AstropyBuildSphinx else: registered_commands['build_sphinx'] = FakeBuildSphinx # Need to override the __name__ here so that the commandline options are # presented as being related to the "build" command, for example; normally # this wouldn't be necessary since commands also have a command_name # attribute, but there is a bug in distutils' help display code that it # uses __name__ instead of command_name. Yay distutils! for name, cls in registered_commands.items(): cls.__name__ = name # Add a few custom options; more of these can be added by specific packages # later for option in [ ('use-system-libraries', "Use system libraries whenever possible", True)]: add_command_option('build', *option) add_command_option('install', *option) return registered_commands def generate_test_command(package_name): """ Creates a custom 'test' command for the given package which sets the command's ``package_name`` class attribute to the name of the package being tested. """ return type(package_name.title() + 'Test', (AstropyTest,), {'package_name': package_name}) def generate_build_ext_command(packagename, release): """ Creates a custom 'build_ext' command that allows for manipulating some of the C extension options at build time. We use a function to build the class since the base class for build_ext may be different depending on certain build-time parameters (for example, we may use Cython's build_ext instead of the default version in distutils). Uses the default distutils.command.build_ext by default. """ uses_cython = should_build_with_cython(packagename, release) if uses_cython: from Cython.Distutils import build_ext as basecls else: basecls = SetuptoolsBuildExt attrs = dict(basecls.__dict__) orig_run = getattr(basecls, 'run', None) orig_finalize = getattr(basecls, 'finalize_options', None) def finalize_options(self): # Add a copy of the _compiler.so module as well, but only if there are # in fact C modules to compile (otherwise there's no reason to include # a record of the compiler used) if self.extensions: src_path = os.path.relpath( os.path.join(os.path.dirname(__file__), 'src')) shutil.copy2(os.path.join(src_path, 'compiler.c'), os.path.join(self.package_name, '_compiler.c')) ext = Extension(self.package_name + '._compiler', [os.path.join(self.package_name, '_compiler.c')]) self.extensions.insert(0, ext) if orig_finalize is not None: orig_finalize(self) # Generate if self.uses_cython: try: from Cython import __version__ as cython_version except ImportError: # This shouldn't happen if we made it this far cython_version = None if (cython_version is not None and cython_version != self.uses_cython): self.force_rebuild = True # Update the used cython version self.uses_cython = cython_version # Regardless of the value of the '--force' option, force a rebuild if # the debug flag changed from the last build if self.force_rebuild: self.force = True def run(self): # For extensions that require 'numpy' in their include dirs, replace # 'numpy' with the actual paths np_include = get_numpy_include_path() for extension in self.extensions: if 'numpy' in extension.include_dirs: idx = extension.include_dirs.index('numpy') extension.include_dirs.insert(idx, np_include) extension.include_dirs.remove('numpy') # Replace .pyx with C-equivalents, unless c files are missing for jdx, src in enumerate(extension.sources): if src.endswith('.pyx'): pyxfn = src cfn = src[:-4] + '.c' elif src.endswith('.c'): pyxfn = src[:-2] + '.pyx' cfn = src if not os.path.isfile(pyxfn): continue if self.uses_cython: extension.sources[jdx] = pyxfn else: if os.path.isfile(cfn): extension.sources[jdx] = cfn else: msg = ( 'Could not find C file {0} for Cython file {1} ' 'when building extension {2}. Cython must be ' 'installed to build from a git checkout.'.format( cfn, pyxfn, extension.name)) raise IOError(errno.ENOENT, msg, cfn) if orig_run is not None: # This should always be the case for a correctly implemented # distutils command. orig_run(self) # Update cython_version.py if building with Cython try: cython_version = get_pkg_version_module( packagename, fromlist=['cython_version'])[0] except (AttributeError, ImportError): cython_version = 'unknown' if self.uses_cython and self.uses_cython != cython_version: package_dir = os.path.relpath(packagename) cython_py = os.path.join(package_dir, 'cython_version.py') with open(cython_py, 'w') as f: f.write('# Generated file; do not modify\n') f.write('cython_version = {0!r}\n'.format(self.uses_cython)) if os.path.isdir(self.build_lib): # The build/lib directory may not exist if the build_py command # was not previously run, which may sometimes be the case self.copy_file(cython_py, os.path.join(self.build_lib, cython_py), preserve_mode=False) invalidate_caches() attrs['run'] = run attrs['finalize_options'] = finalize_options attrs['force_rebuild'] = False attrs['uses_cython'] = uses_cython attrs['package_name'] = packagename attrs['user_options'] = basecls.user_options[:] attrs['boolean_options'] = basecls.boolean_options[:] return type('build_ext', (basecls, object), attrs) def _get_platlib_dir(cmd): plat_specifier = '.{0}-{1}'.format(cmd.plat_name, sys.version[0:3]) return os.path.join(cmd.build_base, 'lib' + plat_specifier) class AstropyInstall(SetuptoolsInstall): user_options = SetuptoolsInstall.user_options[:] boolean_options = SetuptoolsInstall.boolean_options[:] def finalize_options(self): build_cmd = self.get_finalized_command('build') platlib_dir = _get_platlib_dir(build_cmd) self.build_lib = platlib_dir SetuptoolsInstall.finalize_options(self) class AstropyInstallLib(SetuptoolsInstallLib): user_options = SetuptoolsInstallLib.user_options[:] boolean_options = SetuptoolsInstallLib.boolean_options[:] def finalize_options(self): build_cmd = self.get_finalized_command('build') platlib_dir = _get_platlib_dir(build_cmd) self.build_dir = platlib_dir SetuptoolsInstallLib.finalize_options(self) class AstropyBuildPy(SetuptoolsBuildPy): user_options = SetuptoolsBuildPy.user_options[:] boolean_options = SetuptoolsBuildPy.boolean_options[:] def finalize_options(self): # Update build_lib settings from the build command to always put # build files in platform-specific subdirectories of build/, even # for projects with only pure-Python source (this is desirable # specifically for support of multiple Python version). build_cmd = self.get_finalized_command('build') platlib_dir = _get_platlib_dir(build_cmd) build_cmd.build_purelib = platlib_dir build_cmd.build_lib = platlib_dir self.build_lib = platlib_dir SetuptoolsBuildPy.finalize_options(self) def run_2to3(self, files, doctests=False): # Filter the files to exclude things that shouldn't be 2to3'd skip_2to3 = self.distribution.skip_2to3 filtered_files = [] for file in files: for package in skip_2to3: if file[len(self.build_lib) + 1:].startswith(package): break else: filtered_files.append(file) SetuptoolsBuildPy.run_2to3(self, filtered_files, doctests) def run(self): # first run the normal build_py SetuptoolsBuildPy.run(self) def add_command_option(command, name, doc, is_bool=False): """ Add a custom option to a setup command. Issues a warning if the option already exists on that command. Parameters ---------- command : str The name of the command as given on the command line name : str The name of the build option doc : str A short description of the option, for the `--help` message is_bool : bool, optional When `True`, the option is a boolean option and doesn't require an associated value. """ dist = get_dummy_distribution() cmdcls = dist.get_command_class(command) if (hasattr(cmdcls, '_astropy_helpers_options') and name in cmdcls._astropy_helpers_options): return attr = name.replace('-', '_') if hasattr(cmdcls, attr): raise RuntimeError( '{0!r} already has a {1!r} class attribute, barring {2!r} from ' 'being usable as a custom option name.'.format(cmdcls, attr, name)) for idx, cmd in enumerate(cmdcls.user_options): if cmd[0] == name: log.warn('Overriding existing {0!r} option ' '{1!r}'.format(command, name)) del cmdcls.user_options[idx] if name in cmdcls.boolean_options: cmdcls.boolean_options.remove(name) break cmdcls.user_options.append((name, None, doc)) if is_bool: cmdcls.boolean_options.append(name) # Distutils' command parsing requires that a command object have an # attribute with the same name as the option (with '-' replaced with '_') # in order for that option to be recognized as valid setattr(cmdcls, attr, None) # This caches the options added through add_command_option so that if it is # run multiple times in the same interpreter repeated adds are ignored # (this way we can still raise a RuntimeError if a custom option overrides # a built-in option) if not hasattr(cmdcls, '_astropy_helpers_options'): cmdcls._astropy_helpers_options = set([name]) else: cmdcls._astropy_helpers_options.add(name) class AstropyRegister(SetuptoolsRegister): """Extends the built in 'register' command to support a ``--hidden`` option to make the registered version hidden on PyPI by default. The result of this is that when a version is registered as "hidden" it can still be downloaded from PyPI, but it does not show up in the list of actively supported versions under http://pypi.python.org/pypi/astropy, and is not set as the most recent version. Although this can always be set through the web interface it may be more convenient to be able to specify via the 'register' command. Hidden may also be considered a safer default when running the 'register' command, though this command uses distutils' normal behavior if the ``--hidden`` option is omitted. """ user_options = SetuptoolsRegister.user_options + [ ('hidden', None, 'mark this release as hidden on PyPI by default') ] boolean_options = SetuptoolsRegister.boolean_options + ['hidden'] def initialize_options(self): SetuptoolsRegister.initialize_options(self) self.hidden = False def build_post_data(self, action): data = SetuptoolsRegister.build_post_data(self, action) if action == 'submit' and self.hidden: data['_pypi_hidden'] = '1' return data def _set_config(self): # The original register command is buggy--if you use .pypirc with a # server-login section *at all* the repository you specify with the -r # option will be overwritten with either the repository in .pypirc or # with the default, # If you do not have a .pypirc using the -r option will just crash. # Way to go distutils # If we don't set self.repository back to a default value _set_config # can crash if there was a user-supplied value for this option; don't # worry, we'll get the real value back afterwards self.repository = 'pypi' SetuptoolsRegister._set_config(self) options = self.distribution.get_option_dict('register') if 'repository' in options: source, value = options['repository'] # Really anything that came from setup.cfg or the command line # should override whatever was in .pypirc self.repository = value if _module_state['have_sphinx']: class AstropyBuildSphinx(SphinxBuildDoc): """ A version of the ``build_sphinx`` command that uses the version of Astropy that is built by the setup ``build`` command, rather than whatever is installed on the system - to build docs against the installed version, run ``make html`` in the ``astropy/docs`` directory. This also automatically creates the docs/_static directories - this is needed because github won't create the _static dir because it has no tracked files. """ description = 'Build Sphinx documentation for Astropy environment' user_options = SphinxBuildDoc.user_options[:] user_options.append(('warnings-returncode', 'w', 'Parses the sphinx output and sets the return ' 'code to 1 if there are any warnings. Note that ' 'this will cause the sphinx log to only update ' 'when it completes, rather than continuously as ' 'is normally the case.')) user_options.append(('clean-docs', 'l', 'Completely clean previous builds, including ' 'automodapi-generated files before building new ' 'ones')) user_options.append(('no-intersphinx', 'n', 'Skip intersphinx, even if conf.py says to use ' 'it')) user_options.append(('open-docs-in-browser', 'o', 'Open the docs in a browser (using the ' 'webbrowser module) if the build finishes ' 'successfully.')) boolean_options = SphinxBuildDoc.boolean_options[:] boolean_options.append('warnings-returncode') boolean_options.append('clean-docs') boolean_options.append('no-intersphinx') boolean_options.append('open-docs-in-browser') _self_iden_rex = re.compile(r"self\.([^\d\W][\w]+)", re.UNICODE) def initialize_options(self): SphinxBuildDoc.initialize_options(self) self.clean_docs = False self.no_intersphinx = False self.open_docs_in_browser = False self.warnings_returncode = False def finalize_options(self): #Clear out previous sphinx builds, if requested if self.clean_docs: dirstorm = [os.path.join(self.source_dir, 'api')] if self.build_dir is None: dirstorm.append('docs/_build') else: dirstorm.append(self.build_dir) for d in dirstorm: if os.path.isdir(d): log.info('Cleaning directory ' + d) shutil.rmtree(d) else: log.info('Not cleaning directory ' + d + ' because ' 'not present or not a directory') SphinxBuildDoc.finalize_options(self) def run(self): # TODO: Break this method up into a few more subroutines and # document them better import webbrowser if PY3: from urllib.request import pathname2url else: from urllib import pathname2url # This is used at the very end of `run` to decide if sys.exit should # be called. If it's None, it won't be. retcode = None # If possible, create the _static dir if self.build_dir is not None: # the _static dir should be in the same place as the _build dir # for Astropy basedir, subdir = os.path.split(self.build_dir) if subdir == '': # the path has a trailing /... basedir, subdir = os.path.split(basedir) staticdir = os.path.join(basedir, '_static') if os.path.isfile(staticdir): raise DistutilsOptionError( 'Attempted to build_sphinx in a location where' + staticdir + 'is a file. Must be a directory.') self.mkpath(staticdir) #Now make sure Astropy is built and determine where it was built build_cmd = self.reinitialize_command('build') build_cmd.inplace = 0 self.run_command('build') build_cmd = self.get_finalized_command('build') build_cmd_path = os.path.abspath(build_cmd.build_lib) ah_importer = pkgutil.get_importer('astropy_helpers') ah_path = os.path.abspath(ah_importer.path) #Now generate the source for and spawn a new process that runs the #command. This is needed to get the correct imports for the built #version # Note: As of Sphinx 1.3b1 SphinxBuildDoc.run requires # print_function support subproccode = '' try: if StrictVersion(sphinx.__version__) >= StrictVersion('1.3b1'): subproccode = 'from __future__ import print_function\n\n' except: # Could not determine Sphinx version; YMMV pass runlines, runlineno = inspect.getsourcelines(SphinxBuildDoc.run) subproccode += textwrap.dedent(""" from sphinx.setup_command import * os.chdir({srcdir!r}) sys.path.insert(0, {build_cmd_path!r}) sys.path.insert(0, {ah_path!r}) """).format(build_cmd_path=build_cmd_path, ah_path=ah_path, srcdir=self.source_dir) #runlines[1:] removes 'def run(self)' on the first line subproccode += textwrap.dedent(''.join(runlines[1:])) # All "self.foo" in the subprocess code needs to be replaced by the # values taken from the current self in *this* process subproccode = AstropyBuildSphinx._self_iden_rex.split(subproccode) for i in range(1, len(subproccode), 2): iden = subproccode[i] val = getattr(self, iden) if iden.endswith('_dir'): #Directories should be absolute, because the `chdir` call #in the new process moves to a different directory subproccode[i] = repr(os.path.abspath(val)) else: subproccode[i] = repr(val) subproccode = ''.join(subproccode) if self.no_intersphinx: #the confoverrides variable in sphinx.setup_command.BuildDoc can #be used to override the conf.py ... but this could well break #if future versions of sphinx change the internals of BuildDoc, #so remain vigilant! subproccode = subproccode.replace('confoverrides = {}', 'confoverrides = {\'intersphinx_mapping\':{}}') log.debug('Starting subprocess of {0} with python code:\n{1}\n' '[CODE END])'.format(sys.executable, subproccode)) # To return the number of warnings, we need to capture stdout. This # prevents a continuous updating at the terminal, but there's no # apparent way around this. if self.warnings_returncode: proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdo, stde = proc.communicate(subproccode.encode('utf-8')) print(stdo) stdolines = stdo.split(b'\n') if b'build succeeded.' in stdolines: retcode = 0 else: retcode = 1 if retcode != 0: if os.environ.get('TRAVIS', None) == 'true': #this means we are in the travis build, so customize #the message appropriately. msg = ('The build_sphinx travis build FAILED ' 'because sphinx issued documentation ' 'warnings (scroll up to see the warnings).') else: # standard failure message msg = ('build_sphinx returning a non-zero exit ' 'code because sphinx issued documentation ' 'warnings.') log.warn(msg) else: proc = subprocess.Popen([sys.executable], stdin=subprocess.PIPE) proc.communicate(subproccode.encode('utf-8')) if proc.returncode == 0: if self.open_docs_in_browser: if self.builder == 'html': absdir = os.path.abspath(self.builder_target_dir) index_path = os.path.join(absdir, 'index.html') fileurl = 'file://' + pathname2url(index_path) webbrowser.open(fileurl) else: log.warn('open-docs-in-browser option was given, but ' 'the builder is not html! Ignogring.') else: log.warn('Sphinx Documentation subprocess failed with return ' 'code ' + str(proc.returncode)) if retcode is not None: # this is potentially dangerous in that there might be something # after the call to `setup` in `setup.py`, and exiting here will # prevent that from running. But there's no other apparent way # to signal what the return code should be. sys.exit(retcode) def get_distutils_display_options(): """ Returns a set of all the distutils display options in their long and short forms. These are the setup.py arguments such as --name or --version which print the project's metadata and then exit. Returns ------- opts : set The long and short form display option arguments, including the - or -- """ short_display_opts = set('-' + o[1] for o in Distribution.display_options if o[1]) long_display_opts = set('--' + o[0] for o in Distribution.display_options) # Include -h and --help which are not explicitly listed in # Distribution.display_options (as they are handled by optparse) short_display_opts.add('-h') long_display_opts.add('--help') # This isn't the greatest approach to hardcode these commands. # However, there doesn't seem to be a good way to determine # whether build *will be* run as part of the command at this # phase. display_commands = set([ 'clean', 'register', 'setopt', 'saveopts', 'egg_info', 'alias']) return short_display_opts.union(long_display_opts.union(display_commands)) def is_distutils_display_option(): """ Returns True if sys.argv contains any of the distutils display options such as --version or --name. """ display_options = get_distutils_display_options() return bool(set(sys.argv[1:]).intersection(display_options)) def update_package_files(srcdir, extensions, package_data, packagenames, package_dirs): """ This function is deprecated and maintained for backward compatibility with affiliated packages. Affiliated packages should update their setup.py to use `get_package_info` instead. """ info = get_package_info(srcdir) extensions.extend(info['ext_modules']) package_data.update(info['package_data']) packagenames = list(set(packagenames + info['packages'])) package_dirs.update(info['package_dir']) def get_package_info(srcdir='.', exclude=()): """ Collates all of the information for building all subpackages subpackages and returns a dictionary of keyword arguments that can be passed directly to `distutils.setup`. The purpose of this function is to allow subpackages to update the arguments to the package's ``setup()`` function in its setup.py script, rather than having to specify all extensions/package data directly in the ``setup.py``. See Astropy's own ``setup.py`` for example usage and the Astropy development docs for more details. This function obtains that information by iterating through all packages in ``srcdir`` and locating a ``setup_package.py`` module. This module can contain the following functions: ``get_extensions()``, ``get_package_data()``, ``get_build_options()``, ``get_external_libraries()``, and ``requires_2to3()``. Each of those functions take no arguments. - ``get_extensions`` returns a list of `distutils.extension.Extension` objects. - ``get_package_data()`` returns a dict formatted as required by the ``package_data`` argument to ``setup()``. - ``get_build_options()`` returns a list of tuples describing the extra build options to add. - ``get_external_libraries()`` returns a list of libraries that can optionally be built using external dependencies. - ``requires_2to3()`` should return `True` when the source code requires `2to3` processing to run on Python 3.x. If ``requires_2to3()`` is missing, it is assumed to return `True`. """ ext_modules = [] packages = [] package_data = {} package_dir = {} skip_2to3 = [] # Use the find_packages tool to locate all packages and modules packages = filter_packages(find_packages(srcdir, exclude=exclude)) # For each of the setup_package.py modules, extract any # information that is needed to install them. The build options # are extracted first, so that their values will be available in # subsequent calls to `get_extensions`, etc. for setuppkg in iter_setup_packages(srcdir, packages): if hasattr(setuppkg, 'get_build_options'): options = setuppkg.get_build_options() for option in options: add_command_option('build', *option) if hasattr(setuppkg, 'get_external_libraries'): libraries = setuppkg.get_external_libraries() for library in libraries: add_external_library(library) if hasattr(setuppkg, 'requires_2to3'): requires_2to3 = setuppkg.requires_2to3() else: requires_2to3 = True if not requires_2to3: skip_2to3.append( os.path.dirname(setuppkg.__file__)) for setuppkg in iter_setup_packages(srcdir, packages): # get_extensions must include any Cython extensions by their .pyx # filename. if hasattr(setuppkg, 'get_extensions'): ext_modules.extend(setuppkg.get_extensions()) if hasattr(setuppkg, 'get_package_data'): package_data.update(setuppkg.get_package_data()) # Locate any .pyx files not already specified, and add their extensions in. # The default include dirs include numpy to facilitate numerical work. ext_modules.extend(get_cython_extensions(srcdir, packages, ext_modules, ['numpy'])) # Now remove extensions that have the special name 'skip_cython', as they # exist Only to indicate that the cython extensions shouldn't be built for i, ext in reversed(list(enumerate(ext_modules))): if ext.name == 'skip_cython': del ext_modules[i] # On Microsoft compilers, we need to pass the '/MANIFEST' # commandline argument. This was the default on MSVC 9.0, but is # now required on MSVC 10.0, but it doesn't seeem to hurt to add # it unconditionally. if get_compiler_option() == 'msvc': for ext in ext_modules: ext.extra_link_args.append('/MANIFEST') return { 'ext_modules': ext_modules, 'packages': packages, 'package_dir': package_dir, 'package_data': package_data, 'skip_2to3': skip_2to3 } def iter_setup_packages(srcdir, packages): """ A generator that finds and imports all of the ``setup_package.py`` modules in the source packages. Returns ------- modgen : generator A generator that yields (modname, mod), where `mod` is the module and `modname` is the module name for the ``setup_package.py`` modules. """ for packagename in packages: package_parts = packagename.split('.') package_path = os.path.join(srcdir, *package_parts) setup_package = os.path.relpath( os.path.join(package_path, 'setup_package.py')) if os.path.isfile(setup_package): module = import_file(setup_package) yield module def iter_pyx_files(package_dir, package_name): """ A generator that yields Cython source files (ending in '.pyx') in the source packages. Returns ------- pyxgen : generator A generator that yields (extmod, fullfn) where `extmod` is the full name of the module that the .pyx file would live in based on the source directory structure, and `fullfn` is the path to the .pyx file. """ for dirpath, dirnames, filenames in walk_skip_hidden(package_dir): for fn in filenames: if fn.endswith('.pyx'): fullfn = os.path.relpath(os.path.join(dirpath, fn)) # Package must match file name extmod = '.'.join([package_name, fn[:-4]]) yield (extmod, fullfn) break # Don't recurse into subdirectories def should_build_with_cython(package, release=None): """Returns the previously used Cython version (or 'unknown' if not previously built) if Cython should be used to build extension modules from pyx files. If the ``release`` parameter is not specified an attempt is made to determine the release flag from `astropy.version`. """ try: version_module = __import__(package + '.cython_version', fromlist=['release', 'cython_version']) except ImportError: version_module = None if release is None and version_module is not None: try: release = version_module.release except AttributeError: pass try: cython_version = version_module.cython_version except AttributeError: cython_version = 'unknown' # Only build with Cython if, of course, Cython is installed, we're in a # development version (i.e. not release) or the Cython-generated source # files haven't been created yet (cython_version == 'unknown'). The latter # case can happen even when release is True if checking out a release tag # from the repository if (_module_state['have_cython'] and (not release or cython_version == 'unknown')): return cython_version else: return False def get_cython_extensions(srcdir, packages, prevextensions=tuple(), extincludedirs=None): """ Looks for Cython files and generates Extensions if needed. Parameters ---------- srcdir : str Path to the root of the source directory to search. prevextensions : list of `~distutils.core.Extension` objects The extensions that are already defined. Any .pyx files already here will be ignored. extincludedirs : list of str or None Directories to include as the `include_dirs` argument to the generated `~distutils.core.Extension` objects. Returns ------- exts : list of `~distutils.core.Extension` objects The new extensions that are needed to compile all .pyx files (does not include any already in `prevextensions`). """ # Vanilla setuptools and old versions of distribute include Cython files # as .c files in the sources, not .pyx, so we cannot simply look for # existing .pyx sources in the previous sources, but we should also check # for .c files with the same remaining filename. So we look for .pyx and # .c files, and we strip the extension. prevsourcepaths = [] ext_modules = [] for ext in prevextensions: for s in ext.sources: if s.endswith(('.pyx', '.c')): sourcepath = os.path.realpath(os.path.splitext(s)[0]) prevsourcepaths.append(sourcepath) for package_name in packages: package_parts = package_name.split('.') package_path = os.path.join(srcdir, *package_parts) for extmod, pyxfn in iter_pyx_files(package_path, package_name): sourcepath = os.path.realpath(os.path.splitext(pyxfn)[0]) if sourcepath not in prevsourcepaths: ext_modules.append(Extension(extmod, [pyxfn], include_dirs=extincludedirs)) return ext_modules def write_if_different(filename, data): """ Write `data` to `filename`, if the content of the file is different. Parameters ---------- filename : str The file name to be written to. data : bytes The data to be written to `filename`. """ assert isinstance(data, bytes) if os.path.exists(filename): with open(filename, 'rb') as fd: original_data = fd.read() else: original_data = None if original_data != data: with open(filename, 'wb') as fd: fd.write(data) def get_numpy_include_path(): """ Gets the path to the numpy headers. """ # We need to go through this nonsense in case setuptools # downloaded and installed Numpy for us as part of the build or # install, since Numpy may still think it's in "setup mode", when # in fact we're ready to use it to build astropy now. if sys.version_info[0] >= 3: import builtins if hasattr(builtins, '__NUMPY_SETUP__'): del builtins.__NUMPY_SETUP__ import imp import numpy imp.reload(numpy) else: import __builtin__ if hasattr(__builtin__, '__NUMPY_SETUP__'): del __builtin__.__NUMPY_SETUP__ import numpy reload(numpy) try: numpy_include = numpy.get_include() except AttributeError: numpy_include = numpy.get_numpy_include() return numpy_include def import_file(filename): """ Imports a module from a single file as if it doesn't belong to a particular package. """ # Specifying a traditional dot-separated fully qualified name here # results in a number of "Parent module 'astropy' not found while # handling absolute import" warnings. Using the same name, the # namespaces of the modules get merged together. So, this # generates an underscore-separated name which is more likely to # be unique, and it doesn't really matter because the name isn't # used directly here anyway. with open(filename, 'U') as fd: name = '_'.join( os.path.relpath(os.path.splitext(filename)[0]).split(os.sep)[1:]) return imp.load_module(name, fd, filename, ('.py', 'U', 1)) class DistutilsExtensionArgs(collections.defaultdict): """ A special dictionary whose default values are the empty list. This is useful for building up a set of arguments for `distutils.Extension` without worrying whether the entry is already present. """ def __init__(self, *args, **kwargs): def default_factory(): return [] super(DistutilsExtensionArgs, self).__init__( default_factory, *args, **kwargs) def update(self, other): for key, val in other.items(): self[key].extend(val) def pkg_config(packages, default_libraries, executable='pkg-config'): """ Uses pkg-config to update a set of distutils Extension arguments to include the flags necessary to link against the given packages. If the pkg-config lookup fails, default_libraries is applied to libraries. Parameters ---------- packages : list of str A list of pkg-config packages to look up. default_libraries : list of str A list of library names to use if the pkg-config lookup fails. Returns ------- config : dict A dictionary containing keyword arguments to `distutils.Extension`. These entries include: - ``include_dirs``: A list of include directories - ``library_dirs``: A list of library directories - ``libraries``: A list of libraries - ``define_macros``: A list of macro defines - ``undef_macros``: A list of macros to undefine - ``extra_compile_args``: A list of extra arguments to pass to the compiler """ flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries', '-D': 'define_macros', '-U': 'undef_macros'} command = "{0} --libs --cflags {1}".format(executable, ' '.join(packages)), result = DistutilsExtensionArgs() try: pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) output = pipe.communicate()[0].strip() except subprocess.CalledProcessError as e: lines = [ "{0} failed. This may cause the build to fail below.".format(executable), " command: {0}".format(e.cmd), " returncode: {0}".format(e.returncode), " output: {0}".format(e.output) ] log.warn('\n'.join(lines)) result['libraries'].extend(default_libraries) else: if pipe.returncode != 0: lines = [ "pkg-config could not lookup up package(s) {0}.".format( ", ".join(packages)), "This may cause the build to fail below." ] log.warn('\n'.join(lines)) result['libraries'].extend(default_libraries) else: for token in output.split(): # It's not clear what encoding the output of # pkg-config will come to us in. It will probably be # some combination of pure ASCII (for the compiler # flags) and the filesystem encoding (for any argument # that includes directories or filenames), but this is # just conjecture, as the pkg-config documentation # doesn't seem to address it. arg = token[:2].decode('ascii') value = token[2:].decode(sys.getfilesystemencoding()) if arg in flag_map: if arg == '-D': value = tuple(value.split('=', 1)) result[flag_map[arg]].append(value) else: result['extra_compile_args'].append(value) return result def add_external_library(library): """ Add a build option for selecting the internal or system copy of a library. Parameters ---------- library : str The name of the library. If the library is `foo`, the build option will be called `--use-system-foo`. """ for command in ['build', 'build_ext', 'install']: add_command_option(command, str('use-system-' + library), 'Use the system {0} library'.format(library), is_bool=True) def use_system_library(library): """ Returns `True` if the build configuration indicates that the given library should use the system copy of the library rather than the internal one. For the given library `foo`, this will be `True` if `--use-system-foo` or `--use-system-libraries` was provided at the commandline or in `setup.cfg`. Parameters ---------- library : str The name of the library Returns ------- use_system : bool `True` if the build should use the system copy of the library. """ return ( get_distutils_build_or_install_option('use_system_{0}'.format(library)) or get_distutils_build_or_install_option('use_system_libraries')) def filter_packages(packagenames): """ Removes some packages from the package list that shouldn't be installed on the current version of Python. """ if PY3: exclude = '_py2' else: exclude = '_py3' return [x for x in packagenames if not x.endswith(exclude)] class FakeBuildSphinx(Command): """ A dummy build_sphinx command that is called if Sphinx is not installed and displays a relevant error message """ #user options inherited from sphinx.setup_command.BuildDoc user_options = [ ('fresh-env', 'E', '' ), ('all-files', 'a', ''), ('source-dir=', 's', ''), ('build-dir=', None, ''), ('config-dir=', 'c', ''), ('builder=', 'b', ''), ('project=', None, ''), ('version=', None, ''), ('release=', None, ''), ('today=', None, ''), ('link-index', 'i', ''), ] #user options appended in astropy.setup_helpers.AstropyBuildSphinx user_options.append(('warnings-returncode', 'w','')) user_options.append(('clean-docs', 'l', '')) user_options.append(('no-intersphinx', 'n', '')) user_options.append(('open-docs-in-browser', 'o','')) def initialize_options(self): try: raise RuntimeError("Sphinx must be installed for build_sphinx") except: log.error('error : Sphinx must be installed for build_sphinx') sys.exit(1) astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/0000755000077000000240000000000012505171566030722 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/__init__.py0000644000077000000240000000041412354456432033032 0ustar adamstaff00000000000000""" This package contains utilities and extensions for the Astropy sphinx documentation. In particular, the `astropy.sphinx.conf` should be imported by the sphinx ``conf.py`` file for affiliated packages that wish to make use of the Astropy documentation format. """ astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/conf.py0000644000077000000240000002457612425434461032234 0ustar adamstaff00000000000000# -*- coding: utf-8 -*- # Licensed under a 3-clause BSD style license - see LICENSE.rst # # Astropy shared Sphinx settings. These settings are shared between # astropy itself and affiliated packages. # # Note that not all possible configuration values are present in this file. # # All configuration values have a default; values that are commented out # serve to show the default. import warnings from os import path # -- General configuration ---------------------------------------------------- # The version check in Sphinx itself can only compare the major and # minor parts of the version number, not the micro. To do a more # specific version check, call check_sphinx_version("x.y.z.") from # your project's conf.py needs_sphinx = '1.2' def check_sphinx_version(expected_version): import sphinx from distutils import version sphinx_version = version.LooseVersion(sphinx.__version__) expected_version = version.LooseVersion(expected_version) if sphinx_version < expected_version: raise RuntimeError( "At least Sphinx version {0} is required to build this " "documentation. Found {1}.".format( expected_version, sphinx_version)) # Configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { 'python': ('http://docs.python.org/', None), 'python3': ('http://docs.python.org/3/', path.abspath(path.join(path.dirname(__file__), 'local/python3links.inv'))), 'numpy': ('http://docs.scipy.org/doc/numpy/', None), 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), 'matplotlib': ('http://matplotlib.org/', None), 'astropy': ('http://docs.astropy.org/en/stable/', None), 'h5py': ('http://docs.h5py.org/en/latest/', None) } # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # Add any paths that contain templates here, relative to this directory. # templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # The reST default role (used for this markup: `text`) to use for all # documents. Set to the "smart" one. default_role = 'obj' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # This is added to the end of RST files - a good place to put substitutions to # be used globally. rst_epilog = """ .. _Astropy: http://astropy.org """ # -- Project information ------------------------------------------------------ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. #pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Settings for extensions and extension options ---------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.pngmath', 'sphinx.ext.inheritance_diagram', 'astropy_helpers.sphinx.ext.numpydoc', 'astropy_helpers.sphinx.ext.astropyautosummary', 'astropy_helpers.sphinx.ext.automodsumm', 'astropy_helpers.sphinx.ext.automodapi', 'astropy_helpers.sphinx.ext.tocdepthfix', 'astropy_helpers.sphinx.ext.doctest', 'astropy_helpers.sphinx.ext.changelog_links', 'astropy_helpers.sphinx.ext.viewcode', # Use patched version of viewcode 'astropy_helpers.sphinx.ext.smart_resolver' ] # Above, we use a patched version of viewcode rather than 'sphinx.ext.viewcode' # This can be changed to the sphinx version once the following issue is fixed # in sphinx: # https://bitbucket.org/birkenfeld/sphinx/issue/623/ # extension-viewcode-fails-with-function try: import matplotlib.sphinxext.plot_directive extensions += [matplotlib.sphinxext.plot_directive.__name__] # AttributeError is checked here in case matplotlib is installed but # Sphinx isn't. Note that this module is imported by the config file # generator, even if we're not building the docs. except (ImportError, AttributeError): warnings.warn( "matplotlib's plot_directive could not be imported. " + "Inline plots will not be included in the output") # Don't show summaries of the members in each class along with the # class' docstring numpydoc_show_class_members = False autosummary_generate = True automodapi_toctreedirnm = 'api' # Class documentation should contain *both* the class docstring and # the __init__ docstring autoclass_content = "both" # -- Options for HTML output ------------------------------------------------- # Add any paths that contain custom themes here, relative to this directory. html_theme_path = [path.abspath(path.join(path.dirname(__file__), 'themes'))] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'bootstrap-astropy' # Custom sidebar templates, maps document names to template names. html_sidebars = { '**': ['localtoc.html'], 'search': [], 'genindex': [], 'py-modindex': [], } # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # included in the bootstrap-astropy theme html_favicon = path.join(html_theme_path[0], html_theme, 'static', 'astropy_logo.ico') # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%d %b %Y' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # -- Options for LaTeX output ------------------------------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. latex_use_parts = True # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. latex_preamble = r""" % Use a more modern-looking monospace font \usepackage{inconsolata} % The enumitem package provides unlimited nesting of lists and enums. % Sphinx may use this in the future, in which case this can be removed. % See https://bitbucket.org/birkenfeld/sphinx/issue/777/latex-output-too-deeply-nested \usepackage{enumitem} \setlistdepth{15} % In the parameters section, place a newline after the Parameters % header. (This is stolen directly from Numpy's conf.py, since it % affects Numpy-style docstrings). \usepackage{expdlist} \let\latexdescription=\description \def\description{\latexdescription{}{} \breaklabel} % Support the superscript Unicode numbers used by the "unicode" units % formatter \DeclareUnicodeCharacter{2070}{\ensuremath{^0}} \DeclareUnicodeCharacter{00B9}{\ensuremath{^1}} \DeclareUnicodeCharacter{00B2}{\ensuremath{^2}} \DeclareUnicodeCharacter{00B3}{\ensuremath{^3}} \DeclareUnicodeCharacter{2074}{\ensuremath{^4}} \DeclareUnicodeCharacter{2075}{\ensuremath{^5}} \DeclareUnicodeCharacter{2076}{\ensuremath{^6}} \DeclareUnicodeCharacter{2077}{\ensuremath{^7}} \DeclareUnicodeCharacter{2078}{\ensuremath{^8}} \DeclareUnicodeCharacter{2079}{\ensuremath{^9}} \DeclareUnicodeCharacter{207B}{\ensuremath{^-}} \DeclareUnicodeCharacter{00B0}{\ensuremath{^{\circ}}} \DeclareUnicodeCharacter{2032}{\ensuremath{^{\prime}}} \DeclareUnicodeCharacter{2033}{\ensuremath{^{\prime\prime}}} % Make the "warning" and "notes" sections use a sans-serif font to % make them stand out more. \renewenvironment{notice}[2]{ \def\py@noticetype{#1} \csname py@noticestart@#1\endcsname \textsf{\textbf{#2}} }{\csname py@noticeend@\py@noticetype\endcsname} """ # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # -- Options for the linkcheck builder ---------------------------------------- # A timeout value, in seconds, for the linkcheck builder linkcheck_timeout = 60 astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/0000755000077000000240000000000012505171566031522 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/__init__.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/__init_0000644000077000000240000000013612354456432033045 0ustar adamstaff00000000000000from __future__ import division, absolute_import, print_function from .numpydoc import setup ././@LongLink0000000000000000000000000000016300000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/astropyautosummary.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/astropy0000644000077000000240000000652712425434461033155 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension builds off of `sphinx.ext.autosummary` to clean up some issues it presents in the Astropy docs. The main issue this fixes is the summary tables getting cut off before the end of the sentence in some cases. """ import re from sphinx.ext.autosummary import Autosummary # used in AstropyAutosummary.get_items _itemsummrex = re.compile(r'^([A-Z].*?\.(?:\s|$))') class AstropyAutosummary(Autosummary): def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ from sphinx.ext.autosummary import (get_import_prefixes_from_env, import_by_name, get_documenter, mangle_signature) env = self.state.document.settings.env prefixes = get_import_prefixes_from_env(env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: import_by_name_values = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('[astropyautosummary] failed to import %s' % name) items.append((name, '', '', name)) continue # to accommodate Sphinx v1.2.2 and v1.2.3 if len(import_by_name_values) == 3: real_name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: real_name, obj, parent, module_name = import_by_name_values # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('[astropyautosummary] failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): self.warn('[astropyautosummary] failed to import object %s' % real_name) items.append((display_name, '', '', real_name)) continue # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the summary doc = list(documenter.process_doc(documenter.get_doc())) while doc and not doc[0].strip(): doc.pop(0) m = _itemsummrex.search(" ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items def setup(app): # need autosummary, of course app.setup_extension('sphinx.ext.autosummary') # this replaces the default autosummary with the astropy one app.add_directive('autosummary', AstropyAutosummary) ././@LongLink0000000000000000000000000000015300000000000011214 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/automodapi.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/automod0000644000077000000240000003060512401041777033114 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension adds a tools to simplify generating the API documentation for Astropy packages and affiliated packages. .. _automodapi: ======================== automodapi directive ======================== This directive takes a single argument that must be a module or package. It will produce a block of documentation that includes the docstring for the package, an :ref:`automodsumm` directive, and an :ref:`automod-diagram` if there are any classes in the module. If only the main docstring of the module/package is desired in the documentation, use `automodule`_ instead of `automodapi`_. It accepts the following options: * ``:no-inheritance-diagram:`` If present, the inheritance diagram will not be shown even if the module/package has classes. * ``:skip: str`` This option results in the specified object being skipped, that is the object will *not* be included in the generated documentation. This option may appear any number of times to skip multiple objects. * ``:no-main-docstr:`` If present, the docstring for the module/package will not be generated. The function and class tables will still be used, however. * ``:headings: str`` Specifies the characters (in one string) used as the heading levels used for the generated section. This must have at least 2 characters (any after 2 will be ignored). This also *must* match the rest of the documentation on this page for sphinx to be happy. Defaults to "-^", which matches the convention used for Python's documentation, assuming the automodapi call is inside a top-level section (which usually uses '='). * ``:no-heading:`` If specified do not create a top level heading for the section. That is, do not create a title heading with text like "packagename Package". The actual docstring for the package/module will still be shown, though, unless ``:no-main-docstr:`` is given. * ``:allowed-package-names: str`` Specifies the packages that functions/classes documented here are allowed to be from, as comma-separated list of package names. If not given, only objects that are actually in a subpackage of the package currently being documented are included. This extension also adds two sphinx configuration options: * ``automodapi_toctreedirnm`` This must be a string that specifies the name of the directory the automodsumm generated documentation ends up in. This directory path should be relative to the documentation root (e.g., same place as ``index.rst``). Defaults to ``'api'``. * ``automodapi_writereprocessed`` Should be a bool, and if `True`, will cause `automodapi`_ to write files with any `automodapi`_ sections replaced with the content Sphinx processes after `automodapi`_ has run. The output files are not actually used by sphinx, so this option is only for figuring out the cause of sphinx warnings or other debugging. Defaults to `False`. .. _automodule: http://sphinx-doc.org/latest/ext/autodoc.html?highlight=automodule#directive-automodule """ # Implementation note: # The 'automodapi' directive is not actually implemented as a docutils # directive. Instead, this extension searches for the 'automodapi' text in # all sphinx documents, and replaces it where necessary from a template built # into this extension. This is necessary because automodsumm (and autosummary) # use the "builder-inited" event, which comes before the directives are # actually built. import inspect import os import re import sys from .utils import find_mod_objs automod_templ_modheader = """ {modname} {pkgormod} {modhds}{pkgormodhds} {automoduleline} """ automod_templ_classes = """ Classes {clshds} .. automodsumm:: {modname} :classes-only: {clsfuncoptions} """ automod_templ_funcs = """ Functions {funchds} .. automodsumm:: {modname} :functions-only: {clsfuncoptions} """ automod_templ_inh = """ Class Inheritance Diagram {clsinhsechds} .. automod-diagram:: {modname} :private-bases: :parts: 1 {allowedpkgnms} """ _automodapirex = re.compile(r'^(?:\s*\.\.\s+automodapi::\s*)([A-Za-z0-9_.]+)' r'\s*$((?:\n\s+:[a-zA-Z_\-]+:.*$)*)', flags=re.MULTILINE) # the last group of the above regex is intended to go into finall with the below _automodapiargsrex = re.compile(r':([a-zA-Z_\-]+):(.*)$', flags=re.MULTILINE) def automodapi_replace(sourcestr, app, dotoctree=True, docname=None, warnings=True): """ Replaces `sourcestr`'s entries of ".. automdapi::" with the automodapi template form based on provided options. This is used with the sphinx event 'source-read' to replace `automodapi`_ entries before sphinx actually processes them, as automodsumm needs the code to be present to generate stub documentation. Parameters ---------- sourcestr : str The string with sphinx source to be checked for automodapi replacement. app : `sphinx.application.Application` The sphinx application. dotoctree : bool If `True`, a ":toctree:" option will be added in the ".. automodsumm::" sections of the template, pointing to the appropriate "generated" directory based on the Astropy convention (e.g. in ``docs/api``) docname : str The name of the file for this `sourcestr` (if known - if not, it can be `None`). If not provided and `dotoctree` is `True`, the generated files may end up in the wrong place. warnings : bool If `False`, all warnings that would normally be issued are silenced. Returns ------- newstr :str The string with automodapi entries replaced with the correct sphinx markup. """ spl = _automodapirex.split(sourcestr) if len(spl) > 1: # automodsumm is in this document if dotoctree: toctreestr = ':toctree: ' dirnm = app.config.automodapi_toctreedirnm if not dirnm.endswith(os.sep): dirnm += os.sep if docname is not None: toctreestr += '../' * docname.count('/') + dirnm else: toctreestr += dirnm else: toctreestr = '' newstrs = [spl[0]] for grp in range(len(spl) // 3): modnm = spl[grp * 3 + 1] # find where this is in the document for warnings if docname is None: location = None else: location = (docname, spl[0].count('\n')) # initialize default options toskip = [] inhdiag = maindocstr = top_head = True hds = '-^' allowedpkgnms = [] # look for actual options unknownops = [] for opname, args in _automodapiargsrex.findall(spl[grp * 3 + 2]): if opname == 'skip': toskip.append(args.strip()) elif opname == 'no-inheritance-diagram': inhdiag = False elif opname == 'no-main-docstr': maindocstr = False elif opname == 'headings': hds = args elif opname == 'no-heading': top_head = False elif opname == 'allowed-package-names': allowedpkgnms.append(args.strip()) else: unknownops.append(opname) #join all the allowedpkgnms if len(allowedpkgnms) == 0: allowedpkgnms = '' onlylocals = True else: allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms) onlylocals = allowedpkgnms # get the two heading chars if len(hds) < 2: msg = 'Not enough headings (got {0}, need 2), using default -^' if warnings: app.warn(msg.format(len(hds)), location) hds = '-^' h1, h2 = hds.lstrip()[:2] # tell sphinx that the remaining args are invalid. if len(unknownops) > 0 and app is not None: opsstrs = ','.join(unknownops) msg = 'Found additional options ' + opsstrs + ' in automodapi.' if warnings: app.warn(msg, location) ispkg, hascls, hasfuncs = _mod_info(modnm, toskip, onlylocals=onlylocals) # add automodule directive only if no-main-docstr isn't present if maindocstr: automodline = '.. automodule:: {modname}'.format(modname=modnm) else: automodline = '' if top_head: newstrs.append(automod_templ_modheader.format(modname=modnm, modhds=h1 * len(modnm), pkgormod='Package' if ispkg else 'Module', pkgormodhds=h1 * (8 if ispkg else 7), automoduleline=automodline)) else: newstrs.append(automod_templ_modheader.format( modname='', modhds='', pkgormod='', pkgormodhds='', automoduleline=automodline)) #construct the options for the class/function sections #start out indented at 4 spaces, but need to keep the indentation. clsfuncoptions = [] if toctreestr: clsfuncoptions.append(toctreestr) if toskip: clsfuncoptions.append(':skip: ' + ','.join(toskip)) if allowedpkgnms: clsfuncoptions.append(allowedpkgnms) clsfuncoptionstr = '\n '.join(clsfuncoptions) if hasfuncs: newstrs.append(automod_templ_funcs.format( modname=modnm, funchds=h2 * 9, clsfuncoptions=clsfuncoptionstr)) if hascls: newstrs.append(automod_templ_classes.format( modname=modnm, clshds=h2 * 7, clsfuncoptions=clsfuncoptionstr)) if inhdiag and hascls: # add inheritance diagram if any classes are in the module newstrs.append(automod_templ_inh.format( modname=modnm, clsinhsechds=h2 * 25, allowedpkgnms=allowedpkgnms)) newstrs.append(spl[grp * 3 + 3]) newsourcestr = ''.join(newstrs) if app.config.automodapi_writereprocessed: # sometimes they are unicode, sometimes not, depending on how # sphinx has processed things if isinstance(newsourcestr, unicode): ustr = newsourcestr else: ustr = newsourcestr.decode(app.config.source_encoding) if docname is None: with open(os.path.join(app.srcdir, 'unknown.automodapi'), 'a') as f: f.write('\n**NEW DOC**\n\n') f.write(ustr.encode('utf8')) else: with open(os.path.join(app.srcdir, docname + '.automodapi'), 'w') as f: f.write(ustr.encode('utf8')) return newsourcestr else: return sourcestr def _mod_info(modname, toskip=[], onlylocals=True): """ Determines if a module is a module or a package and whether or not it has classes or functions. """ hascls = hasfunc = False for localnm, fqnm, obj in zip(*find_mod_objs(modname, onlylocals=onlylocals)): if localnm not in toskip: hascls = hascls or inspect.isclass(obj) hasfunc = hasfunc or inspect.isroutine(obj) if hascls and hasfunc: break # find_mod_objs has already imported modname pkg = sys.modules[modname] ispkg = '__init__.' in os.path.split(pkg.__name__)[1] return ispkg, hascls, hasfunc def process_automodapi(app, docname, source): source[0] = automodapi_replace(source[0], app, True, docname) def setup(app): # need automodsumm for automodapi app.setup_extension('astropy_helpers.sphinx.ext.automodsumm') app.connect('source-read', process_automodapi) app.add_config_value('automodapi_toctreedirnm', 'api', True) app.add_config_value('automodapi_writereprocessed', False, True) ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/automodsumm.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/automod0000644000077000000240000005451312453761452033126 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension adds two directives for summarizing the public members of a module or package. These directives are primarily for use with the `automodapi`_ extension, but can be used independently. .. _automodsumm: ======================= automodsumm directive ======================= This directive will produce an "autosummary"-style table for public attributes of a specified module. See the `sphinx.ext.autosummary`_ extension for details on this process. The main difference from the `autosummary`_ directive is that `autosummary`_ requires manually inputting all attributes that appear in the table, while this captures the entries automatically. This directive requires a single argument that must be a module or package. It also accepts any options supported by the `autosummary`_ directive- see `sphinx.ext.autosummary`_ for details. It also accepts two additional options: * ``:classes-only:`` If present, the autosummary table will only contain entries for classes. This cannot be used at the same time with ``:functions-only:`` . * ``:functions-only:`` If present, the autosummary table will only contain entries for functions. This cannot be used at the same time with ``:classes-only:`` . * ``:skip: obj1, [obj2, obj3, ...]`` If present, specifies that the listed objects should be skipped and not have their documentation generated, nor be includded in the summary table. * ``:allowed-package-names: pkgormod1, [pkgormod2, pkgormod3, ...]`` Specifies the packages that functions/classes documented here are allowed to be from, as comma-separated list of package names. If not given, only objects that are actually in a subpackage of the package currently being documented are included. This extension also adds one sphinx configuration option: * ``automodsumm_writereprocessed`` Should be a bool, and if True, will cause `automodsumm`_ to write files with any ``automodsumm`` sections replaced with the content Sphinx processes after ``automodsumm`` has run. The output files are not actually used by sphinx, so this option is only for figuring out the cause of sphinx warnings or other debugging. Defaults to `False`. .. _sphinx.ext.autosummary: http://sphinx-doc.org/latest/ext/autosummary.html .. _autosummary: http://sphinx-doc.org/latest/ext/autosummary.html#directive-autosummary .. _automod-diagram: =========================== automod-diagram directive =========================== This directive will produce an inheritance diagram like that of the `sphinx.ext.inheritance_diagram`_ extension. This directive requires a single argument that must be a module or package. It accepts no options. .. note:: Like 'inheritance-diagram', 'automod-diagram' requires `graphviz `_ to generate the inheritance diagram. .. _sphinx.ext.inheritance_diagram: http://sphinx-doc.org/latest/ext/inheritance.html """ import inspect import os import re from sphinx.ext.autosummary import Autosummary from sphinx.ext.inheritance_diagram import InheritanceDiagram from docutils.parsers.rst.directives import flag from .utils import find_mod_objs from .astropyautosummary import AstropyAutosummary def _str_list_converter(argument): """ A directive option conversion function that converts the option into a list of strings. Used for 'skip' option. """ if argument is None: return [] else: return [s.strip() for s in argument.split(',')] class Automodsumm(AstropyAutosummary): required_arguments = 1 optional_arguments = 0 final_argument_whitespace = False has_content = False option_spec = dict(Autosummary.option_spec) option_spec['functions-only'] = flag option_spec['classes-only'] = flag option_spec['skip'] = _str_list_converter option_spec['allowed-package-names'] = _str_list_converter def run(self): env = self.state.document.settings.env modname = self.arguments[0] self.warnings = [] nodelist = [] try: localnames, fqns, objs = find_mod_objs(modname) except ImportError: self.warnings = [] self.warn("Couldn't import module " + modname) return self.warnings try: # set self.content to trick the Autosummary internals. # Be sure to respect functions-only and classes-only. funconly = 'functions-only' in self.options clsonly = 'classes-only' in self.options skipnames = [] if 'skip' in self.options: option_skipnames = set(self.options['skip']) for lnm in localnames: if lnm in option_skipnames: option_skipnames.remove(lnm) skipnames.append(lnm) if len(option_skipnames) > 0: self.warn('Tried to skip objects {objs} in module {mod}, ' 'but they were not present. Ignoring.'.format( objs=option_skipnames, mod=modname)) if funconly and not clsonly: cont = [] for nm, obj in zip(localnames, objs): if nm not in skipnames and inspect.isroutine(obj): cont.append(nm) elif clsonly: cont = [] for nm, obj in zip(localnames, objs): if nm not in skipnames and inspect.isclass(obj): cont.append(nm) else: if clsonly and funconly: self.warning('functions-only and classes-only both ' 'defined. Skipping.') cont = [nm for nm in localnames if nm not in skipnames] self.content = cont #for some reason, even though ``currentmodule`` is substituted in, sphinx #doesn't necessarily recognize this fact. So we just force it #internally, and that seems to fix things env.temp_data['py:module'] = modname #can't use super because Sphinx/docutils has trouble #return super(Autosummary,self).run() nodelist.extend(Autosummary.run(self)) return self.warnings + nodelist finally: # has_content = False for the Automodsumm self.content = [] #<-------------------automod-diagram stuff------------------------------------> class Automoddiagram(InheritanceDiagram): option_spec = dict(InheritanceDiagram.option_spec) option_spec['allowed-package-names'] = _str_list_converter def run(self): try: ols = self.options.get('allowed-package-names', []) ols = True if len(ols) == 0 else ols # if none are given, assume only local nms, objs = find_mod_objs(self.arguments[0], onlylocals=ols)[1:] except ImportError: self.warnings = [] self.warn("Couldn't import module " + self.arguments[0]) return self.warnings clsnms = [] for n, o in zip(nms, objs): if inspect.isclass(o): clsnms.append(n) oldargs = self.arguments try: if len(clsnms) > 0: self.arguments = [' '.join(clsnms)] return InheritanceDiagram.run(self) finally: self.arguments = oldargs #<---------------------automodsumm generation stuff---------------------------> def process_automodsumm_generation(app): env = app.builder.env ext = app.config.source_suffix filestosearch = [x + ext for x in env.found_docs if os.path.isfile(env.doc2path(x))]\ liness = [] for sfn in filestosearch: lines = automodsumm_to_autosummary_lines(sfn, app) liness.append(lines) if app.config.automodsumm_writereprocessed: if lines: # empty list means no automodsumm entry is in the file outfn = os.path.join(app.srcdir, sfn) + '.automodsumm' with open(outfn, 'w') as f: for l in lines: f.write(l) f.write('\n') for sfn, lines in zip(filestosearch, liness): if len(lines) > 0: generate_automodsumm_docs(lines, sfn, builder=app.builder, warn=app.warn, info=app.info, suffix=app.config.source_suffix, base_path=app.srcdir) #_automodsummrex = re.compile(r'^(\s*)\.\. automodsumm::\s*([A-Za-z0-9_.]+)\s*' # r'\n\1(\s*)(\S|$)', re.MULTILINE) _lineendrex = r'(?:\n|$)' _hdrex = r'^\n?(\s*)\.\. automodsumm::\s*(\S+)\s*' + _lineendrex _oprex1 = r'(?:\1(\s+)\S.*' + _lineendrex + ')' _oprex2 = r'(?:\1\4\S.*' + _lineendrex + ')' _automodsummrex = re.compile(_hdrex + '(' + _oprex1 + '?' + _oprex2 + '*)', re.MULTILINE) def automodsumm_to_autosummary_lines(fn, app): """ Generates lines from a file with an "automodsumm" entry suitable for feeding into "autosummary". Searches the provided file for `automodsumm` directives and returns a list of lines specifying the `autosummary` commands for the modules requested. This does *not* return the whole file contents - just an autosummary section in place of any :automodsumm: entries. Note that any options given for `automodsumm` are also included in the generated `autosummary` section. Parameters ---------- fn : str The name of the file to search for `automodsumm` entries. app : sphinx.application.Application The sphinx Application object Return ------ lines : list of str Lines for all `automodsumm` entries with the entries replaced by `autosummary` and the module's members added. """ fullfn = os.path.join(app.builder.env.srcdir, fn) with open(fullfn) as fr: if 'astropy_helpers.sphinx.ext.automodapi' in app._extensions: from astropy_helpers.sphinx.ext.automodapi import automodapi_replace # Must do the automodapi on the source to get the automodsumm # that might be in there filestr = automodapi_replace(fr.read(), app, True, fn, False) else: filestr = fr.read() spl = _automodsummrex.split(filestr) #0th entry is the stuff before the first automodsumm line indent1s = spl[1::5] mods = spl[2::5] opssecs = spl[3::5] indent2s = spl[4::5] remainders = spl[5::5] # only grab automodsumm sections and convert them to autosummary with the # entries for all the public objects newlines = [] #loop over all automodsumms in this document for i, (i1, i2, modnm, ops, rem) in enumerate(zip(indent1s, indent2s, mods, opssecs, remainders)): allindent = i1 + ('' if i2 is None else i2) #filter out functions-only and classes-only options if present oplines = ops.split('\n') toskip = [] allowedpkgnms = [] funcsonly = clssonly = False for i, ln in reversed(list(enumerate(oplines))): if ':functions-only:' in ln: funcsonly = True del oplines[i] if ':classes-only:' in ln: clssonly = True del oplines[i] if ':skip:' in ln: toskip.extend(_str_list_converter(ln.replace(':skip:', ''))) del oplines[i] if ':allowed-package-names:' in ln: allowedpkgnms.extend(_str_list_converter(ln.replace(':allowed-package-names:', ''))) del oplines[i] if funcsonly and clssonly: msg = ('Defined both functions-only and classes-only options. ' 'Skipping this directive.') lnnum = sum([spl[j].count('\n') for j in range(i * 5 + 1)]) app.warn('[automodsumm]' + msg, (fn, lnnum)) continue # Use the currentmodule directive so we can just put the local names # in the autosummary table. Note that this doesn't always seem to # actually "take" in Sphinx's eyes, so in `Automodsumm.run`, we have to # force it internally, as well. newlines.extend([i1 + '.. currentmodule:: ' + modnm, '', '.. autosummary::']) newlines.extend(oplines) ols = True if len(allowedpkgnms) == 0 else allowedpkgnms for nm, fqn, obj in zip(*find_mod_objs(modnm, onlylocals=ols)): if nm in toskip: continue if funcsonly and not inspect.isroutine(obj): continue if clssonly and not inspect.isclass(obj): continue newlines.append(allindent + nm) return newlines def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None, info=None, base_path=None, builder=None, template_dir=None): """ This function is adapted from `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to generate source for the automodsumm directives that should be autosummarized. Unlike generate_autosummary_docs, this function is called one file at a time. """ from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.ext.autosummary import import_by_name, get_documenter from sphinx.ext.autosummary.generate import (find_autosummary_in_lines, _simple_info, _simple_warn) from sphinx.util.osutil import ensuredir from sphinx.util.inspect import safe_getattr from jinja2 import FileSystemLoader, TemplateNotFound from jinja2.sandbox import SandboxedEnvironment if info is None: info = _simple_info if warn is None: warn = _simple_warn #info('[automodsumm] generating automodsumm for: ' + srcfn) # Create our own templating environment - here we use Astropy's # templates rather than the default autosummary templates, in order to # allow docstrings to be shown for methods. template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'), os.path.join(base_path, '_templates')] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read #items = find_autosummary_in_files(sources) items = find_autosummary_in_lines(lines, filename=srcfn) if len(items) > 0: msg = '[automodsumm] {1}: found {0} automodsumm entries to generate' info(msg.format(len(items), srcfn)) # gennms = [item[0] for item in items] # if len(gennms) > 20: # gennms = gennms[:10] + ['...'] + gennms[-10:] # info('[automodsumm] generating autosummary for: ' + ', '.join(gennms)) # remove possible duplicates items = dict([(item, True) for item in items]).keys() # keep track of new files new_files = [] # write for name, path, template_name in sorted(items): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = os.path.abspath(path) ensuredir(path) try: import_by_name_values = import_by_name(name) except ImportError as e: warn('[automodsumm] failed to import %r: %s' % (name, e)) continue # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively if len(import_by_name_values) == 3: name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: name, obj, parent, module_name = import_by_name_values fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) f = open(fn, 'w') try: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: tmplstr = 'autosummary/%s.rst' try: template = template_env.get_template(tmplstr % doc.objtype) except TemplateNotFound: template = template_env.get_template(tmplstr % 'base') def get_members_mod(obj, typ, include_public=[]): """ typ = None -> all """ items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class """ items = [] # using dir gets all of the attributes, including the elements # from the base class, otherwise use __slots__ or __dict__ if include_base: names = dir(obj) else: if hasattr(obj, '__slots__'): names = tuple(getattr(obj, '__slots__')) else: names = getattr(obj, '__dict__').keys() for name in names: try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} if doc.objtype == 'module': ns['members'] = get_members_mod(obj, None) ns['functions'], ns['all_functions'] = \ get_members_mod(obj, 'function') ns['classes'], ns['all_classes'] = \ get_members_mod(obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members_mod(obj, 'exception') elif doc.objtype == 'class': api_class_methods = ['__init__', '__call__'] ns['members'] = get_members_class(obj, None) ns['methods'], ns['all_methods'] = \ get_members_class(obj, 'method', api_class_methods) ns['attributes'], ns['all_attributes'] = \ get_members_class(obj, 'attribute') ns['methods'].sort() ns['attributes'].sort() parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' # We now check whether a file for reference footnotes exists for # the module being documented. We first check if the # current module is a file or a directory, as this will give a # different path for the reference file. For example, if # documenting astropy.wcs then the reference file is at # ../wcs/references.txt, while if we are documenting # astropy.config.logging_helper (which is at # astropy/config/logging_helper.py) then the reference file is set # to ../config/references.txt if '.' in mod_name: mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1] else: mod_name_dir = mod_name if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \ and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])): mod_name_dir = mod_name_dir.rsplit('/', 1)[0] # We then have to check whether it exists, and if so, we pass it # to the template. if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')): # An important subtlety here is that the path we pass in has # to be relative to the file being generated, so we have to # figure out the right number of '..'s ndirsback = path.replace(base_path, '').count('/') ref_file_rel_segments = ['..'] * ndirsback ref_file_rel_segments.append(mod_name_dir) ref_file_rel_segments.append('references.txt') ns['referencefile'] = os.path.join(*ref_file_rel_segments) rendered = template.render(**ns) f.write(rendered) finally: f.close() def setup(app): # need our autosummary app.setup_extension('astropy_helpers.sphinx.ext.astropyautosummary') # need inheritance-diagram for automod-diagram app.setup_extension('sphinx.ext.inheritance_diagram') app.add_directive('automod-diagram', Automoddiagram) app.add_directive('automodsumm', Automodsumm) app.connect('builder-inited', process_automodsumm_generation) app.add_config_value('automodsumm_writereprocessed', False, True) ././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/changelog_links.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/changel0000644000077000000240000000542012403272746033046 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This sphinx extension makes the issue numbers in the changelog into links to GitHub issues. """ from __future__ import print_function import re from docutils.nodes import Text, reference BLOCK_PATTERN = re.compile('\[#.+\]', flags=re.DOTALL) ISSUE_PATTERN = re.compile('#[0-9]+') def process_changelog_links(app, doctree, docname): for rex in app.changelog_links_rexes: if rex.match(docname): break else: # if the doc doesn't match any of the changelog regexes, don't process return app.info('[changelog_links] Adding changelog links to "{0}"'.format(docname)) for item in doctree.traverse(): if not isinstance(item, Text): continue # We build a new list of items to replace the current item. If # a link is found, we need to use a 'reference' item. children = [] # First cycle through blocks of issues (delimited by []) then # iterate inside each one to find the individual issues. prev_block_end = 0 for block in BLOCK_PATTERN.finditer(item): block_start, block_end = block.start(), block.end() children.append(Text(item[prev_block_end:block_start])) block = item[block_start:block_end] prev_end = 0 for m in ISSUE_PATTERN.finditer(block): start, end = m.start(), m.end() children.append(Text(block[prev_end:start])) issue_number = block[start:end] refuri = app.config.github_issues_url + issue_number[1:] children.append(reference(text=issue_number, name=issue_number, refuri=refuri)) prev_end = end prev_block_end = block_end # If no issues were found, this adds the whole item, # otherwise it adds the remaining text. children.append(Text(block[prev_end:block_end])) # If no blocks were found, this adds the whole item, otherwise # it adds the remaining text. children.append(Text(item[prev_block_end:])) # Replace item by the new list of items we have generated, # which may contain links. item.parent.replace(item, children) def setup_patterns_rexes(app): app.changelog_links_rexes = [re.compile(pat) for pat in app.config.changelog_links_docpattern] def setup(app): app.connect('doctree-resolved', process_changelog_links) app.connect('builder-inited', setup_patterns_rexes) app.add_config_value('github_issues_url', None, True) app.add_config_value('changelog_links_docpattern', ['.*changelog.*', 'whatsnew/.*'], True) ././@LongLink0000000000000000000000000000015600000000000011217 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/comment_eater.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/comment0000644000077000000240000001245112354456432033112 0ustar adamstaff00000000000000from __future__ import division, absolute_import, print_function import sys if sys.version_info[0] >= 3: from io import StringIO else: from io import StringIO import compiler import inspect import textwrap import tokenize from .compiler_unparse import unparse class Comment(object): """ A comment block. """ is_comment = True def __init__(self, start_lineno, end_lineno, text): # int : The first line number in the block. 1-indexed. self.start_lineno = start_lineno # int : The last line number. Inclusive! self.end_lineno = end_lineno # str : The text block including '#' character but not any leading spaces. self.text = text def add(self, string, start, end, line): """ Add a new comment line. """ self.start_lineno = min(self.start_lineno, start[0]) self.end_lineno = max(self.end_lineno, end[0]) self.text += string def __repr__(self): return '%s(%r, %r, %r)' % (self.__class__.__name__, self.start_lineno, self.end_lineno, self.text) class NonComment(object): """ A non-comment block of code. """ is_comment = False def __init__(self, start_lineno, end_lineno): self.start_lineno = start_lineno self.end_lineno = end_lineno def add(self, string, start, end, line): """ Add lines to the block. """ if string.strip(): # Only add if not entirely whitespace. self.start_lineno = min(self.start_lineno, start[0]) self.end_lineno = max(self.end_lineno, end[0]) def __repr__(self): return '%s(%r, %r)' % (self.__class__.__name__, self.start_lineno, self.end_lineno) class CommentBlocker(object): """ Pull out contiguous comment blocks. """ def __init__(self): # Start with a dummy. self.current_block = NonComment(0, 0) # All of the blocks seen so far. self.blocks = [] # The index mapping lines of code to their associated comment blocks. self.index = {} def process_file(self, file): """ Process a file object. """ if sys.version_info[0] >= 3: nxt = file.__next__ else: nxt = file.next for token in tokenize.generate_tokens(nxt): self.process_token(*token) self.make_index() def process_token(self, kind, string, start, end, line): """ Process a single token. """ if self.current_block.is_comment: if kind == tokenize.COMMENT: self.current_block.add(string, start, end, line) else: self.new_noncomment(start[0], end[0]) else: if kind == tokenize.COMMENT: self.new_comment(string, start, end, line) else: self.current_block.add(string, start, end, line) def new_noncomment(self, start_lineno, end_lineno): """ We are transitioning from a noncomment to a comment. """ block = NonComment(start_lineno, end_lineno) self.blocks.append(block) self.current_block = block def new_comment(self, string, start, end, line): """ Possibly add a new comment. Only adds a new comment if this comment is the only thing on the line. Otherwise, it extends the noncomment block. """ prefix = line[:start[1]] if prefix.strip(): # Oops! Trailing comment, not a comment block. self.current_block.add(string, start, end, line) else: # A comment block. block = Comment(start[0], end[0], string) self.blocks.append(block) self.current_block = block def make_index(self): """ Make the index mapping lines of actual code to their associated prefix comments. """ for prev, block in zip(self.blocks[:-1], self.blocks[1:]): if not block.is_comment: self.index[block.start_lineno] = prev def search_for_comment(self, lineno, default=None): """ Find the comment block just before the given line number. Returns None (or the specified default) if there is no such block. """ if not self.index: self.make_index() block = self.index.get(lineno, None) text = getattr(block, 'text', default) return text def strip_comment_marker(text): """ Strip # markers at the front of a block of comment text. """ lines = [] for line in text.splitlines(): lines.append(line.lstrip('#')) text = textwrap.dedent('\n'.join(lines)) return text def get_class_traits(klass): """ Yield all of the documentation for trait definitions on a class object. """ # FIXME: gracefully handle errors here or in the caller? source = inspect.getsource(klass) cb = CommentBlocker() cb.process_file(StringIO(source)) mod_ast = compiler.parse(source) class_ast = mod_ast.node.nodes[0] for node in class_ast.code.nodes: # FIXME: handle other kinds of assignments? if isinstance(node, compiler.ast.Assign): name = node.nodes[0].name rhs = unparse(node.expr).strip() doc = strip_comment_marker(cb.search_for_comment(node.lineno, default='')) yield name, rhs, doc ././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/compiler_unparse.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/compile0000644000077000000240000006024412354456432033103 0ustar adamstaff00000000000000""" Turn compiler.ast structures back into executable python code. The unparse method takes a compiler.ast tree and transforms it back into valid python code. It is incomplete and currently only works for import statements, function calls, function definitions, assignments, and basic expressions. Inspired by python-2.5-svn/Demo/parser/unparse.py fixme: We may want to move to using _ast trees because the compiler for them is about 6 times faster than compiler.compile. """ from __future__ import division, absolute_import, print_function import sys from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add if sys.version_info[0] >= 3: from io import StringIO else: from StringIO import StringIO def unparse(ast, single_line_functions=False): s = StringIO() UnparseCompilerAst(ast, s, single_line_functions) return s.getvalue().lstrip() op_precedence = { 'compiler.ast.Power':3, 'compiler.ast.Mul':2, 'compiler.ast.Div':2, 'compiler.ast.Add':1, 'compiler.ast.Sub':1 } class UnparseCompilerAst: """ Methods in this class recursively traverse an AST and output source code for the abstract syntax; original formatting is disregarged. """ ######################################################################### # object interface. ######################################################################### def __init__(self, tree, file = sys.stdout, single_line_functions=False): """ Unparser(tree, file=sys.stdout) -> None. Print the source for tree to file. """ self.f = file self._single_func = single_line_functions self._do_indent = True self._indent = 0 self._dispatch(tree) self._write("\n") self.f.flush() ######################################################################### # Unparser private interface. ######################################################################### ### format, output, and dispatch methods ################################ def _fill(self, text = ""): "Indent a piece of text, according to the current indentation level" if self._do_indent: self._write("\n"+" "*self._indent + text) else: self._write(text) def _write(self, text): "Append a piece of text to the current line." self.f.write(text) def _enter(self): "Print ':', and increase the indentation." self._write(": ") self._indent += 1 def _leave(self): "Decrease the indentation level." self._indent -= 1 def _dispatch(self, tree): "_dispatcher function, _dispatching tree type T to method _T." if isinstance(tree, list): for t in tree: self._dispatch(t) return meth = getattr(self, "_"+tree.__class__.__name__) if tree.__class__.__name__ == 'NoneType' and not self._do_indent: return meth(tree) ######################################################################### # compiler.ast unparsing methods. # # There should be one method per concrete grammar type. They are # organized in alphabetical order. ######################################################################### def _Add(self, t): self.__binary_op(t, '+') def _And(self, t): self._write(" (") for i, node in enumerate(t.nodes): self._dispatch(node) if i != len(t.nodes)-1: self._write(") and (") self._write(")") def _AssAttr(self, t): """ Handle assigning an attribute of an object """ self._dispatch(t.expr) self._write('.'+t.attrname) def _Assign(self, t): """ Expression Assignment such as "a = 1". This only handles assignment in expressions. Keyword assignment is handled separately. """ self._fill() for target in t.nodes: self._dispatch(target) self._write(" = ") self._dispatch(t.expr) if not self._do_indent: self._write('; ') def _AssName(self, t): """ Name on left hand side of expression. Treat just like a name on the right side of an expression. """ self._Name(t) def _AssTuple(self, t): """ Tuple on left hand side of an expression. """ # _write each elements, separated by a comma. for element in t.nodes[:-1]: self._dispatch(element) self._write(", ") # Handle the last one without writing comma last_element = t.nodes[-1] self._dispatch(last_element) def _AugAssign(self, t): """ +=,-=,*=,/=,**=, etc. operations """ self._fill() self._dispatch(t.node) self._write(' '+t.op+' ') self._dispatch(t.expr) if not self._do_indent: self._write(';') def _Bitand(self, t): """ Bit and operation. """ for i, node in enumerate(t.nodes): self._write("(") self._dispatch(node) self._write(")") if i != len(t.nodes)-1: self._write(" & ") def _Bitor(self, t): """ Bit or operation """ for i, node in enumerate(t.nodes): self._write("(") self._dispatch(node) self._write(")") if i != len(t.nodes)-1: self._write(" | ") def _CallFunc(self, t): """ Function call. """ self._dispatch(t.node) self._write("(") comma = False for e in t.args: if comma: self._write(", ") else: comma = True self._dispatch(e) if t.star_args: if comma: self._write(", ") else: comma = True self._write("*") self._dispatch(t.star_args) if t.dstar_args: if comma: self._write(", ") else: comma = True self._write("**") self._dispatch(t.dstar_args) self._write(")") def _Compare(self, t): self._dispatch(t.expr) for op, expr in t.ops: self._write(" " + op + " ") self._dispatch(expr) def _Const(self, t): """ A constant value such as an integer value, 3, or a string, "hello". """ self._dispatch(t.value) def _Decorators(self, t): """ Handle function decorators (eg. @has_units) """ for node in t.nodes: self._dispatch(node) def _Dict(self, t): self._write("{") for i, (k, v) in enumerate(t.items): self._dispatch(k) self._write(": ") self._dispatch(v) if i < len(t.items)-1: self._write(", ") self._write("}") def _Discard(self, t): """ Node for when return value is ignored such as in "foo(a)". """ self._fill() self._dispatch(t.expr) def _Div(self, t): self.__binary_op(t, '/') def _Ellipsis(self, t): self._write("...") def _From(self, t): """ Handle "from xyz import foo, bar as baz". """ # fixme: Are From and ImportFrom handled differently? self._fill("from ") self._write(t.modname) self._write(" import ") for i, (name,asname) in enumerate(t.names): if i != 0: self._write(", ") self._write(name) if asname is not None: self._write(" as "+asname) def _Function(self, t): """ Handle function definitions """ if t.decorators is not None: self._fill("@") self._dispatch(t.decorators) self._fill("def "+t.name + "(") defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults) for i, arg in enumerate(zip(t.argnames, defaults)): self._write(arg[0]) if arg[1] is not None: self._write('=') self._dispatch(arg[1]) if i < len(t.argnames)-1: self._write(', ') self._write(")") if self._single_func: self._do_indent = False self._enter() self._dispatch(t.code) self._leave() self._do_indent = True def _Getattr(self, t): """ Handle getting an attribute of an object """ if isinstance(t.expr, (Div, Mul, Sub, Add)): self._write('(') self._dispatch(t.expr) self._write(')') else: self._dispatch(t.expr) self._write('.'+t.attrname) def _If(self, t): self._fill() for i, (compare,code) in enumerate(t.tests): if i == 0: self._write("if ") else: self._write("elif ") self._dispatch(compare) self._enter() self._fill() self._dispatch(code) self._leave() self._write("\n") if t.else_ is not None: self._write("else") self._enter() self._fill() self._dispatch(t.else_) self._leave() self._write("\n") def _IfExp(self, t): self._dispatch(t.then) self._write(" if ") self._dispatch(t.test) if t.else_ is not None: self._write(" else (") self._dispatch(t.else_) self._write(")") def _Import(self, t): """ Handle "import xyz.foo". """ self._fill("import ") for i, (name,asname) in enumerate(t.names): if i != 0: self._write(", ") self._write(name) if asname is not None: self._write(" as "+asname) def _Keyword(self, t): """ Keyword value assignment within function calls and definitions. """ self._write(t.name) self._write("=") self._dispatch(t.expr) def _List(self, t): self._write("[") for i,node in enumerate(t.nodes): self._dispatch(node) if i < len(t.nodes)-1: self._write(", ") self._write("]") def _Module(self, t): if t.doc is not None: self._dispatch(t.doc) self._dispatch(t.node) def _Mul(self, t): self.__binary_op(t, '*') def _Name(self, t): self._write(t.name) def _NoneType(self, t): self._write("None") def _Not(self, t): self._write('not (') self._dispatch(t.expr) self._write(')') def _Or(self, t): self._write(" (") for i, node in enumerate(t.nodes): self._dispatch(node) if i != len(t.nodes)-1: self._write(") or (") self._write(")") def _Pass(self, t): self._write("pass\n") def _Printnl(self, t): self._fill("print ") if t.dest: self._write(">> ") self._dispatch(t.dest) self._write(", ") comma = False for node in t.nodes: if comma: self._write(', ') else: comma = True self._dispatch(node) def _Power(self, t): self.__binary_op(t, '**') def _Return(self, t): self._fill("return ") if t.value: if isinstance(t.value, Tuple): text = ', '.join([ name.name for name in t.value.asList() ]) self._write(text) else: self._dispatch(t.value) if not self._do_indent: self._write('; ') def _Slice(self, t): self._dispatch(t.expr) self._write("[") if t.lower: self._dispatch(t.lower) self._write(":") if t.upper: self._dispatch(t.upper) #if t.step: # self._write(":") # self._dispatch(t.step) self._write("]") def _Sliceobj(self, t): for i, node in enumerate(t.nodes): if i != 0: self._write(":") if not (isinstance(node, Const) and node.value is None): self._dispatch(node) def _Stmt(self, tree): for node in tree.nodes: self._dispatch(node) def _Sub(self, t): self.__binary_op(t, '-') def _Subscript(self, t): self._dispatch(t.expr) self._write("[") for i, value in enumerate(t.subs): if i != 0: self._write(",") self._dispatch(value) self._write("]") def _TryExcept(self, t): self._fill("try") self._enter() self._dispatch(t.body) self._leave() for handler in t.handlers: self._fill('except ') self._dispatch(handler[0]) if handler[1] is not None: self._write(', ') self._dispatch(handler[1]) self._enter() self._dispatch(handler[2]) self._leave() if t.else_: self._fill("else") self._enter() self._dispatch(t.else_) self._leave() def _Tuple(self, t): if not t.nodes: # Empty tuple. self._write("()") else: self._write("(") # _write each elements, separated by a comma. for element in t.nodes[:-1]: self._dispatch(element) self._write(", ") # Handle the last one without writing comma last_element = t.nodes[-1] self._dispatch(last_element) self._write(")") def _UnaryAdd(self, t): self._write("+") self._dispatch(t.expr) def _UnarySub(self, t): self._write("-") self._dispatch(t.expr) def _With(self, t): self._fill('with ') self._dispatch(t.expr) if t.vars: self._write(' as ') self._dispatch(t.vars.name) self._enter() self._dispatch(t.body) self._leave() self._write('\n') def _int(self, t): self._write(repr(t)) def __binary_op(self, t, symbol): # Check if parenthesis are needed on left side and then dispatch has_paren = False left_class = str(t.left.__class__) if (left_class in op_precedence.keys() and op_precedence[left_class] < op_precedence[str(t.__class__)]): has_paren = True if has_paren: self._write('(') self._dispatch(t.left) if has_paren: self._write(')') # Write the appropriate symbol for operator self._write(symbol) # Check if parenthesis are needed on the right side and then dispatch has_paren = False right_class = str(t.right.__class__) if (right_class in op_precedence.keys() and op_precedence[right_class] < op_precedence[str(t.__class__)]): has_paren = True if has_paren: self._write('(') self._dispatch(t.right) if has_paren: self._write(')') def _float(self, t): # if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001' # We prefer str here. self._write(str(t)) def _str(self, t): self._write(repr(t)) def _tuple(self, t): self._write(str(t)) ######################################################################### # These are the methods from the _ast modules unparse. # # As our needs to handle more advanced code increase, we may want to # modify some of the methods below so that they work for compiler.ast. ######################################################################### # # stmt # def _Expr(self, tree): # self._fill() # self._dispatch(tree.value) # # def _Import(self, t): # self._fill("import ") # first = True # for a in t.names: # if first: # first = False # else: # self._write(", ") # self._write(a.name) # if a.asname: # self._write(" as "+a.asname) # ## def _ImportFrom(self, t): ## self._fill("from ") ## self._write(t.module) ## self._write(" import ") ## for i, a in enumerate(t.names): ## if i == 0: ## self._write(", ") ## self._write(a.name) ## if a.asname: ## self._write(" as "+a.asname) ## # XXX(jpe) what is level for? ## # # def _Break(self, t): # self._fill("break") # # def _Continue(self, t): # self._fill("continue") # # def _Delete(self, t): # self._fill("del ") # self._dispatch(t.targets) # # def _Assert(self, t): # self._fill("assert ") # self._dispatch(t.test) # if t.msg: # self._write(", ") # self._dispatch(t.msg) # # def _Exec(self, t): # self._fill("exec ") # self._dispatch(t.body) # if t.globals: # self._write(" in ") # self._dispatch(t.globals) # if t.locals: # self._write(", ") # self._dispatch(t.locals) # # def _Print(self, t): # self._fill("print ") # do_comma = False # if t.dest: # self._write(">>") # self._dispatch(t.dest) # do_comma = True # for e in t.values: # if do_comma:self._write(", ") # else:do_comma=True # self._dispatch(e) # if not t.nl: # self._write(",") # # def _Global(self, t): # self._fill("global") # for i, n in enumerate(t.names): # if i != 0: # self._write(",") # self._write(" " + n) # # def _Yield(self, t): # self._fill("yield") # if t.value: # self._write(" (") # self._dispatch(t.value) # self._write(")") # # def _Raise(self, t): # self._fill('raise ') # if t.type: # self._dispatch(t.type) # if t.inst: # self._write(", ") # self._dispatch(t.inst) # if t.tback: # self._write(", ") # self._dispatch(t.tback) # # # def _TryFinally(self, t): # self._fill("try") # self._enter() # self._dispatch(t.body) # self._leave() # # self._fill("finally") # self._enter() # self._dispatch(t.finalbody) # self._leave() # # def _excepthandler(self, t): # self._fill("except ") # if t.type: # self._dispatch(t.type) # if t.name: # self._write(", ") # self._dispatch(t.name) # self._enter() # self._dispatch(t.body) # self._leave() # # def _ClassDef(self, t): # self._write("\n") # self._fill("class "+t.name) # if t.bases: # self._write("(") # for a in t.bases: # self._dispatch(a) # self._write(", ") # self._write(")") # self._enter() # self._dispatch(t.body) # self._leave() # # def _FunctionDef(self, t): # self._write("\n") # for deco in t.decorators: # self._fill("@") # self._dispatch(deco) # self._fill("def "+t.name + "(") # self._dispatch(t.args) # self._write(")") # self._enter() # self._dispatch(t.body) # self._leave() # # def _For(self, t): # self._fill("for ") # self._dispatch(t.target) # self._write(" in ") # self._dispatch(t.iter) # self._enter() # self._dispatch(t.body) # self._leave() # if t.orelse: # self._fill("else") # self._enter() # self._dispatch(t.orelse) # self._leave # # def _While(self, t): # self._fill("while ") # self._dispatch(t.test) # self._enter() # self._dispatch(t.body) # self._leave() # if t.orelse: # self._fill("else") # self._enter() # self._dispatch(t.orelse) # self._leave # # # expr # def _Str(self, tree): # self._write(repr(tree.s)) ## # def _Repr(self, t): # self._write("`") # self._dispatch(t.value) # self._write("`") # # def _Num(self, t): # self._write(repr(t.n)) # # def _ListComp(self, t): # self._write("[") # self._dispatch(t.elt) # for gen in t.generators: # self._dispatch(gen) # self._write("]") # # def _GeneratorExp(self, t): # self._write("(") # self._dispatch(t.elt) # for gen in t.generators: # self._dispatch(gen) # self._write(")") # # def _comprehension(self, t): # self._write(" for ") # self._dispatch(t.target) # self._write(" in ") # self._dispatch(t.iter) # for if_clause in t.ifs: # self._write(" if ") # self._dispatch(if_clause) # # def _IfExp(self, t): # self._dispatch(t.body) # self._write(" if ") # self._dispatch(t.test) # if t.orelse: # self._write(" else ") # self._dispatch(t.orelse) # # unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} # def _UnaryOp(self, t): # self._write(self.unop[t.op.__class__.__name__]) # self._write("(") # self._dispatch(t.operand) # self._write(")") # # binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%", # "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&", # "FloorDiv":"//", "Pow": "**"} # def _BinOp(self, t): # self._write("(") # self._dispatch(t.left) # self._write(")" + self.binop[t.op.__class__.__name__] + "(") # self._dispatch(t.right) # self._write(")") # # boolops = {_ast.And: 'and', _ast.Or: 'or'} # def _BoolOp(self, t): # self._write("(") # self._dispatch(t.values[0]) # for v in t.values[1:]: # self._write(" %s " % self.boolops[t.op.__class__]) # self._dispatch(v) # self._write(")") # # def _Attribute(self,t): # self._dispatch(t.value) # self._write(".") # self._write(t.attr) # ## def _Call(self, t): ## self._dispatch(t.func) ## self._write("(") ## comma = False ## for e in t.args: ## if comma: self._write(", ") ## else: comma = True ## self._dispatch(e) ## for e in t.keywords: ## if comma: self._write(", ") ## else: comma = True ## self._dispatch(e) ## if t.starargs: ## if comma: self._write(", ") ## else: comma = True ## self._write("*") ## self._dispatch(t.starargs) ## if t.kwargs: ## if comma: self._write(", ") ## else: comma = True ## self._write("**") ## self._dispatch(t.kwargs) ## self._write(")") # # # slice # def _Index(self, t): # self._dispatch(t.value) # # def _ExtSlice(self, t): # for i, d in enumerate(t.dims): # if i != 0: # self._write(': ') # self._dispatch(d) # # # others # def _arguments(self, t): # first = True # nonDef = len(t.args)-len(t.defaults) # for a in t.args[0:nonDef]: # if first:first = False # else: self._write(", ") # self._dispatch(a) # for a,d in zip(t.args[nonDef:], t.defaults): # if first:first = False # else: self._write(", ") # self._dispatch(a), # self._write("=") # self._dispatch(d) # if t.vararg: # if first:first = False # else: self._write(", ") # self._write("*"+t.vararg) # if t.kwarg: # if first:first = False # else: self._write(", ") # self._write("**"+t.kwarg) # ## def _keyword(self, t): ## self._write(t.arg) ## self._write("=") ## self._dispatch(t.value) # # def _Lambda(self, t): # self._write("lambda ") # self._dispatch(t.args) # self._write(": ") # self._dispatch(t.body) ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/docscrape.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/docscra0000644000077000000240000003771312354456432033076 0ustar adamstaff00000000000000"""Extract reference documentation from the NumPy source tree. """ from __future__ import division, absolute_import, print_function import inspect import textwrap import re import pydoc from warnings import warn import collections import sys class Reader(object): """A line-based string reader. """ def __init__(self, data): """ Parameters ---------- data : str String with lines separated by '\n'. """ if isinstance(data,list): self._str = data else: self._str = data.split('\n') # store string as list of lines self.reset() def __getitem__(self, n): return self._str[n] def reset(self): self._l = 0 # current line nr def read(self): if not self.eof(): out = self[self._l] self._l += 1 return out else: return '' def seek_next_non_empty_line(self): for l in self[self._l:]: if l.strip(): break else: self._l += 1 def eof(self): return self._l >= len(self._str) def read_to_condition(self, condition_func): start = self._l for line in self[start:]: if condition_func(line): return self[start:self._l] self._l += 1 if self.eof(): return self[start:self._l+1] return [] def read_to_next_empty_line(self): self.seek_next_non_empty_line() def is_empty(line): return not line.strip() return self.read_to_condition(is_empty) def read_to_next_unindented_line(self): def is_unindented(line): return (line.strip() and (len(line.lstrip()) == len(line))) return self.read_to_condition(is_unindented) def peek(self,n=0): if self._l + n < len(self._str): return self[self._l + n] else: return '' def is_empty(self): return not ''.join(self._str).strip() class NumpyDocString(object): def __init__(self, docstring, config={}): docstring = textwrap.dedent(docstring).split('\n') self._doc = Reader(docstring) self._parsed_data = { 'Signature': '', 'Summary': [''], 'Extended Summary': [], 'Parameters': [], 'Returns': [], 'Raises': [], 'Warns': [], 'Other Parameters': [], 'Attributes': [], 'Methods': [], 'See Also': [], 'Notes': [], 'Warnings': [], 'References': '', 'Examples': '', 'index': {} } self._parse() def __getitem__(self,key): return self._parsed_data[key] def __setitem__(self,key,val): if key not in self._parsed_data: warn("Unknown section %s" % key) else: self._parsed_data[key] = val def _is_at_section(self): self._doc.seek_next_non_empty_line() if self._doc.eof(): return False l1 = self._doc.peek().strip() # e.g. Parameters if l1.startswith('.. index::'): return True l2 = self._doc.peek(1).strip() # ---------- or ========== return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1)) def _strip(self,doc): i = 0 j = 0 for i,line in enumerate(doc): if line.strip(): break for j,line in enumerate(doc[::-1]): if line.strip(): break return doc[i:len(doc)-j] def _read_to_next_section(self): section = self._doc.read_to_next_empty_line() while not self._is_at_section() and not self._doc.eof(): if not self._doc.peek(-1).strip(): # previous line was empty section += [''] section += self._doc.read_to_next_empty_line() return section def _read_sections(self): while not self._doc.eof(): data = self._read_to_next_section() name = data[0].strip() if name.startswith('..'): # index section yield name, data[1:] elif len(data) < 2: yield StopIteration else: yield name, self._strip(data[2:]) def _parse_param_list(self,content): r = Reader(content) params = [] while not r.eof(): header = r.read().strip() if ' : ' in header: arg_name, arg_type = header.split(' : ')[:2] else: arg_name, arg_type = header, '' desc = r.read_to_next_unindented_line() desc = dedent_lines(desc) params.append((arg_name,arg_type,desc)) return params _name_rgx = re.compile(r"^\s*(:(?P\w+):`(?P[a-zA-Z0-9_.-]+)`|" r" (?P[a-zA-Z0-9_.-]+))\s*", re.X) def _parse_see_also(self, content): """ func_name : Descriptive text continued text another_func_name : Descriptive text func_name1, func_name2, :meth:`func_name`, func_name3 """ items = [] def parse_item_name(text): """Match ':role:`name`' or 'name'""" m = self._name_rgx.match(text) if m: g = m.groups() if g[1] is None: return g[3], None else: return g[2], g[1] raise ValueError("%s is not a item name" % text) def push_item(name, rest): if not name: return name, role = parse_item_name(name) items.append((name, list(rest), role)) del rest[:] current_func = None rest = [] for line in content: if not line.strip(): continue m = self._name_rgx.match(line) if m and line[m.end():].strip().startswith(':'): push_item(current_func, rest) current_func, line = line[:m.end()], line[m.end():] rest = [line.split(':', 1)[1].strip()] if not rest[0]: rest = [] elif not line.startswith(' '): push_item(current_func, rest) current_func = None if ',' in line: for func in line.split(','): if func.strip(): push_item(func, []) elif line.strip(): current_func = line elif current_func is not None: rest.append(line.strip()) push_item(current_func, rest) return items def _parse_index(self, section, content): """ .. index: default :refguide: something, else, and more """ def strip_each_in(lst): return [s.strip() for s in lst] out = {} section = section.split('::') if len(section) > 1: out['default'] = strip_each_in(section[1].split(','))[0] for line in content: line = line.split(':') if len(line) > 2: out[line[1]] = strip_each_in(line[2].split(',')) return out def _parse_summary(self): """Grab signature (if given) and summary""" if self._is_at_section(): return # If several signatures present, take the last one while True: summary = self._doc.read_to_next_empty_line() summary_str = " ".join([s.strip() for s in summary]).strip() if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str): self['Signature'] = summary_str if not self._is_at_section(): continue break if summary is not None: self['Summary'] = summary if not self._is_at_section(): self['Extended Summary'] = self._read_to_next_section() def _parse(self): self._doc.reset() self._parse_summary() for (section,content) in self._read_sections(): if not section.startswith('..'): section = ' '.join([s.capitalize() for s in section.split(' ')]) if section in ('Parameters', 'Returns', 'Raises', 'Warns', 'Other Parameters', 'Attributes', 'Methods'): self[section] = self._parse_param_list(content) elif section.startswith('.. index::'): self['index'] = self._parse_index(section, content) elif section == 'See Also': self['See Also'] = self._parse_see_also(content) else: self[section] = content # string conversion routines def _str_header(self, name, symbol='-'): return [name, len(name)*symbol] def _str_indent(self, doc, indent=4): out = [] for line in doc: out += [' '*indent + line] return out def _str_signature(self): if self['Signature']: return [self['Signature'].replace('*','\*')] + [''] else: return [''] def _str_summary(self): if self['Summary']: return self['Summary'] + [''] else: return [] def _str_extended_summary(self): if self['Extended Summary']: return self['Extended Summary'] + [''] else: return [] def _str_param_list(self, name): out = [] if self[name]: out += self._str_header(name) for param,param_type,desc in self[name]: if param_type: out += ['%s : %s' % (param, param_type)] else: out += [param] out += self._str_indent(desc) out += [''] return out def _str_section(self, name): out = [] if self[name]: out += self._str_header(name) out += self[name] out += [''] return out def _str_see_also(self, func_role): if not self['See Also']: return [] out = [] out += self._str_header("See Also") last_had_desc = True for func, desc, role in self['See Also']: if role: link = ':%s:`%s`' % (role, func) elif func_role: link = ':%s:`%s`' % (func_role, func) else: link = "`%s`_" % func if desc or last_had_desc: out += [''] out += [link] else: out[-1] += ", %s" % link if desc: out += self._str_indent([' '.join(desc)]) last_had_desc = True else: last_had_desc = False out += [''] return out def _str_index(self): idx = self['index'] out = [] out += ['.. index:: %s' % idx.get('default','')] for section, references in idx.items(): if section == 'default': continue out += [' :%s: %s' % (section, ', '.join(references))] return out def __str__(self, func_role=''): out = [] out += self._str_signature() out += self._str_summary() out += self._str_extended_summary() for param_list in ('Parameters', 'Returns', 'Other Parameters', 'Raises', 'Warns'): out += self._str_param_list(param_list) out += self._str_section('Warnings') out += self._str_see_also(func_role) for s in ('Notes','References','Examples'): out += self._str_section(s) for param_list in ('Attributes', 'Methods'): out += self._str_param_list(param_list) out += self._str_index() return '\n'.join(out) def indent(str,indent=4): indent_str = ' '*indent if str is None: return indent_str lines = str.split('\n') return '\n'.join(indent_str + l for l in lines) def dedent_lines(lines): """Deindent a list of lines maximally""" return textwrap.dedent("\n".join(lines)).split("\n") def header(text, style='-'): return text + '\n' + style*len(text) + '\n' class FunctionDoc(NumpyDocString): def __init__(self, func, role='func', doc=None, config={}): self._f = func self._role = role # e.g. "func" or "meth" if doc is None: if func is None: raise ValueError("No function or docstring given") doc = inspect.getdoc(func) or '' NumpyDocString.__init__(self, doc) if not self['Signature'] and func is not None: func, func_name = self.get_func() try: # try to read signature if sys.version_info[0] >= 3: argspec = inspect.getfullargspec(func) else: argspec = inspect.getargspec(func) argspec = inspect.formatargspec(*argspec) argspec = argspec.replace('*','\*') signature = '%s%s' % (func_name, argspec) except TypeError as e: signature = '%s()' % func_name self['Signature'] = signature def get_func(self): func_name = getattr(self._f, '__name__', self.__class__.__name__) if inspect.isclass(self._f): func = getattr(self._f, '__call__', self._f.__init__) else: func = self._f return func, func_name def __str__(self): out = '' func, func_name = self.get_func() signature = self['Signature'].replace('*', '\*') roles = {'func': 'function', 'meth': 'method'} if self._role: if self._role not in roles: print("Warning: invalid role %s" % self._role) out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''), func_name) out += super(FunctionDoc, self).__str__(func_role=self._role) return out class ClassDoc(NumpyDocString): extra_public_methods = ['__call__'] def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc, config={}): if not inspect.isclass(cls) and cls is not None: raise ValueError("Expected a class or None, but got %r" % cls) self._cls = cls if modulename and not modulename.endswith('.'): modulename += '.' self._mod = modulename if doc is None: if cls is None: raise ValueError("No class or documentation string given") doc = pydoc.getdoc(cls) NumpyDocString.__init__(self, doc) if config.get('show_class_members', True): def splitlines_x(s): if not s: return [] else: return s.splitlines() for field, items in [('Methods', self.methods), ('Attributes', self.properties)]: if not self[field]: doc_list = [] for name in sorted(items): try: doc_item = pydoc.getdoc(getattr(self._cls, name)) doc_list.append((name, '', splitlines_x(doc_item))) except AttributeError: pass # method doesn't exist self[field] = doc_list @property def methods(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) if ((not name.startswith('_') or name in self.extra_public_methods) and isinstance(func, collections.Callable))] @property def properties(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) if not name.startswith('_') and (func is None or isinstance(func, property) or inspect.isgetsetdescriptor(func))] ././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/docscrape_sphinx.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/docscra0000644000077000000240000002233512354456432033070 0ustar adamstaff00000000000000from __future__ import division, absolute_import, print_function import sys, re, inspect, textwrap, pydoc import sphinx import collections from .docscrape import NumpyDocString, FunctionDoc, ClassDoc if sys.version_info[0] >= 3: sixu = lambda s: s else: sixu = lambda s: unicode(s, 'unicode_escape') class SphinxDocString(NumpyDocString): def __init__(self, docstring, config={}): NumpyDocString.__init__(self, docstring, config=config) self.load_config(config) def load_config(self, config): self.use_plots = config.get('use_plots', False) self.class_members_toctree = config.get('class_members_toctree', True) # string conversion routines def _str_header(self, name, symbol='`'): return ['.. rubric:: ' + name, ''] def _str_field_list(self, name): return [':' + name + ':'] def _str_indent(self, doc, indent=4): out = [] for line in doc: out += [' '*indent + line] return out def _str_signature(self): return [''] if self['Signature']: return ['``%s``' % self['Signature']] + [''] else: return [''] def _str_summary(self): return self['Summary'] + [''] def _str_extended_summary(self): return self['Extended Summary'] + [''] def _str_returns(self): out = [] if self['Returns']: out += self._str_field_list('Returns') out += [''] for param, param_type, desc in self['Returns']: if param_type: out += self._str_indent(['**%s** : %s' % (param.strip(), param_type)]) else: out += self._str_indent([param.strip()]) if desc: out += [''] out += self._str_indent(desc, 8) out += [''] return out def _str_param_list(self, name): out = [] if self[name]: out += self._str_field_list(name) out += [''] for param, param_type, desc in self[name]: if param_type: out += self._str_indent(['**%s** : %s' % (param.strip(), param_type)]) else: out += self._str_indent(['**%s**' % param.strip()]) if desc: out += [''] out += self._str_indent(desc, 8) out += [''] return out @property def _obj(self): if hasattr(self, '_cls'): return self._cls elif hasattr(self, '_f'): return self._f return None def _str_member_list(self, name): """ Generate a member listing, autosummary:: table where possible, and a table where not. """ out = [] if self[name]: out += ['.. rubric:: %s' % name, ''] prefix = getattr(self, '_name', '') if prefix: prefix = '~%s.' % prefix autosum = [] others = [] for param, param_type, desc in self[name]: param = param.strip() # Check if the referenced member can have a docstring or not param_obj = getattr(self._obj, param, None) if not (callable(param_obj) or isinstance(param_obj, property) or inspect.isgetsetdescriptor(param_obj)): param_obj = None if param_obj and (pydoc.getdoc(param_obj) or not desc): # Referenced object has a docstring autosum += [" %s%s" % (prefix, param)] else: others.append((param, param_type, desc)) if autosum: out += ['.. autosummary::'] if self.class_members_toctree: out += [' :toctree:'] out += [''] + autosum if others: maxlen_0 = max(3, max([len(x[0]) for x in others])) hdr = sixu("=")*maxlen_0 + sixu(" ") + sixu("=")*10 fmt = sixu('%%%ds %%s ') % (maxlen_0,) out += ['', hdr] for param, param_type, desc in others: desc = sixu(" ").join(x.strip() for x in desc).strip() if param_type: desc = "(%s) %s" % (param_type, desc) out += [fmt % (param.strip(), desc)] out += [hdr] out += [''] return out def _str_section(self, name): out = [] if self[name]: out += self._str_header(name) out += [''] content = textwrap.dedent("\n".join(self[name])).split("\n") out += content out += [''] return out def _str_see_also(self, func_role): out = [] if self['See Also']: see_also = super(SphinxDocString, self)._str_see_also(func_role) out = ['.. seealso::', ''] out += self._str_indent(see_also[2:]) return out def _str_warnings(self): out = [] if self['Warnings']: out = ['.. warning::', ''] out += self._str_indent(self['Warnings']) return out def _str_index(self): idx = self['index'] out = [] if len(idx) == 0: return out out += ['.. index:: %s' % idx.get('default','')] for section, references in idx.items(): if section == 'default': continue elif section == 'refguide': out += [' single: %s' % (', '.join(references))] else: out += [' %s: %s' % (section, ','.join(references))] return out def _str_references(self): out = [] if self['References']: out += self._str_header('References') if isinstance(self['References'], str): self['References'] = [self['References']] out.extend(self['References']) out += [''] # Latex collects all references to a separate bibliography, # so we need to insert links to it if sphinx.__version__ >= "0.6": out += ['.. only:: latex',''] else: out += ['.. latexonly::',''] items = [] for line in self['References']: m = re.match(r'.. \[([a-z0-9._-]+)\]', line, re.I) if m: items.append(m.group(1)) out += [' ' + ", ".join(["[%s]_" % item for item in items]), ''] return out def _str_examples(self): examples_str = "\n".join(self['Examples']) if (self.use_plots and 'import matplotlib' in examples_str and 'plot::' not in examples_str): out = [] out += self._str_header('Examples') out += ['.. plot::', ''] out += self._str_indent(self['Examples']) out += [''] return out else: return self._str_section('Examples') def __str__(self, indent=0, func_role="obj"): out = [] out += self._str_signature() out += self._str_index() + [''] out += self._str_summary() out += self._str_extended_summary() out += self._str_param_list('Parameters') out += self._str_returns() for param_list in ('Other Parameters', 'Raises', 'Warns'): out += self._str_param_list(param_list) out += self._str_warnings() out += self._str_see_also(func_role) out += self._str_section('Notes') out += self._str_references() out += self._str_examples() for param_list in ('Attributes', 'Methods'): out += self._str_member_list(param_list) out = self._str_indent(out,indent) return '\n'.join(out) class SphinxFunctionDoc(SphinxDocString, FunctionDoc): def __init__(self, obj, doc=None, config={}): self.load_config(config) FunctionDoc.__init__(self, obj, doc=doc, config=config) class SphinxClassDoc(SphinxDocString, ClassDoc): def __init__(self, obj, doc=None, func_doc=None, config={}): self.load_config(config) ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config) class SphinxObjDoc(SphinxDocString): def __init__(self, obj, doc=None, config={}): self._f = obj self.load_config(config) SphinxDocString.__init__(self, doc, config=config) def get_doc_object(obj, what=None, doc=None, config={}): if what is None: if inspect.isclass(obj): what = 'class' elif inspect.ismodule(obj): what = 'module' elif isinstance(obj, collections.Callable): what = 'function' else: what = 'object' if what == 'class': return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, config=config) elif what in ('function', 'method'): return SphinxFunctionDoc(obj, doc=doc, config=config) else: if doc is None: doc = pydoc.getdoc(obj) return SphinxObjDoc(obj, doc, config=config) ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/doctest.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/doctest0000644000077000000240000000243612425434461033114 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This is a set of three directives that allow us to insert metadata about doctests into the .rst files so the testing framework knows which tests to skip. This is quite different from the doctest extension in Sphinx itself, which actually does something. For astropy, all of the testing is centrally managed from py.test and Sphinx is not used for running tests. """ import re from docutils.nodes import literal_block from sphinx.util.compat import Directive class DoctestSkipDirective(Directive): has_content = True def run(self): # Check if there is any valid argument, and skip it. Currently only # 'win32' is supported in astropy.tests.pytest_plugins. if re.match('win32', self.content[0]): self.content = self.content[2:] code = '\n'.join(self.content) return [literal_block(code, code)] class DoctestRequiresDirective(DoctestSkipDirective): # This is silly, but we really support an unbounded number of # optional arguments optional_arguments = 64 def setup(app): app.add_directive('doctest-requires', DoctestRequiresDirective) app.add_directive('doctest-skip', DoctestSkipDirective) app.add_directive('doctest-skip-all', DoctestSkipDirective) ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/edit_on_github.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/edit_on0000644000077000000240000001340712401041777033066 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ This extension makes it easy to edit documentation on github. It adds links associated with each docstring that go to the corresponding view source page on Github. From there, the user can push the "Edit" button, edit the docstring, and submit a pull request. It has the following configuration options (to be set in the project's ``conf.py``): * ``edit_on_github_project`` The name of the github project, in the form "username/projectname". * ``edit_on_github_branch`` The name of the branch to edit. If this is a released version, this should be a git tag referring to that version. For a dev version, it often makes sense for it to be "master". It may also be a git hash. * ``edit_on_github_source_root`` The location within the source tree of the root of the Python package. Defaults to "lib". * ``edit_on_github_doc_root`` The location within the source tree of the root of the documentation source. Defaults to "doc", but it may make sense to set it to "doc/source" if the project uses a separate source directory. * ``edit_on_github_docstring_message`` The phrase displayed in the links to edit a docstring. Defaults to "[edit on github]". * ``edit_on_github_page_message`` The phrase displayed in the links to edit a RST page. Defaults to "[edit this page on github]". * ``edit_on_github_help_message`` The phrase displayed as a tooltip on the edit links. Defaults to "Push the Edit button on the next page" * ``edit_on_github_skip_regex`` When the path to the .rst file matches this regular expression, no "edit this page on github" link will be added. Defaults to ``"_.*"``. """ import inspect import os import re import sys from docutils import nodes from sphinx import addnodes def import_object(modname, name): """ Import the object given by *modname* and *name* and return it. If not found, or the import fails, returns None. """ try: __import__(modname) mod = sys.modules[modname] obj = mod for part in name.split('.'): obj = getattr(obj, part) return obj except: return None def get_url_base(app): return 'http://github.com/%s/tree/%s/' % ( app.config.edit_on_github_project, app.config.edit_on_github_branch) def doctree_read(app, doctree): # Get the configuration parameters if app.config.edit_on_github_project == 'REQUIRED': raise ValueError( "The edit_on_github_project configuration variable must be " "provided in the conf.py") source_root = app.config.edit_on_github_source_root url = get_url_base(app) docstring_message = app.config.edit_on_github_docstring_message # Handle the docstring-editing links for objnode in doctree.traverse(addnodes.desc): if objnode.get('domain') != 'py': continue names = set() for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue modname = signode.get('module') if not modname: continue fullname = signode.get('fullname') if fullname in names: # only one link per name, please continue names.add(fullname) obj = import_object(modname, fullname) anchor = None if obj is not None: try: lines, lineno = inspect.getsourcelines(obj) except: pass else: anchor = '#L%d' % lineno if anchor: real_modname = inspect.getmodule(obj).__name__ path = '%s%s%s.py%s' % ( url, source_root, real_modname.replace('.', '/'), anchor) onlynode = addnodes.only(expr='html') onlynode += nodes.reference( reftitle=app.config.edit_on_github_help_message, refuri=path) onlynode[0] += nodes.inline( '', '', nodes.raw('', ' ', format='html'), nodes.Text(docstring_message), classes=['edit-on-github', 'viewcode-link']) signode += onlynode def html_page_context(app, pagename, templatename, context, doctree): if (templatename == 'page.html' and not re.match(app.config.edit_on_github_skip_regex, pagename)): doc_root = app.config.edit_on_github_doc_root if doc_root != '' and not doc_root.endswith('/'): doc_root += '/' doc_path = os.path.relpath(doctree.get('source'), app.builder.srcdir) url = get_url_base(app) page_message = app.config.edit_on_github_page_message context['edit_on_github'] = url + doc_root + doc_path context['edit_on_github_page_message'] = ( app.config.edit_on_github_page_message) def setup(app): app.add_config_value('edit_on_github_project', 'REQUIRED', True) app.add_config_value('edit_on_github_branch', 'master', True) app.add_config_value('edit_on_github_source_root', 'lib', True) app.add_config_value('edit_on_github_doc_root', 'doc', True) app.add_config_value('edit_on_github_docstring_message', '[edit on github]', True) app.add_config_value('edit_on_github_page_message', 'Edit This Page on Github', True) app.add_config_value('edit_on_github_help_message', 'Push the Edit button on the next page', True) app.add_config_value('edit_on_github_skip_regex', '_.*', True) app.connect('doctree-read', doctree_read) app.connect('html-page-context', html_page_context) ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/numpydoc.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/numpydo0000644000077000000240000001441412354456432033144 0ustar adamstaff00000000000000""" ======== numpydoc ======== Sphinx extension that handles docstrings in the Numpy standard format. [1] It will: - Convert Parameters etc. sections to field lists. - Convert See Also section to a See also entry. - Renumber references. - Extract the signature from the docstring, if it can't be determined otherwise. .. [1] https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt """ from __future__ import division, absolute_import, print_function import os, sys, re, pydoc import sphinx import inspect import collections if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") from .docscrape_sphinx import get_doc_object, SphinxDocString from sphinx.util.compat import Directive if sys.version_info[0] >= 3: sixu = lambda s: s else: sixu = lambda s: unicode(s, 'unicode_escape') def mangle_docstrings(app, what, name, obj, options, lines, reference_offset=[0]): cfg = dict(use_plots=app.config.numpydoc_use_plots, show_class_members=app.config.numpydoc_show_class_members, class_members_toctree=app.config.numpydoc_class_members_toctree, ) if what == 'module': # Strip top title title_re = re.compile(sixu('^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*'), re.I|re.S) lines[:] = title_re.sub(sixu(''), sixu("\n").join(lines)).split(sixu("\n")) else: doc = get_doc_object(obj, what, sixu("\n").join(lines), config=cfg) if sys.version_info[0] >= 3: doc = str(doc) else: doc = unicode(doc) lines[:] = doc.split(sixu("\n")) if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \ obj.__name__: if hasattr(obj, '__module__'): v = dict(full_name=sixu("%s.%s") % (obj.__module__, obj.__name__)) else: v = dict(full_name=obj.__name__) lines += [sixu(''), sixu('.. htmlonly::'), sixu('')] lines += [sixu(' %s') % x for x in (app.config.numpydoc_edit_link % v).split("\n")] # replace reference numbers so that there are no duplicates references = [] for line in lines: line = line.strip() m = re.match(sixu('^.. \\[([a-z0-9_.-])\\]'), line, re.I) if m: references.append(m.group(1)) # start renaming from the longest string, to avoid overwriting parts references.sort(key=lambda x: -len(x)) if references: for i, line in enumerate(lines): for r in references: if re.match(sixu('^\\d+$'), r): new_r = sixu("R%d") % (reference_offset[0] + int(r)) else: new_r = sixu("%s%d") % (r, reference_offset[0]) lines[i] = lines[i].replace(sixu('[%s]_') % r, sixu('[%s]_') % new_r) lines[i] = lines[i].replace(sixu('.. [%s]') % r, sixu('.. [%s]') % new_r) reference_offset[0] += len(references) def mangle_signature(app, what, name, obj, options, sig, retann): # Do not try to inspect classes that don't define `__init__` if (inspect.isclass(obj) and (not hasattr(obj, '__init__') or 'initializes x; see ' in pydoc.getdoc(obj.__init__))): return '', '' if not (isinstance(obj, collections.Callable) or hasattr(obj, '__argspec_is_invalid_')): return if not hasattr(obj, '__doc__'): return doc = SphinxDocString(pydoc.getdoc(obj)) if doc['Signature']: sig = re.sub(sixu("^[^(]*"), sixu(""), doc['Signature']) return sig, sixu('') def setup(app, get_doc_object_=get_doc_object): if not hasattr(app, 'add_config_value'): return # probably called by nose, better bail out global get_doc_object get_doc_object = get_doc_object_ app.connect('autodoc-process-docstring', mangle_docstrings) app.connect('autodoc-process-signature', mangle_signature) app.add_config_value('numpydoc_edit_link', None, False) app.add_config_value('numpydoc_use_plots', None, False) app.add_config_value('numpydoc_show_class_members', True, True) app.add_config_value('numpydoc_class_members_toctree', True, True) # Extra mangling domains app.add_domain(NumpyPythonDomain) app.add_domain(NumpyCDomain) #------------------------------------------------------------------------------ # Docstring-mangling domains #------------------------------------------------------------------------------ from docutils.statemachine import ViewList from sphinx.domains.c import CDomain from sphinx.domains.python import PythonDomain class ManglingDomainBase(object): directive_mangling_map = {} def __init__(self, *a, **kw): super(ManglingDomainBase, self).__init__(*a, **kw) self.wrap_mangling_directives() def wrap_mangling_directives(self): for name, objtype in list(self.directive_mangling_map.items()): self.directives[name] = wrap_mangling_directive( self.directives[name], objtype) class NumpyPythonDomain(ManglingDomainBase, PythonDomain): name = 'np' directive_mangling_map = { 'function': 'function', 'class': 'class', 'exception': 'class', 'method': 'function', 'classmethod': 'function', 'staticmethod': 'function', 'attribute': 'attribute', } indices = [] class NumpyCDomain(ManglingDomainBase, CDomain): name = 'np-c' directive_mangling_map = { 'function': 'function', 'member': 'attribute', 'macro': 'function', 'type': 'class', 'var': 'object', } def wrap_mangling_directive(base_directive, objtype): class directive(base_directive): def run(self): env = self.state.document.settings.env name = None if self.arguments: m = re.match(r'^(.*\s+)?(.*?)(\(.*)?', self.arguments[0]) name = m.group(2).strip() if not name: name = self.arguments[0] lines = list(self.content) mangle_docstrings(env.app, objtype, name, None, None, lines) self.content = ViewList(lines, self.content.parent) return base_directive.run(self) return directive ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/phantom_import.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/phantom0000644000077000000240000001333612354456432033121 0ustar adamstaff00000000000000""" ============== phantom_import ============== Sphinx extension to make directives from ``sphinx.ext.autodoc`` and similar extensions to use docstrings loaded from an XML file. This extension loads an XML file in the Pydocweb format [1] and creates a dummy module that contains the specified docstrings. This can be used to get the current docstrings from a Pydocweb instance without needing to rebuild the documented module. .. [1] http://code.google.com/p/pydocweb """ from __future__ import division, absolute_import, print_function import imp, sys, compiler, types, os, inspect, re def setup(app): app.connect('builder-inited', initialize) app.add_config_value('phantom_import_file', None, True) def initialize(app): fn = app.config.phantom_import_file if (fn and os.path.isfile(fn)): print("[numpydoc] Phantom importing modules from", fn, "...") import_phantom_module(fn) #------------------------------------------------------------------------------ # Creating 'phantom' modules from an XML description #------------------------------------------------------------------------------ def import_phantom_module(xml_file): """ Insert a fake Python module to sys.modules, based on a XML file. The XML file is expected to conform to Pydocweb DTD. The fake module will contain dummy objects, which guarantee the following: - Docstrings are correct. - Class inheritance relationships are correct (if present in XML). - Function argspec is *NOT* correct (even if present in XML). Instead, the function signature is prepended to the function docstring. - Class attributes are *NOT* correct; instead, they are dummy objects. Parameters ---------- xml_file : str Name of an XML file to read """ import lxml.etree as etree object_cache = {} tree = etree.parse(xml_file) root = tree.getroot() # Sort items so that # - Base classes come before classes inherited from them # - Modules come before their contents all_nodes = dict([(n.attrib['id'], n) for n in root]) def _get_bases(node, recurse=False): bases = [x.attrib['ref'] for x in node.findall('base')] if recurse: j = 0 while True: try: b = bases[j] except IndexError: break if b in all_nodes: bases.extend(_get_bases(all_nodes[b])) j += 1 return bases type_index = ['module', 'class', 'callable', 'object'] def base_cmp(a, b): x = cmp(type_index.index(a.tag), type_index.index(b.tag)) if x != 0: return x if a.tag == 'class' and b.tag == 'class': a_bases = _get_bases(a, recurse=True) b_bases = _get_bases(b, recurse=True) x = cmp(len(a_bases), len(b_bases)) if x != 0: return x if a.attrib['id'] in b_bases: return -1 if b.attrib['id'] in a_bases: return 1 return cmp(a.attrib['id'].count('.'), b.attrib['id'].count('.')) nodes = root.getchildren() nodes.sort(base_cmp) # Create phantom items for node in nodes: name = node.attrib['id'] doc = (node.text or '').decode('string-escape') + "\n" if doc == "\n": doc = "" # create parent, if missing parent = name while True: parent = '.'.join(parent.split('.')[:-1]) if not parent: break if parent in object_cache: break obj = imp.new_module(parent) object_cache[parent] = obj sys.modules[parent] = obj # create object if node.tag == 'module': obj = imp.new_module(name) obj.__doc__ = doc sys.modules[name] = obj elif node.tag == 'class': bases = [object_cache[b] for b in _get_bases(node) if b in object_cache] bases.append(object) init = lambda self: None init.__doc__ = doc obj = type(name, tuple(bases), {'__doc__': doc, '__init__': init}) obj.__name__ = name.split('.')[-1] elif node.tag == 'callable': funcname = node.attrib['id'].split('.')[-1] argspec = node.attrib.get('argspec') if argspec: argspec = re.sub('^[^(]*', '', argspec) doc = "%s%s\n\n%s" % (funcname, argspec, doc) obj = lambda: 0 obj.__argspec_is_invalid_ = True if sys.version_info[0] >= 3: obj.__name__ = funcname else: obj.func_name = funcname obj.__name__ = name obj.__doc__ = doc if inspect.isclass(object_cache[parent]): obj.__objclass__ = object_cache[parent] else: class Dummy(object): pass obj = Dummy() obj.__name__ = name obj.__doc__ = doc if inspect.isclass(object_cache[parent]): obj.__get__ = lambda: None object_cache[name] = obj if parent: if inspect.ismodule(object_cache[parent]): obj.__module__ = parent setattr(object_cache[parent], name.split('.')[-1], obj) # Populate items for node in root: obj = object_cache.get(node.attrib['id']) if obj is None: continue for ref in node.findall('ref'): if node.tag == 'class': if ref.attrib['ref'].startswith(node.attrib['id'] + '.'): setattr(obj, ref.attrib['name'], object_cache.get(ref.attrib['ref'])) else: setattr(obj, ref.attrib['name'], object_cache.get(ref.attrib['ref'])) ././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/smart_resolver.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/smart_r0000644000077000000240000000717612425434461033124 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ The classes in the astropy docs are documented by their API location, which is not necessarily where they are defined in the source. This causes a problem when certain automated features of the doc build, such as the inheritance diagrams or the `Bases` list of a class reference a class by its canonical location rather than its "user" location. In the `autodoc-process-docstring` event, a mapping from the actual name to the API name is maintained. Later, in the `missing-reference` event, unresolved references are looked up in this dictionary and corrected if possible. """ from docutils.nodes import literal, reference def process_docstring(app, what, name, obj, options, lines): if isinstance(obj, type): env = app.env if not hasattr(env, 'class_name_mapping'): env.class_name_mapping = {} mapping = env.class_name_mapping mapping[obj.__module__ + '.' + obj.__name__] = name def missing_reference_handler(app, env, node, contnode): if not hasattr(env, 'class_name_mapping'): env.class_name_mapping = {} mapping = env.class_name_mapping reftype = node['reftype'] reftarget = node['reftarget'] if reftype in ('obj', 'class', 'exc', 'meth'): reftarget = node['reftarget'] suffix = '' if reftarget not in mapping: if '.' in reftarget: front, suffix = reftarget.rsplit('.', 1) else: suffix = reftarget if suffix.startswith('_') and not suffix.startswith('__'): # If this is a reference to a hidden class or method, # we can't link to it, but we don't want to have a # nitpick warning. return node[0].deepcopy() if reftype in ('obj', 'meth') and '.' in reftarget: if front in mapping: reftarget = front suffix = '.' + suffix if (reftype in ('class', ) and '.' in reftarget and reftarget not in mapping): if '.' in front: reftarget, _ = front.rsplit('.', 1) suffix = '.' + suffix reftarget = reftarget + suffix prefix = reftarget.rsplit('.')[0] if (reftarget not in mapping and prefix in env.intersphinx_named_inventory): if reftarget in env.intersphinx_named_inventory[prefix]['py:class']: newtarget = env.intersphinx_named_inventory[prefix]['py:class'][reftarget][2] if not node['refexplicit'] and \ '~' not in node.rawsource: contnode = literal(text=reftarget) newnode = reference('', '', internal=True) newnode['reftitle'] = reftarget newnode['refuri'] = newtarget newnode.append(contnode) return newnode if reftarget in mapping: newtarget = mapping[reftarget] + suffix if not node['refexplicit'] and not '~' in node.rawsource: contnode = literal(text=newtarget) newnode = env.domains['py'].resolve_xref( env, node['refdoc'], app.builder, 'class', newtarget, node, contnode) if newnode is not None: newnode['reftitle'] = reftarget return newnode def setup(app): app.connect('autodoc-process-docstring', process_docstring) app.connect('missing-reference', missing_reference_handler) ././@LongLink0000000000000000000000000000015000000000000011211 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templates/astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templat0000755000077000000240000000000012505171566033111 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000017100000000000011214 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templates/autosummary_core/astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templat0000755000077000000240000000000012505171566033111 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000020100000000000011206 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templates/autosummary_core/base.rstastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templat0000644000077000000240000000025212354456432033112 0ustar adamstaff00000000000000{% if referencefile %} .. include:: {{ referencefile }} {% endif %} {{ objname }} {{ underline }} .. currentmodule:: {{ module }} .. auto{{ objtype }}:: {{ objname }} ././@LongLink0000000000000000000000000000020200000000000011207 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templates/autosummary_core/class.rstastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templat0000644000077000000240000000221112354456432033107 0ustar adamstaff00000000000000{% if referencefile %} .. include:: {{ referencefile }} {% endif %} {{ objname }} {{ underline }} .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} :show-inheritance: {% if '__init__' in methods %} {% set caught_result = methods.remove('__init__') %} {% endif %} {% block attributes_summary %} {% if attributes %} .. rubric:: Attributes Summary .. autosummary:: {% for item in attributes %} ~{{ name }}.{{ item }} {%- endfor %} {% endif %} {% endblock %} {% block methods_summary %} {% if methods %} .. rubric:: Methods Summary .. autosummary:: {% for item in methods %} ~{{ name }}.{{ item }} {%- endfor %} {% endif %} {% endblock %} {% block attributes_documentation %} {% if attributes %} .. rubric:: Attributes Documentation {% for item in attributes %} .. autoattribute:: {{ item }} {%- endfor %} {% endif %} {% endblock %} {% block methods_documentation %} {% if methods %} .. rubric:: Methods Documentation {% for item in methods %} .. automethod:: {{ item }} {%- endfor %} {% endif %} {% endblock %} ././@LongLink0000000000000000000000000000020300000000000011210 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templates/autosummary_core/module.rstastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/templat0000644000077000000240000000127712354456432033122 0ustar adamstaff00000000000000{% if referencefile %} .. include:: {{ referencefile }} {% endif %} {{ objname }} {{ underline }} .. automodule:: {{ fullname }} {% block functions %} {% if functions %} .. rubric:: Functions .. autosummary:: {% for item in functions %} {{ item }} {%- endfor %} {% endif %} {% endblock %} {% block classes %} {% if classes %} .. rubric:: Classes .. autosummary:: {% for item in classes %} {{ item }} {%- endfor %} {% endif %} {% endblock %} {% block exceptions %} {% if exceptions %} .. rubric:: Exceptions .. autosummary:: {% for item in exceptions %} {{ item }} {%- endfor %} {% endif %} {% endblock %} astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/0000755000077000000240000000000012505171566032664 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000015700000000000011220 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/__init__.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/_0000644000077000000240000000334112401041777033021 0ustar adamstaff00000000000000import os import subprocess as sp import sys from textwrap import dedent import pytest @pytest.fixture def cython_testpackage(tmpdir, request): """ Creates a trivial Cython package for use with tests. """ test_pkg = tmpdir.mkdir('test_pkg') test_pkg.mkdir('_eva_').ensure('__init__.py') test_pkg.join('_eva_').join('unit02.pyx').write(dedent("""\ def pilot(): \"\"\"Returns the pilot of Eva Unit-02.\"\"\" return True """)) import astropy_helpers test_pkg.join('setup.py').write(dedent("""\ import sys sys.path.insert(0, {0!r}) from os.path import join from setuptools import setup, Extension from astropy_helpers.setup_helpers import register_commands NAME = '_eva_' VERSION = 0.1 RELEASE = True cmdclassd = register_commands(NAME, VERSION, RELEASE) setup( name=NAME, version=VERSION, cmdclass=cmdclassd, ext_modules=[Extension('_eva_.unit02', [join('_eva_', 'unit02.pyx')])] ) """.format(os.path.dirname(astropy_helpers.__path__[0])))) test_pkg.chdir() # Build the Cython module in a subprocess; otherwise strange things can # happen with Cython's global module state sp.call([sys.executable, 'setup.py', 'build_ext', '--inplace']) sys.path.insert(0, str(test_pkg)) import _eva_.unit02 def cleanup(test_pkg=test_pkg): for modname in ['_eva_', '_eva_.unit02']: try: del sys.modules[modname] except KeyError: pass sys.path.remove(str(test_pkg)) request.addfinalizer(cleanup) return test_pkg ././@LongLink0000000000000000000000000000016600000000000011220 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/test_automodapi.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/t0000644000077000000240000001633412453761452033062 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import os import sys import pytest from . import * from ....utils import iteritems pytest.importorskip('sphinx') # skips these tests if sphinx not present class FakeConfig(object): """ Mocks up a sphinx configuration setting construct for automodapi tests """ def __init__(self, **kwargs): for k, v in iteritems(kwargs): setattr(self, k, v) class FakeApp(object): """ Mocks up a `sphinx.application.Application` object for automodapi tests """ # Some default config values _defaults = { 'automodapi_toctreedirnm': 'api', 'automodapi_writereprocessed': False } def __init__(self, **configs): config = self._defaults.copy() config.update(configs) self.config = FakeConfig(**config) self.info = [] self.warnings = [] def info(self, msg, loc): self.info.append((msg, loc)) def warn(self, msg, loc): self.warnings.append((msg, loc)) am_replacer_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.tests.test_automodapi {options} This comes after """ am_replacer_basic_expected = """ This comes before astropy_helpers.sphinx.ext.tests.test_automodapi Module ------------------------------------------------------- .. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :functions-only: :toctree: api/ Classes ^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :classes-only: :toctree: api/ Class Inheritance Diagram ^^^^^^^^^^^^^^^^^^^^^^^^^ .. automod-diagram:: astropy_helpers.sphinx.ext.tests.test_automodapi :private-bases: :parts: 1 {empty} This comes after """.format(empty='').replace('/', os.sep) # the .format is necessary for editors that remove empty-line whitespace def test_am_replacer_basic(): """ Tests replacing an ".. automodapi::" with the automodapi no-option template """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_str.format(options=''), fakeapp) assert result == am_replacer_basic_expected am_replacer_noinh_expected = """ This comes before astropy_helpers.sphinx.ext.tests.test_automodapi Module ------------------------------------------------------- .. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :functions-only: :toctree: api/ Classes ^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :classes-only: :toctree: api/ This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_noinh(): """ Tests replacing an ".. automodapi::" with no-inheritance-diagram option """ from ..automodapi import automodapi_replace fakeapp = FakeApp() ops = ['', ':no-inheritance-diagram:'] ostr = '\n '.join(ops) result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp) assert result == am_replacer_noinh_expected am_replacer_titleandhdrs_expected = """ This comes before astropy_helpers.sphinx.ext.tests.test_automodapi Module &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& .. automodule:: astropy_helpers.sphinx.ext.tests.test_automodapi Functions ********* .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :functions-only: :toctree: api/ Classes ******* .. automodsumm:: astropy_helpers.sphinx.ext.tests.test_automodapi :classes-only: :toctree: api/ Class Inheritance Diagram ************************* .. automod-diagram:: astropy_helpers.sphinx.ext.tests.test_automodapi :private-bases: :parts: 1 {empty} This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_titleandhdrs(): """ Tests replacing an ".. automodapi::" entry with title-setting and header character options. """ from ..automodapi import automodapi_replace fakeapp = FakeApp() ops = ['', ':title: A new title', ':headings: &*'] ostr = '\n '.join(ops) result = automodapi_replace(am_replacer_str.format(options=ostr), fakeapp) assert result == am_replacer_titleandhdrs_expected am_replacer_nomain_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.automodapi :no-main-docstr: This comes after """ am_replacer_nomain_expected = """ This comes before astropy_helpers.sphinx.ext.automodapi Module -------------------------------------------- Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.automodapi :functions-only: :toctree: api/ This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_nomain(): """ Tests replacing an ".. automodapi::" with "no-main-docstring" . """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_nomain_str, fakeapp) assert result == am_replacer_nomain_expected am_replacer_skip_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.automodapi :skip: something1 :skip: something2 This comes after """ am_replacer_skip_expected = """ This comes before astropy_helpers.sphinx.ext.automodapi Module -------------------------------------------- .. automodule:: astropy_helpers.sphinx.ext.automodapi Functions ^^^^^^^^^ .. automodsumm:: astropy_helpers.sphinx.ext.automodapi :functions-only: :toctree: api/ :skip: something1,something2 This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_skip(): """ Tests using the ":skip: option in an ".. automodapi::" . """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_skip_str, fakeapp) assert result == am_replacer_skip_expected am_replacer_invalidop_str = """ This comes before .. automodapi:: astropy_helpers.sphinx.ext.automodapi :invalid-option: This comes after """ def test_am_replacer_invalidop(): """ Tests that a sphinx warning is produced with an invalid option. """ from ..automodapi import automodapi_replace fakeapp = FakeApp() automodapi_replace(am_replacer_invalidop_str, fakeapp) expected_warnings = [('Found additional options invalid-option in ' 'automodapi.', None)] assert fakeapp.warnings == expected_warnings am_replacer_cython_str = """ This comes before .. automodapi:: _eva_.unit02 {options} This comes after """ am_replacer_cython_expected = """ This comes before _eva_.unit02 Module ------------------- .. automodule:: _eva_.unit02 Functions ^^^^^^^^^ .. automodsumm:: _eva_.unit02 :functions-only: :toctree: api/ This comes after """.format(empty='').replace('/', os.sep) def test_am_replacer_cython(cython_testpackage): """ Tests replacing an ".. automodapi::" for a Cython module. """ from ..automodapi import automodapi_replace fakeapp = FakeApp() result = automodapi_replace(am_replacer_cython_str.format(options=''), fakeapp) assert result == am_replacer_cython_expected ././@LongLink0000000000000000000000000000016700000000000011221 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/test_automodsumm.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/t0000644000077000000240000000456212453761452033062 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import sys import pytest from . import * from ....utils import iteritems pytest.importorskip('sphinx') # skips these tests if sphinx not present class FakeEnv(object): """ Mocks up a sphinx env setting construct for automodapi tests """ def __init__(self, **kwargs): for k, v in iteritems(kwargs): setattr(self, k, v) class FakeBuilder(object): """ Mocks up a sphinx builder setting construct for automodapi tests """ def __init__(self, **kwargs): self.env = FakeEnv(**kwargs) class FakeApp(object): """ Mocks up a `sphinx.application.Application` object for automodapi tests """ def __init__(self, srcdir, automodapipresent=True): self.builder = FakeBuilder(srcdir=srcdir) self.info = [] self.warnings = [] self._extensions = [] if automodapipresent: self._extensions.append('astropy_helpers.sphinx.ext.automodapi') def info(self, msg, loc): self.info.append((msg, loc)) def warn(self, msg, loc): self.warnings.append((msg, loc)) ams_to_asmry_str = """ Before .. automodsumm:: astropy_helpers.sphinx.ext.automodsumm :p: And After """ ams_to_asmry_expected = """\ .. currentmodule:: astropy_helpers.sphinx.ext.automodsumm .. autosummary:: :p: Automoddiagram Automodsumm automodsumm_to_autosummary_lines generate_automodsumm_docs process_automodsumm_generation setup""" def test_ams_to_asmry(tmpdir): from ..automodsumm import automodsumm_to_autosummary_lines fi = tmpdir.join('automodsumm.rst') fi.write(ams_to_asmry_str) fakeapp = FakeApp(srcdir='') resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp) assert '\n'.join(resultlines) == ams_to_asmry_expected ams_cython_str = """ Before .. automodsumm:: _eva_.unit02 :functions-only: :p: And After """ ams_cython_expected = """\ .. currentmodule:: _eva_.unit02 .. autosummary:: :p: pilot""" def test_ams_cython(tmpdir, cython_testpackage): from ..automodsumm import automodsumm_to_autosummary_lines fi = tmpdir.join('automodsumm.rst') fi.write(ams_cython_str) fakeapp = FakeApp(srcdir='') resultlines = automodsumm_to_autosummary_lines(str(fi), fakeapp) assert '\n'.join(resultlines) == ams_cython_expected ././@LongLink0000000000000000000000000000016500000000000011217 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/test_docscrape.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/t0000644000077000000240000004327112354456432033061 0ustar adamstaff00000000000000# -*- encoding:utf-8 -*- from __future__ import division, absolute_import, print_function import sys, textwrap from ..docscrape import NumpyDocString, FunctionDoc, ClassDoc from ..docscrape_sphinx import SphinxDocString, SphinxClassDoc if sys.version_info[0] >= 3: sixu = lambda s: s else: sixu = lambda s: unicode(s, 'unicode_escape') doc_txt = '''\ numpy.multivariate_normal(mean, cov, shape=None, spam=None) Draw values from a multivariate normal distribution with specified mean and covariance. The multivariate normal or Gaussian distribution is a generalisation of the one-dimensional normal distribution to higher dimensions. Parameters ---------- mean : (N,) ndarray Mean of the N-dimensional distribution. .. math:: (1+2+3)/3 cov : (N, N) ndarray Covariance matrix of the distribution. shape : tuple of ints Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). Returns ------- out : ndarray The drawn samples, arranged according to `shape`. If the shape given is (m,n,...), then the shape of `out` is is (m,n,...,N). In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. list of str This is not a real return value. It exists to test anonymous return values. Other Parameters ---------------- spam : parrot A parrot off its mortal coil. Raises ------ RuntimeError Some error Warns ----- RuntimeWarning Some warning Warnings -------- Certain warnings apply. Notes ----- Instead of specifying the full covariance matrix, popular approximations include: - Spherical covariance (`cov` is a multiple of the identity matrix) - Diagonal covariance (`cov` has non-negative elements only on the diagonal) This geometrical property can be seen in two dimensions by plotting generated data-points: >>> mean = [0,0] >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis >>> x,y = multivariate_normal(mean,cov,5000).T >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show() Note that the covariance matrix must be symmetric and non-negative definite. References ---------- .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic Processes," 3rd ed., McGraw-Hill Companies, 1991 .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification," 2nd ed., Wiley, 2001. See Also -------- some, other, funcs otherfunc : relationship Examples -------- >>> mean = (1,2) >>> cov = [[1,0],[1,0]] >>> x = multivariate_normal(mean,cov,(3,3)) >>> print x.shape (3, 3, 2) The following is probably true, given that 0.6 is roughly twice the standard deviation: >>> print list( (x[0,0,:] - mean) < 0.6 ) [True, True] .. index:: random :refguide: random;distributions, random;gauss ''' doc = NumpyDocString(doc_txt) def test_signature(): assert doc['Signature'].startswith('numpy.multivariate_normal(') assert doc['Signature'].endswith('spam=None)') def test_summary(): assert doc['Summary'][0].startswith('Draw values') assert doc['Summary'][-1].endswith('covariance.') def test_extended_summary(): assert doc['Extended Summary'][0].startswith('The multivariate normal') def test_parameters(): assert len(doc['Parameters']) == 3 assert [n for n,_,_ in doc['Parameters']] == ['mean','cov','shape'] arg, arg_type, desc = doc['Parameters'][1] assert arg_type == '(N, N) ndarray' assert desc[0].startswith('Covariance matrix') assert doc['Parameters'][0][-1][-2] == ' (1+2+3)/3' def test_other_parameters(): assert len(doc['Other Parameters']) == 1 assert [n for n,_,_ in doc['Other Parameters']] == ['spam'] arg, arg_type, desc = doc['Other Parameters'][0] assert arg_type == 'parrot' assert desc[0].startswith('A parrot off its mortal coil') def test_returns(): assert len(doc['Returns']) == 2 arg, arg_type, desc = doc['Returns'][0] assert arg == 'out' assert arg_type == 'ndarray' assert desc[0].startswith('The drawn samples') assert desc[-1].endswith('distribution.') arg, arg_type, desc = doc['Returns'][1] assert arg == 'list of str' assert arg_type == '' assert desc[0].startswith('This is not a real') assert desc[-1].endswith('anonymous return values.') def test_notes(): assert doc['Notes'][0].startswith('Instead') assert doc['Notes'][-1].endswith('definite.') assert len(doc['Notes']) == 17 def test_references(): assert doc['References'][0].startswith('..') assert doc['References'][-1].endswith('2001.') def test_examples(): assert doc['Examples'][0].startswith('>>>') assert doc['Examples'][-1].endswith('True]') def test_index(): assert doc['index']['default'] == 'random' assert len(doc['index']) == 2 assert len(doc['index']['refguide']) == 2 def non_blank_line_by_line_compare(a,b): a = textwrap.dedent(a) b = textwrap.dedent(b) a = [l.rstrip() for l in a.split('\n') if l.strip()] b = [l.rstrip() for l in b.split('\n') if l.strip()] for n,line in enumerate(a): if not line == b[n]: raise AssertionError("Lines %s of a and b differ: " "\n>>> %s\n<<< %s\n" % (n,line,b[n])) def test_str(): non_blank_line_by_line_compare(str(doc), """numpy.multivariate_normal(mean, cov, shape=None, spam=None) Draw values from a multivariate normal distribution with specified mean and covariance. The multivariate normal or Gaussian distribution is a generalisation of the one-dimensional normal distribution to higher dimensions. Parameters ---------- mean : (N,) ndarray Mean of the N-dimensional distribution. .. math:: (1+2+3)/3 cov : (N, N) ndarray Covariance matrix of the distribution. shape : tuple of ints Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). Returns ------- out : ndarray The drawn samples, arranged according to `shape`. If the shape given is (m,n,...), then the shape of `out` is is (m,n,...,N). In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. list of str This is not a real return value. It exists to test anonymous return values. Other Parameters ---------------- spam : parrot A parrot off its mortal coil. Raises ------ RuntimeError Some error Warns ----- RuntimeWarning Some warning Warnings -------- Certain warnings apply. See Also -------- `some`_, `other`_, `funcs`_ `otherfunc`_ relationship Notes ----- Instead of specifying the full covariance matrix, popular approximations include: - Spherical covariance (`cov` is a multiple of the identity matrix) - Diagonal covariance (`cov` has non-negative elements only on the diagonal) This geometrical property can be seen in two dimensions by plotting generated data-points: >>> mean = [0,0] >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis >>> x,y = multivariate_normal(mean,cov,5000).T >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show() Note that the covariance matrix must be symmetric and non-negative definite. References ---------- .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic Processes," 3rd ed., McGraw-Hill Companies, 1991 .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification," 2nd ed., Wiley, 2001. Examples -------- >>> mean = (1,2) >>> cov = [[1,0],[1,0]] >>> x = multivariate_normal(mean,cov,(3,3)) >>> print x.shape (3, 3, 2) The following is probably true, given that 0.6 is roughly twice the standard deviation: >>> print list( (x[0,0,:] - mean) < 0.6 ) [True, True] .. index:: random :refguide: random;distributions, random;gauss""") def test_sphinx_str(): sphinx_doc = SphinxDocString(doc_txt) non_blank_line_by_line_compare(str(sphinx_doc), """ .. index:: random single: random;distributions, random;gauss Draw values from a multivariate normal distribution with specified mean and covariance. The multivariate normal or Gaussian distribution is a generalisation of the one-dimensional normal distribution to higher dimensions. :Parameters: **mean** : (N,) ndarray Mean of the N-dimensional distribution. .. math:: (1+2+3)/3 **cov** : (N, N) ndarray Covariance matrix of the distribution. **shape** : tuple of ints Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). :Returns: **out** : ndarray The drawn samples, arranged according to `shape`. If the shape given is (m,n,...), then the shape of `out` is is (m,n,...,N). In other words, each entry ``out[i,j,...,:]`` is an N-dimensional value drawn from the distribution. list of str This is not a real return value. It exists to test anonymous return values. :Other Parameters: **spam** : parrot A parrot off its mortal coil. :Raises: **RuntimeError** Some error :Warns: **RuntimeWarning** Some warning .. warning:: Certain warnings apply. .. seealso:: :obj:`some`, :obj:`other`, :obj:`funcs` :obj:`otherfunc` relationship .. rubric:: Notes Instead of specifying the full covariance matrix, popular approximations include: - Spherical covariance (`cov` is a multiple of the identity matrix) - Diagonal covariance (`cov` has non-negative elements only on the diagonal) This geometrical property can be seen in two dimensions by plotting generated data-points: >>> mean = [0,0] >>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis >>> x,y = multivariate_normal(mean,cov,5000).T >>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show() Note that the covariance matrix must be symmetric and non-negative definite. .. rubric:: References .. [1] A. Papoulis, "Probability, Random Variables, and Stochastic Processes," 3rd ed., McGraw-Hill Companies, 1991 .. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification," 2nd ed., Wiley, 2001. .. only:: latex [1]_, [2]_ .. rubric:: Examples >>> mean = (1,2) >>> cov = [[1,0],[1,0]] >>> x = multivariate_normal(mean,cov,(3,3)) >>> print x.shape (3, 3, 2) The following is probably true, given that 0.6 is roughly twice the standard deviation: >>> print list( (x[0,0,:] - mean) < 0.6 ) [True, True] """) doc2 = NumpyDocString(""" Returns array of indices of the maximum values of along the given axis. Parameters ---------- a : {array_like} Array to look in. axis : {None, integer} If None, the index is into the flattened array, otherwise along the specified axis""") def test_parameters_without_extended_description(): assert len(doc2['Parameters']) == 2 doc3 = NumpyDocString(""" my_signature(*params, **kwds) Return this and that. """) def test_escape_stars(): signature = str(doc3).split('\n')[0] signature == 'my_signature(\*params, \*\*kwds)' doc4 = NumpyDocString( """a.conj() Return an array with all complex-valued elements conjugated.""") def test_empty_extended_summary(): assert doc4['Extended Summary'] == [] doc5 = NumpyDocString( """ a.something() Raises ------ LinAlgException If array is singular. Warns ----- SomeWarning If needed """) def test_raises(): assert len(doc5['Raises']) == 1 name,_,desc = doc5['Raises'][0] assert name == 'LinAlgException' assert desc == ['If array is singular.'] def test_warns(): assert len(doc5['Warns']) == 1 name,_,desc = doc5['Warns'][0] assert name == 'SomeWarning' assert desc == ['If needed'] def test_see_also(): doc6 = NumpyDocString( """ z(x,theta) See Also -------- func_a, func_b, func_c func_d : some equivalent func foo.func_e : some other func over multiple lines func_f, func_g, :meth:`func_h`, func_j, func_k :obj:`baz.obj_q` :class:`class_j`: fubar foobar """) assert len(doc6['See Also']) == 12 for func, desc, role in doc6['See Also']: if func in ('func_a', 'func_b', 'func_c', 'func_f', 'func_g', 'func_h', 'func_j', 'func_k', 'baz.obj_q'): assert(not desc) else: assert(desc) if func == 'func_h': assert role == 'meth' elif func == 'baz.obj_q': assert role == 'obj' elif func == 'class_j': assert role == 'class' else: assert role is None if func == 'func_d': assert desc == ['some equivalent func'] elif func == 'foo.func_e': assert desc == ['some other func over', 'multiple lines'] elif func == 'class_j': assert desc == ['fubar', 'foobar'] def test_see_also_print(): class Dummy(object): """ See Also -------- func_a, func_b func_c : some relationship goes here func_d """ pass obj = Dummy() s = str(FunctionDoc(obj, role='func')) assert(':func:`func_a`, :func:`func_b`' in s) assert(' some relationship' in s) assert(':func:`func_d`' in s) doc7 = NumpyDocString(""" Doc starts on second line. """) def test_empty_first_line(): assert doc7['Summary'][0].startswith('Doc starts') def test_no_summary(): str(SphinxDocString(""" Parameters ----------""")) def test_unicode(): doc = SphinxDocString(""" öäöäöäöäöåååå öäöäöäööäååå Parameters ---------- ååå : äää ööö Returns ------- ååå : ööö äää """) assert isinstance(doc['Summary'][0], str) assert doc['Summary'][0] == 'öäöäöäöäöåååå' def test_plot_examples(): cfg = dict(use_plots=True) doc = SphinxDocString(""" Examples -------- >>> import matplotlib.pyplot as plt >>> plt.plot([1,2,3],[4,5,6]) >>> plt.show() """, config=cfg) assert 'plot::' in str(doc), str(doc) doc = SphinxDocString(""" Examples -------- .. plot:: import matplotlib.pyplot as plt plt.plot([1,2,3],[4,5,6]) plt.show() """, config=cfg) assert str(doc).count('plot::') == 1, str(doc) def test_class_members(): class Dummy(object): """ Dummy class. """ def spam(self, a, b): """Spam\n\nSpam spam.""" pass def ham(self, c, d): """Cheese\n\nNo cheese.""" pass @property def spammity(self): """Spammity index""" return 0.95 class Ignorable(object): """local class, to be ignored""" pass for cls in (ClassDoc, SphinxClassDoc): doc = cls(Dummy, config=dict(show_class_members=False)) assert 'Methods' not in str(doc), (cls, str(doc)) assert 'spam' not in str(doc), (cls, str(doc)) assert 'ham' not in str(doc), (cls, str(doc)) assert 'spammity' not in str(doc), (cls, str(doc)) assert 'Spammity index' not in str(doc), (cls, str(doc)) doc = cls(Dummy, config=dict(show_class_members=True)) assert 'Methods' in str(doc), (cls, str(doc)) assert 'spam' in str(doc), (cls, str(doc)) assert 'ham' in str(doc), (cls, str(doc)) assert 'spammity' in str(doc), (cls, str(doc)) if cls is SphinxClassDoc: assert '.. autosummary::' in str(doc), str(doc) else: assert 'Spammity index' in str(doc), str(doc) def test_duplicate_signature(): # Duplicate function signatures occur e.g. in ufuncs, when the # automatic mechanism adds one, and a more detailed comes from the # docstring itself. doc = NumpyDocString( """ z(x1, x2) z(a, theta) """) assert doc['Signature'].strip() == 'z(a, theta)' class_doc_txt = """ Foo Parameters ---------- f : callable ``f(t, y, *f_args)`` Aaa. jac : callable ``jac(t, y, *jac_args)`` Bbb. Attributes ---------- t : float Current time. y : ndarray Current variable values. Methods ------- a b c Examples -------- For usage examples, see `ode`. """ def test_class_members_doc(): doc = ClassDoc(None, class_doc_txt) non_blank_line_by_line_compare(str(doc), """ Foo Parameters ---------- f : callable ``f(t, y, *f_args)`` Aaa. jac : callable ``jac(t, y, *jac_args)`` Bbb. Examples -------- For usage examples, see `ode`. Attributes ---------- t : float Current time. y : ndarray Current variable values. Methods ------- a b c .. index:: """) def test_class_members_doc_sphinx(): doc = SphinxClassDoc(None, class_doc_txt) non_blank_line_by_line_compare(str(doc), """ Foo :Parameters: **f** : callable ``f(t, y, *f_args)`` Aaa. **jac** : callable ``jac(t, y, *jac_args)`` Bbb. .. rubric:: Examples For usage examples, see `ode`. .. rubric:: Attributes === ========== t (float) Current time. y (ndarray) Current variable values. === ========== .. rubric:: Methods === ========== a b c === ========== """) ././@LongLink0000000000000000000000000000016100000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/test_utils.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tests/t0000644000077000000240000000174312401041777033052 0ustar adamstaff00000000000000#namedtuple is needed for find_mod_objs so it can have a non-local module import sys from collections import namedtuple import pytest from ..utils import find_mod_objs PY3 = sys.version_info[0] >= 3 pytestmark = pytest.mark.skipif("PY3") def test_find_mod_objs(): lnms, fqns, objs = find_mod_objs('astropy_helpers') # this import is after the above call intentionally to make sure # find_mod_objs properly imports astropy on its own import astropy_helpers # just check for astropy.test ... other things might be added, so we # shouldn't check that it's the only thing assert lnms == [] lnms, fqns, objs = find_mod_objs( 'astropy_helpers.sphinx.ext.tests.test_utils', onlylocals=False) assert namedtuple in objs lnms, fqns, objs = find_mod_objs( 'astropy_helpers.sphinx.ext.tests.test_utils', onlylocals=True) assert 'namedtuple' not in lnms assert 'collections.namedtuple' not in fqns assert namedtuple not in objs ././@LongLink0000000000000000000000000000015400000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tocdepthfix.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/tocdept0000644000077000000240000000124512354456432033111 0ustar adamstaff00000000000000from sphinx import addnodes def fix_toc_entries(app, doctree): # Get the docname; I don't know why this isn't just passed in to the # callback # This seems a bit unreliable as it's undocumented, but it's not "private" # either: docname = app.builder.env.temp_data['docname'] if app.builder.env.metadata[docname].get('tocdepth', 0) != 0: # We need to reprocess any TOC nodes in the doctree and make sure all # the files listed in any TOCs are noted for treenode in doctree.traverse(addnodes.toctree): app.builder.env.note_toctree(docname, treenode) def setup(app): app.connect('doctree-read', fix_toc_entries) ././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/traitsdoc.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/traitsd0000644000077000000240000001026112354456432033117 0ustar adamstaff00000000000000""" ========= traitsdoc ========= Sphinx extension that handles docstrings in the Numpy standard format, [1] and support Traits [2]. This extension can be used as a replacement for ``numpydoc`` when support for Traits is required. .. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard .. [2] http://code.enthought.com/projects/traits/ """ from __future__ import division, absolute_import, print_function import inspect import os import pydoc import collections from . import docscrape from . import docscrape_sphinx from .docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString from . import numpydoc from . import comment_eater class SphinxTraitsDoc(SphinxClassDoc): def __init__(self, cls, modulename='', func_doc=SphinxFunctionDoc): if not inspect.isclass(cls): raise ValueError("Initialise using a class. Got %r" % cls) self._cls = cls if modulename and not modulename.endswith('.'): modulename += '.' self._mod = modulename self._name = cls.__name__ self._func_doc = func_doc docstring = pydoc.getdoc(cls) docstring = docstring.split('\n') # De-indent paragraph try: indent = min(len(s) - len(s.lstrip()) for s in docstring if s.strip()) except ValueError: indent = 0 for n,line in enumerate(docstring): docstring[n] = docstring[n][indent:] self._doc = docscrape.Reader(docstring) self._parsed_data = { 'Signature': '', 'Summary': '', 'Description': [], 'Extended Summary': [], 'Parameters': [], 'Returns': [], 'Raises': [], 'Warns': [], 'Other Parameters': [], 'Traits': [], 'Methods': [], 'See Also': [], 'Notes': [], 'References': '', 'Example': '', 'Examples': '', 'index': {} } self._parse() def _str_summary(self): return self['Summary'] + [''] def _str_extended_summary(self): return self['Description'] + self['Extended Summary'] + [''] def __str__(self, indent=0, func_role="func"): out = [] out += self._str_signature() out += self._str_index() + [''] out += self._str_summary() out += self._str_extended_summary() for param_list in ('Parameters', 'Traits', 'Methods', 'Returns','Raises'): out += self._str_param_list(param_list) out += self._str_see_also("obj") out += self._str_section('Notes') out += self._str_references() out += self._str_section('Example') out += self._str_section('Examples') out = self._str_indent(out,indent) return '\n'.join(out) def looks_like_issubclass(obj, classname): """ Return True if the object has a class or superclass with the given class name. Ignores old-style classes. """ t = obj if t.__name__ == classname: return True for klass in t.__mro__: if klass.__name__ == classname: return True return False def get_doc_object(obj, what=None, config=None): if what is None: if inspect.isclass(obj): what = 'class' elif inspect.ismodule(obj): what = 'module' elif isinstance(obj, collections.Callable): what = 'function' else: what = 'object' if what == 'class': doc = SphinxTraitsDoc(obj, '', func_doc=SphinxFunctionDoc, config=config) if looks_like_issubclass(obj, 'HasTraits'): for name, trait, comment in comment_eater.get_class_traits(obj): # Exclude private traits. if not name.startswith('_'): doc['Traits'].append((name, trait, comment.splitlines())) return doc elif what in ('function', 'method'): return SphinxFunctionDoc(obj, '', config=config) else: return SphinxDocString(pydoc.getdoc(obj), config=config) def setup(app): # init numpydoc numpydoc.setup(app, get_doc_object) ././@LongLink0000000000000000000000000000014600000000000011216 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/utils.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/utils.p0000644000077000000240000000443312354456432033047 0ustar adamstaff00000000000000import inspect import sys def find_mod_objs(modname, onlylocals=False): """ Returns all the public attributes of a module referenced by name. .. note:: The returned list *not* include subpackages or modules of `modname`,nor does it include private attributes (those that beginwith '_' or are not in `__all__`). Parameters ---------- modname : str The name of the module to search. onlylocals : bool If True, only attributes that are either members of `modname` OR one of its modules or subpackages will be included. Returns ------- localnames : list of str A list of the names of the attributes as they are named in the module `modname` . fqnames : list of str A list of the full qualified names of the attributes (e.g., ``astropy.utils.misc.find_mod_objs``). For attributes that are simple variables, this is based on the local name, but for functions or classes it can be different if they are actually defined elsewhere and just referenced in `modname`. objs : list of objects A list of the actual attributes themselves (in the same order as the other arguments) """ __import__(modname) mod = sys.modules[modname] if hasattr(mod, '__all__'): pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__] else: pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_'] # filter out modules and pull the names and objs out ismodule = inspect.ismodule localnames = [k for k, v in pkgitems if not ismodule(v)] objs = [v for k, v in pkgitems if not ismodule(v)] # fully qualified names can be determined from the object's module fqnames = [] for obj, lnm in zip(objs, localnames): if hasattr(obj, '__module__') and hasattr(obj, '__name__'): fqnames.append(obj.__module__ + '.' + obj.__name__) else: fqnames.append(modname + '.' + lnm) if onlylocals: valids = [fqn.startswith(modname) for fqn in fqnames] localnames = [e for i, e in enumerate(localnames) if valids[i]] fqnames = [e for i, e in enumerate(fqnames) if valids[i]] objs = [e for i, e in enumerate(objs) if valids[i]] return localnames, fqnames, objs ././@LongLink0000000000000000000000000000015100000000000011212 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/viewcode.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/ext/viewcod0000644000077000000240000001743712425434461033116 0ustar adamstaff00000000000000# -*- coding: utf-8 -*- """ sphinx.ext.viewcode ~~~~~~~~~~~~~~~~~~~ Add links to module code in Python object descriptions. :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. Patched using patch in https://bitbucket.org/birkenfeld/sphinx/issue/623/extension-viewcode-fails-with-function on 21 Aug 2013 by Kyle H Barbary """ from docutils import nodes from sphinx import addnodes from sphinx.locale import _ from sphinx.pycode import ModuleAnalyzer from sphinx.util.nodes import make_refnode import sys import traceback if sys.version < '3': text_type = unicode else: text_type = str from ...utils import iteritems def doctree_read(app, doctree): env = app.builder.env if not hasattr(env, '_viewcode_modules'): env._viewcode_modules = {} def get_full_modname(modname, attribute): try: __import__(modname) except Exception as error: if not app.quiet: app.info(traceback.format_exc().rstrip()) app.warn('viewcode can\'t import %s, failed with error "%s"' % (modname, error)) return None module = sys.modules[modname] try: # Allow an attribute to have multiple parts and incidentially allow # repeated .s in the attribute. attr = attribute.split('.') value = module for attr in attribute.split('.'): if attr: value = getattr(value, attr) except AttributeError: app.warn('Didn\'t find %s in %s' % (attribute, module.__name__)) return None else: return getattr(value, '__module__', None) def has_tag(modname, fullname, docname, refname): entry = env._viewcode_modules.get(modname, None) if entry is None: try: analyzer = ModuleAnalyzer.for_module(modname) except Exception: env._viewcode_modules[modname] = False return analyzer.find_tags() if not isinstance(analyzer.code, text_type): code = analyzer.code.decode(analyzer.encoding) else: code = analyzer.code entry = code, analyzer.tags, {}, refname env._viewcode_modules[modname] = entry elif entry is False: return _, tags, used, _ = entry if fullname in tags: used[fullname] = docname return True for objnode in doctree.traverse(addnodes.desc): if objnode.get('domain') != 'py': continue names = set() for signode in objnode: if not isinstance(signode, addnodes.desc_signature): continue modname = signode.get('module') fullname = signode.get('fullname') refname = modname if env.config.viewcode_import: modname = get_full_modname(modname, fullname) if not modname: continue if not has_tag(modname, fullname, env.docname, refname): continue if fullname in names: # only one link per name, please continue names.add(fullname) pagename = '_modules/' + modname.replace('.', '/') onlynode = addnodes.only(expr='html') onlynode += addnodes.pending_xref( '', reftype='viewcode', refdomain='std', refexplicit=False, reftarget=pagename, refid=fullname, refdoc=env.docname) onlynode[0] += nodes.inline('', _('[source]'), classes=['viewcode-link']) signode += onlynode def missing_reference(app, env, node, contnode): # resolve our "viewcode" reference nodes -- they need special treatment if node['reftype'] == 'viewcode': return make_refnode(app.builder, node['refdoc'], node['reftarget'], node['refid'], contnode) def collect_pages(app): env = app.builder.env if not hasattr(env, '_viewcode_modules'): return highlighter = app.builder.highlighter urito = app.builder.get_relative_uri modnames = set(env._viewcode_modules) app.builder.info(' (%d module code pages)' % len(env._viewcode_modules), nonl=1) for modname, entry in iteritems(env._viewcode_modules): if not entry: continue code, tags, used, refname = entry # construct a page name for the highlighted source pagename = '_modules/' + modname.replace('.', '/') # highlight the source using the builder's highlighter highlighted = highlighter.highlight_block(code, 'python', linenos=False) # split the code into lines lines = highlighted.splitlines() # split off wrap markup from the first line of the actual code before, after = lines[0].split('
    ')
            lines[0:1] = [before + '
    ', after]
            # nothing to do for the last line; it always starts with 
    anyway # now that we have code lines (starting at index 1), insert anchors for # the collected tags (HACK: this only works if the tag boundaries are # properly nested!) maxindex = len(lines) - 1 for name, docname in iteritems(used): type, start, end = tags[name] backlink = urito(pagename, docname) + '#' + refname + '.' + name lines[start] = ( '
    %s' % (name, backlink, _('[docs]')) + lines[start]) lines[min(end - 1, maxindex)] += '
    ' # try to find parents (for submodules) parents = [] parent = modname while '.' in parent: parent = parent.rsplit('.', 1)[0] if parent in modnames: parents.append({ 'link': urito(pagename, '_modules/' + parent.replace('.', '/')), 'title': parent}) parents.append({'link': urito(pagename, '_modules/index'), 'title': _('Module code')}) parents.reverse() # putting it all together context = { 'parents': parents, 'title': modname, 'body': _('

    Source code for %s

    ') % modname + \ '\n'.join(lines) } yield (pagename, context, 'page.html') if not modnames: return app.builder.info(' _modules/index') html = ['\n'] # the stack logic is needed for using nested lists for submodules stack = [''] for modname in sorted(modnames): if modname.startswith(stack[-1]): stack.append(modname + '.') html.append('
      ') else: stack.pop() while not modname.startswith(stack[-1]): stack.pop() html.append('
    ') stack.append(modname + '.') html.append('
  • %s
  • \n' % ( urito('_modules/index', '_modules/' + modname.replace('.', '/')), modname)) html.append('' * (len(stack) - 1)) context = { 'title': _('Overview: module code'), 'body': _('

    All modules for which code is available

    ') + \ ''.join(html), } yield ('_modules/index', context, 'page.html') def setup(app): app.add_config_value('viewcode_import', True, False) app.connect('doctree-read', doctree_read) app.connect('html-collect-pages', collect_pages) app.connect('missing-reference', missing_reference) #app.add_config_value('viewcode_include_modules', [], 'env') #app.add_config_value('viewcode_exclude_modules', [], 'env') astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/local/0000755000077000000240000000000012505171566032014 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000016000000000000011212 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/local/python3links.invastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/local/pytho0000644000077000000240000000050012354456432033075 0ustar adamstaff00000000000000# Sphinx inventory version 2 # Project: Python # Version: 3.4 # The remainder of this file is compressed using zlib. xœ¥‘Á‚0 †ï{ /zØŒWïxÖÄ€Yflص ¼½0Ð  ‰—-ë¾ÿë–æOšî\°ÕT9›ÈSbª3쎟šW%Õf—VŠ{UƒcJQh54Ëì·8…BR¸ü š66žàyJ›Ìû-FÓ# áÅàIõG×€]k¼ ƒjÅ …vV3"XR#xu {ô:è×-Ñ÷!{\3i šiÁ?Ý"F)ú¿2¨Û°Fýã}PÎQ)¬,í'è>õ×ð7././@LongLink0000000000000000000000000000015200000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/setup_package.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/setup_packa0000644000077000000240000000050412354456432033143 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst def get_package_data(): # Install the theme files return { 'astropy_helpers.sphinx': [ 'ext/templates/*/*', 'local/*.inv', 'themes/bootstrap-astropy/*.*', 'themes/bootstrap-astropy/static/*.*']} astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/0000755000077000000240000000000012505171566032207 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000016300000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000755000077000000240000000000012505171566033073 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000020100000000000011206 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.htmlastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000011112354456432033066 0ustar adamstaff00000000000000

    Table of Contents

    {{ toctree(maxdepth=-1, titles_only=true) }} ././@LongLink0000000000000000000000000000017600000000000011221 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/layout.htmlastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000655012354456432033103 0ustar adamstaff00000000000000{% extends "basic/layout.html" %} {# Collapsible sidebar script from default/layout.html in Sphinx #} {% set script_files = script_files + ['_static/sidebar.js'] %} {# Add the google webfonts needed for the logo #} {% block extrahead %} {% if not embedded %}{% endif %} {% endblock %} {% block header %}
    {{ theme_logotext1 }}{{ theme_logotext2 }}{{ theme_logotext3 }}
    • Index
    • Modules
    • {% block sidebarsearch %} {% include "searchbox.html" %} {% endblock %}
    {% endblock %} {% block relbar1 %} {% endblock %} {# Silence the bottom relbar. #} {% block relbar2 %}{% endblock %} {%- block footer %}

    {%- if edit_on_github %} {{ edit_on_github_page_message }}   {%- endif %} {%- if show_source and has_source and sourcename %} {{ _('Page Source') }} {%- endif %}   Back to Top

    {%- if show_copyright %} {%- if hasdoc('copyright') %} {% trans path=pathto('copyright'), copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}
    {%- else %} {% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}
    {%- endif %} {%- endif %} {%- if show_sphinx %} {% trans sphinx_version=sphinx_version|e %}Created using Sphinx {{ sphinx_version }}.{% endtrans %}   {%- endif %} {%- if last_updated %} {% trans last_updated=last_updated|e %}Last built {{ last_updated }}.{% endtrans %}
    {%- endif %}

    {%- endblock %} ././@LongLink0000000000000000000000000000020000000000000011205 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.htmlastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000004212354456432033071 0ustar adamstaff00000000000000

    Page Contents

    {{ toc }} ././@LongLink0000000000000000000000000000020100000000000011206 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.htmlastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000042012354456432033071 0ustar adamstaff00000000000000{%- if pagename != "search" %}
    {%- endif %} ././@LongLink0000000000000000000000000000017200000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000755000077000000240000000000012505171566033073 5ustar adamstaff00000000000000././@LongLink0000000000000000000000000000022000000000000011207 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.pngastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000327512354456432033104 0ustar adamstaff00000000000000‰PNG  IHDR[â8A bKGDÿÿÿ ½§“ oFFsvek pHYs × ×B(›x vpAg\@0¢Ð¬IDATXÃå˜iŒ_SÆϘÚ+Új‹fF« BH‘XbOÐέ†ª}‰-Z¤Abû¢$¤Öi…V#¸T•ZCÕ– µIi™ÚU”d¦ª÷ý›;·÷?™)Ó*OrsïyÏsÏûžçžóžs®è!ج’ôLOùÙ`[À–=é`œ3|¼±;»1`{ÛͶﱽÔv]mú«ßØÞX°=˜l¦y’Zjs„á@30ŒlÈ<,éÝ’ÆöÆ @+ð60SÒ϶ûÇG½í‰ñü¡¤mo œ¬‘t—íþÀ%À `¶¤4üÔ pÐX<,’Ô1¦„:`•R~qÂPà` ð.°0kœÐ¨WJéŒs¶@R>)é÷ÎÀ´Ntž$éS`6p6pTØím¢5…—ÿÆHš“s8˜Éã{à@`»¿ ÷J:×v=ð%``/à9`çàœ/iší~À\`ÿbŸ{ƒçœH7KBäÝ€§"Æ“o€f¥´:¡/°hRÊʱ' J™\"ö`ànàÜ*ý[!©ÍöåÀ”ˆÿ `'I­ØÆö¶µ}Ÿí ¶o´Ý9÷#Ûg›Ùþ6ì l²}’í—m¿h[¶›lO·ýeð~ŽòtÛgE;õnÇÛkmϳ=Ëö^ÑÎKQ¿&âš~*¸² Ò NøÑ §ìµNxÊ ×æl30¡L-'ÌwÂ~¥uö ÛOÒ lOŒ˜Ïm)†ÙÞ©`»"×±ÁakÈÙšs\"5äߟ[m,ˆÝfû˜Bý±¹ú 9{ígÃþ[Œþ¼Ø“ªØà„'(Ê8á}'ëðú;aqÑ^{N•:l_q-ãÔHZ"éëx©.„Ü5ÇkŠû×ÀOñ|[ì86—„¤_Y?Ü-éé‚í¸¸ÿB6m‰8×wDqkÚ×… ÚÊ(eY´5$ʯwdz"ðD%¿—iZMh²´1/éѪbÛîmûZÛŸ‘åÒ¸0Çë] ŒV’-Ž_Ù¾9öÕ냲…ª1îK%­)Ôå®AÝðÓBûº08­À9•lî *±íN¶à'’ž M/ÎØÛÛo×;·GcJ=IÏÛ€€þÀeÀ›¶û®§àÕ:T6’܆ò}ÖæÊ³€£œP à„F 7°¸“6J}Kú h,ÌÐa¡S‡ÎŒŠV`¤¤‹%½üXU é[I—»WEÀÿˆÔ°<îM¶‹;¤Á¹çeÝh³1ÏWÊjà% 2úF3;I!±ËF6’Z ¦âÇ¥†ÈcÀrIKªtªÝ›=¢"€¤VIS€rªà·¸°½Y7Å®ï·ÎÈù8/ŠmÀü®4æ„}Õdg‡<¦çÄóhàÁ.4§.p*Úv»ø*žw·}=YJ9ÖÝÙ¼,²=øì”…9ú;À @_`†í¹ÀÊ.þ'IÉöê#{lï |Hv868·Hú¦ðÞÞNRòûï-ÈRãÍ%£öM Þ ûµJÿšQÕÐVCvNé öŒ¶¸&ìk"À“ÉrrÉv$Ä•Ç:ŽŒidi¥8%®WiµU!i­íÑÀcáçÒ\õÀý¹XóÌsÂL²…w7`2°¸o?)8áNàqàÖ.ŠØd{rxS˜yÙ¾ÓÞ¸˜,¡¯î—ôží1À²³ýòàöŽúß‘”æåOtÁ\ V $MSë©A{UÒGeÑFºj&;öö#›IIZg‹dK| ó€=ÉÆJYTM'lE¶»¤”–ÎÔ‹³Äé]ü(¯Hú üMq¨¹h=ÞÛÏ ¯lˆkþ~›<&wmGÿk±pYº™½!üõäÿì%âÿÈ#ÀædëÀX¥·h=…ÿ’ØSß»À3p5™Ø‹óÛĞƟ ½§pÅ%tEXtdate:create2012-10-18T20:57:33+02:00¢p_f%tEXtdate:modify2012-10-18T20:57:33+02:00Ó-çÚtEXtSoftwarewww.inkscape.org›î<IEND®B`‚././@LongLink0000000000000000000000000000021200000000000011210 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.icoastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000217612354456432033103 0ustar adamstaff00000000000000 h(  × × $ý'ýüùü* ümîïþ“dmýƒüU$ýýý#ý"ý!ý%ý"ý1ü2ý üª ýû‘šþÿÿÿÿþ4Eýþüÿýîý•ýü'ý.þ-þ%ü 3üüá6ýÿàäþýõøþüG\ýûüûüý üþüÿ üí&üH )ý,ý=þû'ý¶+ýÿÝâþøÇÓþþ#ýÿ!ýþl…ýþ¨´þþœªþýKiýú!ýþ$ýý/ýP.ý-ý@þC$ýÿwþý÷úþþ 3ýþ DþÿåëþÿúûÿÿÁÎþÿÐÚþþÿÿÿÿÅÐþü;þÿ-ýñ=þ%3þ>þˆ4ýÿØáþü•«þþ$ýÿÏÚþÿÉ×þÿ4ýÿ"ýÿ"ýÿ RþþáêþÿÅÒþú6ýÿ;þ¨.ýBý¨JþÿøúþüRþþTþÿÿÿÿÿ0aþÿIxþÿ¼Îþÿœ¸þÿ Býÿ UþþÿÿÿþW‚þÿ8ýöTþ-Lý RþÿõùþüX‰þþ_þÿöøþÿ´Ëþÿÿÿÿÿûüþÿÿÿÿÿœ»þÿ5ýÿ¿Ðþþ°ÉþüAýÿSþt\þtOýÿÈÛþü®ÉþþCýÿ»Òþÿÿÿÿÿÿÿÿÿ¶Ïþÿ¡ÂþÿÐàþÿBýÿ˜¸þþÏàþüNýÿZþ mþ-XýöNþÿÿÿÿþKþþWýÿWšþÿGþÿ\ýÿÔãþÿ¢ÆþÿIýÿ®Ëþþ¿×þüVýÿdþ¨oýmþ¨dýÿŠ»þúÿÿÿÿ¢Çþþ@ŽþÿN–þÿÔåþÿíõþÿuþÿdýÿð÷þþy°þü_ýÿoþˆuþsþ%uþñmýÿR¢þüÕéþÿûþþþùýþÿ´Øþÿþÿ{þÿ»Úþþëôþþ~ýýqýÿvþC{þþ}þP€þývþþvþú ‚þý€þþtþþoþþ¬Ôþÿÿÿÿþ¼þøtþÿ€þ¶ÿiý}þˆÿ…ÿH‰ÿí‰ÿÿ†ÿþ…ÿý ŒÿûNªÿû—Îþü[²þý‹ÿÿ†ÿá…þ…ÿyýxý€þÿŽþþ”‘þî‘þÿ‘þþ:«þþ þÿ‡ÿúþªþšÿ‡þÿ…ÿ„ÿƒÿ‰ÿ“ÿ˜ÿ—ÿU—ÿ€ÿˆšÿl¤ÿ*zÿ~þ…þ‚þ$@ €€€€@ P$ ././@LongLink0000000000000000000000000000021500000000000011213 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.pngastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000353412354456432033102 0ustar adamstaff00000000000000‰PNG  IHDR szzôsBIT|dˆ pHYsÓÇòŽtEXtSoftwarewww.inkscape.org›î<ÙIDATX…Å—PT×Ç?÷ñc‘P° ˆ „FƒUBìȘ&Ådi”I# ±ÒÄJhC2æÇŒ5ÑÔtw:íÛª5ÑÒSÒÆª©é„Ú¡%¨ZÉF2Vk­JFŒ`ÁŠ(JdÙ÷öÝþqaß., É?½3gæ½sÏïýžûΞº®óÿ\Ñ_ÄÉ•ìÎ#šÅHŠl ø2pèZ€Ý8ØãéÔ¯KL”Wš;†AC°È‹h4¥z>ÕÀ$?ñôé—#¹hJ~‹»œ›´`;&y˜#D²ËÂß b0¨Â¤Åu‹»2RìqKàJr'âã7˜<6.´;`Îã2Ò‹@‹†Ž&°Ìa‹$`›+Æâ1ôWB]Ç, w.rÆM¶|»r€Þh?G6B—m"ù‘GêÕïKàƒ…“œ0º#Ñ&¢: WBÅaˆË°mL6¸pÏ€+àΔƒx¥Áti@D1Çä;«áz§ v³ú7zCýrׇóE9ÎÐäš ‹,“é_Gÿ±hbÞˆy•ˆ;¾Ñ Ðñ!,e÷ÙUÄ—¦AÚlˆO†„©ˆ€-^;V€¬…~ï;MçÅðKxUZùK%:Lü剜"¸ë9äžáT½rÝë†3WCúWaá8úè9ô³`p4XW·;KšxBjó«ËwÙÉ¥„Ö÷á“ýÐÚׇ.WêLDå_e5Êw`ÎDîzFíG;ßz9ì¾?@ÈghI^Ž ÄâUˆ¥›Ô³áƒÆMÈl…+çíãÇÄs%bñZˆK„»Ÿ‚Ão@ûÅ`ó!8¹ò—À¬o‚)Ô!ÔÊpu¹4W›;Uü0ˆ0×i'÷Ý@V— ë\Ð}>üÖßôÁž Èu Àôƒˆï¾ ¦übdëÇ‘‰Yáþ>rµ¡z—c0iØI,\1D‹‰ÜX §)‡Ìùׇˆ×üˆ__…Šm cáB3ì߬|f̃¹ÙI.œ²KŸ;ò“NÖ¤AqÐ!~*Üùr8Þg)ã¬BÄß…¬;!*â'#î©DÔôÁürdÓN;Ql’ à|(€Ùá Xôj®€[Ã`aPy÷ã* ÷ר—¦Ô¥h¹bâO½¶Î 9el¢­ïë 0HÆi¦a29HáReÜÝ 5*Ã@ä)}豄 ¢cU5ö»aÙIr mý0›Jú€nARÂPÊør‡j­&5â“+Þðçõ£AL:éµKðAƒÍ\îÿ´ž eà'_Œ໩âlg'ò›Èm/!7|ü¾p7z‘¯T@ß5å—0 KÕÞ¹Àg†öƒ ú@/fHN|ׯ@b bÁÃÈú8X‹lü,yf} ºÚ ®ú•ˆU; )U1·o»bSµ j€~Ú¦‚aS2!&A”8¼/‡‚û ¿Ž7ªhu¯Ž.@ùó0¿D=¿_oo nIøý/© Ió”è70è¦FÞ§¬&%ÀýÁ¶,Ô*}t â—ƒ{Ë#ÿ$'Ï@ütbÅËʾç?ÈuO„Ú j&Á¡DèºÎK î-T㎉E4| )épá,ò;·Ûí³ôˆµ¿…¨!ÊÎ7ÿ¼Èö3ˆiÙ0ý6X°“Ô¾¹ò8önðôB°ÚSjOEÑšÅNi 0ýÈÚ-ˆg<0c&”T@Ãe]· ùßKˆ» .²ó ;©Þzäæç¡³-Tû³™R[åt:iºÝy±è„·‹,, å4âÑçÝEBÛY8{Z5˜öðîFô÷A¬¦¤ƒÐK]àä?‘úÓð»upíjèLñ©,ñ<«÷…" ^?aReÁ ÀAO/¬YŽØü–±áHKCî}K7ÿÙ¼V='N†´ èhß@$.:4Á}žr½säFp"jÊw^ùÆqo?%Š…føä$¢äâþ2HÍ€÷€°O6àƒžËà75E)iנس\o™FÌ„ë*õj¬þ”î{YU†¬¢üI´¿…ܹ㠦!bò¦¦Qà©Ð[Ç¢&âX¾¶Æ])àWHTÿ]º í…ŸAÖ­Ê`Їu×W ëâXq;¤dÍúgõÚ± "20¼Ö¯Ð·k·að:µobÝ3¹u‹2pÄ!}rô¸nÒ,TjÝäN$9Là¿¡k“{rÀâAMP*a¦Öri.©išÜ[ï—ËÊÎ h“Ш™ì÷¼¨7O$éç0 Ë•Lg§$3ó3Çãÿ¼ G®ÿ.Á½8<ßÇIEND®B`‚././@LongLink0000000000000000000000000000021700000000000011215 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.cssastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000002647012425434461033103 0ustar adamstaff00000000000000/*! * Bootstrap v1.4.0 * * Copyright 2011 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Heavily modified by Kyle Barbary for the AstroPy Project for use with Sphinx. */ @import url("basic.css"); body { background-color: #ffffff; margin: 0; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; font-weight: normal; line-height: 18px; color: #404040; } /* Hyperlinks ----------------------------------------------------------------*/ a { color: #0069d6; text-decoration: none; line-height: inherit; font-weight: inherit; } a:hover { color: #00438a; text-decoration: underline; } /* Typography ----------------------------------------------------------------*/ h1,h2,h3,h4,h5,h6 { color: #404040; margin: 0.7em 0 0 0; line-height: 1.5em; } h1 { font-size: 24px; margin: 0; } h2 { font-size: 21px; line-height: 1.2em; margin: 1em 0 0.5em 0; border-bottom: 1px solid #404040; } h3 { font-size: 18px; } h4 { font-size: 16px; } h5 { font-size: 14px; } h6 { font-size: 13px; text-transform: uppercase; } p { font-size: 13px; font-weight: normal; line-height: 18px; margin-top: 0px; margin-bottom: 9px; } ul, ol { margin-left: 0; padding: 0 0 0 25px; } ul ul, ul ol, ol ol, ol ul { margin-bottom: 0; } ul { list-style: disc; } ol { list-style: decimal; } li { line-height: 18px; color: #404040; } ul.unstyled { list-style: none; margin-left: 0; } dl { margin-bottom: 18px; } dl dt, dl dd { line-height: 18px; } dl dd { margin-left: 9px; } hr { margin: 20px 0 19px; border: 0; border-bottom: 1px solid #eee; } strong { font-style: inherit; font-weight: bold; } em { font-style: italic; font-weight: inherit; line-height: inherit; } .muted { color: #bfbfbf; } address { display: block; line-height: 18px; margin-bottom: 18px; } code, pre { padding: 0 3px 2px; font-family: monospace; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } tt { font-family: monospace; } code { color: rgba(0, 0, 0, 0.75); padding: 1px 3px; } pre { display: block; padding: 8.5px; margin: 0 0 18px; line-height: 18px; border: 1px solid #ddd; border: 1px solid rgba(0, 0, 0, 0.12); -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; white-space: pre; white-space: pre-wrap; word-wrap: break-word; } img { margin: 9px 0; } /* format inline code with a rounded box */ tt { margin: 0 2px; padding: 0 5px; border: 1px solid #ddd; border: 1px solid rgba(0, 0, 0, 0.12); border-radius: 3px; } /* all code has same box background color, even in headers */ h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt, pre, code, tt { background-color: #f8f8f8; } /* override box for links & other sphinx-specifc stuff */ tt.xref, a tt, tt.descname, tt.descclassname { padding: 0 1px 0 1px; border: none; } /* override box for related bar at the top of the page */ .related tt { border: none; padding: 0 1px 0 1px; background-color: transparent; font-weight: bold; } th { background-color: #dddddd; } .viewcode-back { font-family: sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; } table.docutils { border-spacing: 5px; border-collapse: separate; } /* Topbar --------------------------------------------------------------------*/ div.topbar { height: 40px; position: absolute; top: 0; left: 0; right: 0; z-index: 10000; padding: 0px 10px; background-color: #222; background-color: #222222; background-repeat: repeat-x; background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222)); background-image: -moz-linear-gradient(top, #333333, #222222); background-image: -ms-linear-gradient(top, #333333, #222222); background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222)); background-image: -webkit-linear-gradient(top, #333333, #222222); background-image: -o-linear-gradient(top, #333333, #222222); background-image: linear-gradient(top, #333333, #222222); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); } div.topbar a.brand { font-family: 'Source Sans Pro', sans-serif; font-size: 26px; color: #ffffff; font-weight: 600; text-decoration: none; float: left; display: block; height: 32px; padding: 8px 12px 0px 45px; margin-left: -10px; background: transparent url("astropy_logo_32.png") no-repeat 10px 4px; } #logotext1 { } #logotext2 { font-weight:200; color: #ff5000; } #logotext3 { font-weight:200; } div.topbar .brand:hover, div.topbar ul li a.homelink:hover { background-color: #333; background-color: rgba(255, 255, 255, 0.05); } div.topbar ul { font-size: 110%; list-style: none; margin: 0; padding: 0 0 0 10px; float: right; color: #bfbfbf; text-align: center; text-decoration: none; height: 100%; } div.topbar ul li { float: left; display: inline; height: 30px; margin: 5px; padding: 0px; } div.topbar ul li a { color: #bfbfbf; text-decoration: none; padding: 5px; display: block; height: auto; text-align: center; vertical-align: middle; border-radius: 4px; } div.topbar ul li a:hover { color: #ffffff; text-decoration: none; } div.topbar ul li a.homelink { width: 112px; display: block; height: 20px; padding: 5px 0px; background: transparent url("astropy_linkout_20.png") no-repeat 10px 5px; } div.topbar form { text-align: left; margin: 0 0 0 5px; position: relative; filter: alpha(opacity=100); -khtml-opacity: 1; -moz-opacity: 1; opacity: 1; } div.topbar input { background-color: #444; background-color: rgba(255, 255, 255, 0.3); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: normal; font-weight: 13px; line-height: 1; padding: 4px 9px; color: #ffffff; color: rgba(255, 255, 255, 0.75); border: 1px solid #111; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.25); -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; transition: none; } div.topbar input:-moz-placeholder { color: #e6e6e6; } div.topbar input::-webkit-input-placeholder { color: #e6e6e6; } div.topbar input:hover { background-color: #bfbfbf; background-color: rgba(255, 255, 255, 0.5); color: #ffffff; } div.topbar input:focus, div.topbar input.focused { outline: 0; background-color: #ffffff; color: #404040; text-shadow: 0 1px 0 #ffffff; border: 0; padding: 5px 10px; -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); } /* Relation bar (breadcrumbs, prev, next) ------------------------------------*/ div.related { height: 21px; width: auto; margin: 0 10px; position: absolute; top: 42px; clear: both; left: 0; right: 0; z-index: 10000; font-size: 100%; vertical-align: middle; background-color: #fff; border-bottom: 1px solid #bbb; } div.related ul { padding: 0; margin: 0; } /* Footer --------------------------------------------------------------------*/ footer { display: block; margin: 10px 10px 0px; padding: 10px 0 0 0; border-top: 1px solid #bbb; } .pull-right { float: right; width: 30em; text-align: right; } /* Sphinx sidebar ------------------------------------------------------------*/ div.sphinxsidebar { font-size: inherit; border-radius: 3px; background-color: #eee; border: 1px solid #bbb; } div.sphinxsidebarwrapper { padding: 0px 0px 0px 5px; } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; font-size: 1.4em; font-weight: normal; margin: 5px 0px 0px 5px; padding: 0; line-height: 1.6em; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 0px 0px 0px 5px; padding: 0; } div.sphinxsidebar ul ul { margin-left: 15px; list-style-type: disc; } /* If showing the global TOC (toctree), color the current page differently */ div.sphinxsidebar a.current { color: #404040; } div.sphinxsidebar a.current:hover { color: #404040; } /* document, documentwrapper, body, bodywrapper ----------------------------- */ div.document { margin-top: 72px; margin-left: 10px; margin-right: 10px; } div.documentwrapper { float: left; width: 100%; } div.body { background-color: #ffffff; padding: 0 0 0px 20px; } div.bodywrapper { margin: 0 0 0 230px; max-width: 55em; } /* Header links ------------------------------------------------------------- */ a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } a.headerlink:hover { background-color: #0069d6; color: white; text-docoration: none; } /* Admonitions and warnings ------------------------------------------------- */ /* Shared by admonitions and warnings */ div.admonition, div.warning { padding: 0px; border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } div.admonition p, div.warning p { margin: 0.5em 1em 0.5em 1em; padding: 0; } div.admonition pre, div.warning pre { margin: 0.4em 1em 0.4em 1em; } div.admonition p.admonition-title, div.warning p.admonition-title { margin: 0; padding: 0.1em 0 0.1em 0.5em; color: white; font-weight: bold; font-size: 1.1em; } div.admonition ul, div.admonition ol, div.warning ul, div.warning ol { margin: 0.1em 0.5em 0.5em 3em; padding: 0; } /* Admonitions only */ div.admonition { border: 1px solid #609060; background-color: #e9ffe9; } div.admonition p.admonition-title { background-color: #70A070; } /* Warnings only */ div.warning { border: 1px solid #900000; background-color: #ffe9e9; } div.warning p.admonition-title { background-color: #b04040; } /* Figures ------------------------------------------------------------------ */ .figure.align-center { clear: none; } /* This is a div for containing multiple figures side-by-side, for use with * .. container:: figures */ div.figures { border: 1px solid #CCCCCC; background-color: #F8F8F8; margin: 1em; text-align: center; } div.figures .figure { clear: none; float: none; display: inline-block; border: none; margin-left: 0.5em; margin-right: 0.5em; } .field-list th { white-space: nowrap; } table.field-list { border-spacing: 0px; margin-left: 1px; border-left: 5px solid rgb(238, 238, 238) !important; } table.field-list th.field-name { display: inline-block; padding: 1px 8px 1px 5px; white-space: nowrap; background-color: rgb(238, 238, 238); border-radius: 0 3px 3px 0; -webkit-border-radius: 0 3px 3px 0; } ././@LongLink0000000000000000000000000000020700000000000011214 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.jsastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000000467712354456432033113 0ustar adamstaff00000000000000$(document).ready(function() { /* Add a [>>>] button on the top-right corner of code samples to hide * the >>> and ... prompts and the output and thus make the code * copyable. */ var div = $('.highlight-python .highlight,' + '.highlight-python3 .highlight') var pre = div.find('pre'); // get the styles from the current theme pre.parent().parent().css('position', 'relative'); var hide_text = 'Hide the prompts and output'; var show_text = 'Show the prompts and output'; var border_width = pre.css('border-top-width'); var border_style = pre.css('border-top-style'); var border_color = pre.css('border-top-color'); var button_styles = { 'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0', 'border-color': border_color, 'border-style': border_style, 'border-width': border_width, 'color': border_color, 'text-size': '75%', 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em', 'border-radius': '0 3px 0 0' } // create and add the button to all the code blocks that contain >>> div.each(function(index) { var jthis = $(this); if (jthis.find('.gp').length > 0) { var button = $('>>>'); button.css(button_styles) button.attr('title', hide_text); jthis.prepend(button); } // tracebacks (.gt) contain bare text elements that need to be // wrapped in a span to work with .nextUntil() (see later) jthis.find('pre:has(.gt)').contents().filter(function() { return ((this.nodeType == 3) && (this.data.trim().length > 0)); }).wrap(''); }); // define the behavior of the button when it's clicked $('.copybutton').toggle( function() { var button = $(this); button.parent().find('.go, .gp, .gt').hide(); button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden'); button.css('text-decoration', 'line-through'); button.attr('title', show_text); }, function() { var button = $(this); button.parent().find('.go, .gp, .gt').show(); button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible'); button.css('text-decoration', 'none'); button.attr('title', hide_text); }); }); ././@LongLink0000000000000000000000000000020400000000000011211 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.jsastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/sphinx/themes/boot0000644000077000000240000001155312354456432033102 0ustar adamstaff00000000000000/* * sidebar.js * ~~~~~~~~~~ * * This script makes the Sphinx sidebar collapsible. * * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton * used to collapse and expand the sidebar. * * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden * and the width of the sidebar and the margin-left of the document * are decreased. When the sidebar is expanded the opposite happens. * This script saves a per-browser/per-session cookie used to * remember the position of the sidebar among the pages. * Once the browser is closed the cookie is deleted and the position * reset to the default (expanded). * * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ $(function() { // global elements used by the functions. // the 'sidebarbutton' element is defined as global after its // creation, in the add_sidebar_button function var bodywrapper = $('.bodywrapper'); var sidebar = $('.sphinxsidebar'); var sidebarwrapper = $('.sphinxsidebarwrapper'); // for some reason, the document has no sidebar; do not run into errors if (!sidebar.length) return; // original margin-left of the bodywrapper and width of the sidebar // with the sidebar expanded var bw_margin_expanded = bodywrapper.css('margin-left'); var ssb_width_expanded = sidebar.width(); // margin-left of the bodywrapper and width of the sidebar // with the sidebar collapsed var bw_margin_collapsed = 12; var ssb_width_collapsed = 12; // custom colors var dark_color = '#404040'; var light_color = '#505050'; function sidebar_is_collapsed() { return sidebarwrapper.is(':not(:visible)'); } function toggle_sidebar() { if (sidebar_is_collapsed()) expand_sidebar(); else collapse_sidebar(); } function collapse_sidebar() { sidebarwrapper.hide(); sidebar.css('width', ssb_width_collapsed); bodywrapper.css('margin-left', bw_margin_collapsed); sidebarbutton.css({ 'margin-left': '-1px', 'height': bodywrapper.height(), 'border-radius': '3px' }); sidebarbutton.find('span').text('»'); sidebarbutton.attr('title', _('Expand sidebar')); document.cookie = 'sidebar=collapsed'; } function expand_sidebar() { bodywrapper.css('margin-left', bw_margin_expanded); sidebar.css('width', ssb_width_expanded); sidebarwrapper.show(); sidebarbutton.css({ 'margin-left': ssb_width_expanded - 12, 'height': bodywrapper.height(), 'border-radius': '0px 3px 3px 0px' }); sidebarbutton.find('span').text('«'); sidebarbutton.attr('title', _('Collapse sidebar')); document.cookie = 'sidebar=expanded'; } function add_sidebar_button() { sidebarwrapper.css({ 'float': 'left', 'margin-right': '0', 'width': ssb_width_expanded - 18 }); // create the button sidebar.append('
    «
    '); var sidebarbutton = $('#sidebarbutton'); // find the height of the viewport to center the '<<' in the page var viewport_height; if (window.innerHeight) viewport_height = window.innerHeight; else viewport_height = $(window).height(); var sidebar_offset = sidebar.offset().top; var sidebar_height = Math.max(bodywrapper.height(), sidebar.height()); sidebarbutton.find('span').css({ 'font-family': '"Lucida Grande",Arial,sans-serif', 'display': 'block', 'top': Math.min(viewport_height/2, sidebar_height/2 + sidebar_offset) - 10, 'width': 12, 'position': 'fixed', 'text-align': 'center' }); sidebarbutton.click(toggle_sidebar); sidebarbutton.attr('title', _('Collapse sidebar')); sidebarbutton.css({ 'color': '#FFFFFF', 'background-color': light_color, 'border': '1px solid ' + light_color, 'border-radius': '0px 3px 3px 0px', 'font-size': '1.2em', 'cursor': 'pointer', 'height': sidebar_height, 'padding-top': '1px', 'margin': '-1px', 'margin-left': ssb_width_expanded - 12 }); sidebarbutton.hover( function () { $(this).css('background-color', dark_color); }, function () { $(this).css('background-color', light_color); } ); } function set_position_from_cookie() { if (!document.cookie) return; var items = document.cookie.split(';'); for(var k=0; k /*************************************************************************** * Macros for determining the compiler version. * * These are borrowed from boost, and majorly abridged to include only * the compilers we care about. ***************************************************************************/ #ifndef PY3K #if PY_MAJOR_VERSION >= 3 #define PY3K 1 #else #define PY3K 0 #endif #endif #define STRINGIZE(X) DO_STRINGIZE(X) #define DO_STRINGIZE(X) #X #if defined __clang__ /* Clang C++ emulates GCC, so it has to appear early. */ # define COMPILER "Clang version " __clang_version__ #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) /* Intel */ # if defined(__INTEL_COMPILER) # define INTEL_VERSION __INTEL_COMPILER # elif defined(__ICL) # define INTEL_VERSION __ICL # elif defined(__ICC) # define INTEL_VERSION __ICC # elif defined(__ECC) # define INTEL_VERSION __ECC # endif # define COMPILER "Intel C compiler version " STRINGIZE(INTEL_VERSION) #elif defined(__GNUC__) /* gcc */ # define COMPILER "GCC version " __VERSION__ #elif defined(__SUNPRO_CC) /* Sun Workshop Compiler */ # define COMPILER "Sun compiler version " STRINGIZE(__SUNPRO_CC) #elif defined(_MSC_VER) /* Microsoft Visual C/C++ Must be last since other compilers define _MSC_VER for compatibility as well */ # if _MSC_VER < 1200 # define COMPILER_VERSION 5.0 # elif _MSC_VER < 1300 # define COMPILER_VERSION 6.0 # elif _MSC_VER == 1300 # define COMPILER_VERSION 7.0 # elif _MSC_VER == 1310 # define COMPILER_VERSION 7.1 # elif _MSC_VER == 1400 # define COMPILER_VERSION 8.0 # elif _MSC_VER == 1500 # define COMPILER_VERSION 9.0 # elif _MSC_VER == 1600 # define COMPILER_VERSION 10.0 # else # define COMPILER_VERSION _MSC_VER # endif # define COMPILER "Microsoft Visual C++ version " STRINGIZE(COMPILER_VERSION) #else /* Fallback */ # define COMPILER "Unknown compiler" #endif /*************************************************************************** * Module-level ***************************************************************************/ struct module_state { /* The Sun compiler can't handle empty structs */ #if defined(__SUNPRO_C) || defined(_MSC_VER) int _dummy; #endif }; #if PY3K static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_compiler", NULL, sizeof(struct module_state), NULL, NULL, NULL, NULL, NULL }; #define INITERROR return NULL PyMODINIT_FUNC PyInit__compiler(void) #else #define INITERROR return PyMODINIT_FUNC init_compiler(void) #endif { PyObject* m; #if PY3K m = PyModule_Create(&moduledef); #else m = Py_InitModule3("_compiler", NULL, NULL); #endif if (m == NULL) INITERROR; PyModule_AddStringConstant(m, "compiler", COMPILER); #if PY3K return m; #endif } ././@LongLink0000000000000000000000000000014700000000000011217 Lustar 00000000000000astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/src/setup_package.pyastroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/src/setup_package.0000644000077000000240000000011312354456432033007 0ustar adamstaff00000000000000def get_package_data(): return {'astropy_helpers.src': ['compiler.c']} astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/test_helpers.py0000644000077000000240000002256512453761452032477 0ustar adamstaff00000000000000from __future__ import (absolute_import, division, print_function, unicode_literals) import inspect import os import shutil import subprocess import sys import tempfile from distutils.core import Command from .compat import _fix_user_options PY3 = sys.version_info[0] == 3 class AstropyTest(Command, object): description = 'Run the tests for this package' user_options = [ ('package=', 'P', "The name of a specific package to test, e.g. 'io.fits' or 'utils'. " "If nothing is specified, all default tests are run."), ('test-path=', 't', 'Specify a test location by path. If a relative path to a .py file, ' 'it is relative to the built package, so e.g., a leading "astropy/" ' 'is necessary. If a relative path to a .rst file, it is relative to ' 'the directory *below* the --docs-path directory, so a leading ' '"docs/" is usually necessary. May also be an absolute path.'), ('verbose-results', 'V', 'Turn on verbose output from pytest.'), ('plugins=', 'p', 'Plugins to enable when running pytest.'), ('pastebin=', 'b', "Enable pytest pastebin output. Either 'all' or 'failed'."), ('args=', 'a', 'Additional arguments to be passed to pytest.'), ('remote-data', 'R', 'Run tests that download remote data.'), ('pep8', '8', 'Enable PEP8 checking and disable regular tests. ' 'Requires the pytest-pep8 plugin.'), ('pdb', 'd', 'Start the interactive Python debugger on errors.'), ('coverage', 'c', 'Create a coverage report. Requires the coverage package.'), ('open-files', 'o', 'Fail if any tests leave files open. Requires the ' 'psutil package.'), ('parallel=', 'j', 'Run the tests in parallel on the specified number of ' 'CPUs. If negative, all the cores on the machine will be ' 'used. Requires the pytest-xdist plugin.'), ('docs-path=', None, 'The path to the documentation .rst files. If not provided, and ' 'the current directory contains a directory called "docs", that ' 'will be used.'), ('skip-docs', None, "Don't test the documentation .rst files."), ('repeat=', None, 'How many times to repeat each test (can be used to check for ' 'sporadic failures).') ] user_options = _fix_user_options(user_options) package_name = '' def initialize_options(self): self.package = None self.test_path = None self.verbose_results = False self.plugins = None self.pastebin = None self.args = None self.remote_data = False self.pep8 = False self.pdb = False self.coverage = False self.open_files = False self.parallel = 0 self.docs_path = None self.skip_docs = False self.repeat = None def finalize_options(self): # Normally we would validate the options here, but that's handled in # run_tests pass def run(self): try: import astropy except ImportError: raise ImportError( "The 'test' command requires the astropy package to be " "installed and importable.") self.reinitialize_command('build', inplace=False) self.run_command('build') build_cmd = self.get_finalized_command('build') new_path = os.path.abspath(build_cmd.build_lib) if self.docs_path is None: if os.path.exists('docs'): self.docs_path = os.path.abspath('docs') else: self.docs_path = os.path.abspath(self.docs_path) # Copy the build to a temporary directory for the purposes of testing # - this avoids creating pyc and __pycache__ directories inside the # build directory tmp_dir = tempfile.mkdtemp(prefix=self.package_name + '-test-') testing_path = os.path.join(tmp_dir, os.path.basename(new_path)) shutil.copytree(new_path, testing_path) shutil.copy('setup.cfg', testing_path) cmd_pre = '' cmd_post = '' try: if self.coverage: if self.parallel != 0: raise ValueError( "--coverage can not be used with --parallel") try: import coverage except ImportError: raise ImportError( "--coverage requires that the coverage package is " "installed.") # Don't use get_pkg_data_filename here, because it # requires importing astropy.config and thus screwing # up coverage results for those packages. coveragerc = os.path.join( testing_path, self.package_name, 'tests', 'coveragerc') # We create a coveragerc that is specific to the version # of Python we're running, so that we can mark branches # as being specifically for Python 2 or Python 3 with open(coveragerc, 'r') as fd: coveragerc_content = fd.read() if PY3: ignore_python_version = '2' else: ignore_python_version = '3' coveragerc_content = coveragerc_content.replace( "{ignore_python_version}", ignore_python_version).replace( "{packagename}", self.package_name) tmp_coveragerc = os.path.join(tmp_dir, 'coveragerc') with open(tmp_coveragerc, 'wb') as tmp: tmp.write(coveragerc_content.encode('utf-8')) cmd_pre = ( 'import coverage; ' 'cov = coverage.coverage(data_file="{0}", config_file="{1}"); ' 'cov.start();'.format( os.path.abspath(".coverage"), tmp_coveragerc)) cmd_post = ( 'cov.stop(); ' 'from astropy.tests.helper import _save_coverage; ' '_save_coverage(cov, result, "{0}", "{1}");'.format( os.path.abspath('.'), testing_path)) test_args = filter(lambda arg: hasattr(self, arg), self._get_test_runner_args()) test_args = ', '.join('{0}={1!r}'.format(arg, getattr(self, arg)) for arg in test_args) if PY3: set_flag = "import builtins; builtins._ASTROPY_TEST_ = True" else: set_flag = "import __builtin__; __builtin__._ASTROPY_TEST_ = True" cmd = ('{cmd_pre}{0}; import {1.package_name}, sys; result = ' '{1.package_name}.test({test_args}); {cmd_post}' 'sys.exit(result)') cmd = cmd.format(set_flag, self, cmd_pre=cmd_pre, cmd_post=cmd_post, test_args=test_args) # Run the tests in a subprocess--this is necessary since # new extension modules may have appeared, and this is the # easiest way to set up a new environment # Remove temporary directory # On Python 3.x prior to 3.3, the creation of .pyc files # is not atomic. py.test jumps through some hoops to make # this work by parsing import statements and carefully # importing files atomically. However, it can't detect # when __import__ is used, so its carefulness still fails. # The solution here (admittedly a bit of a hack), is to # turn off the generation of .pyc files altogether by # passing the `-B` switch to `python`. This does mean # that each core will have to compile .py file to bytecode # itself, rather than getting lucky and borrowing the work # already done by another core. Compilation is an # insignificant fraction of total testing time, though, so # it's probably not worth worrying about. retcode = subprocess.call([sys.executable, '-B', '-c', cmd], cwd=testing_path, close_fds=False) finally: shutil.rmtree(tmp_dir) raise SystemExit(retcode) def _get_test_runner_args(self): """ A hack to determine what arguments are supported by the package's test() function. In the future there should be a more straightforward API to determine this (really it should be determined by the ``TestRunner`` class for whatever version of Astropy is in use). """ if PY3: import builtins builtins._ASTROPY_TEST_ = True else: import __builtin__ __builtin__._ASTROPY_TEST_ = True try: pkg = __import__(self.package_name) if not hasattr(pkg, 'test'): raise ImportError( 'package {0} does not have a {0}.test() function as ' 'required by the Astropy test runner'.format(package_name)) argspec = inspect.getargspec(pkg.test) return argspec.args finally: if PY3: del builtins._ASTROPY_TEST_ else: del __builtin__._ASTROPY_TEST_ astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/utils.py0000644000077000000240000001206612453761452031131 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import contextlib import imp import os import sys try: from importlib import machinery as import_machinery except ImportError: import_machinery = None # Python 3.3's importlib caches filesystem reads for faster imports in the # general case. But sometimes it's necessary to manually invalidate those # caches so that the import system can pick up new generated files. See # https://github.com/astropy/astropy/issues/820 if sys.version_info[:2] >= (3, 3): from importlib import invalidate_caches else: invalidate_caches = lambda: None class _DummyFile(object): """A noop writeable object.""" errors = '' # Required for Python 3.x def write(self, s): pass def flush(self): pass @contextlib.contextmanager def silence(): """A context manager that silences sys.stdout and sys.stderr.""" old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = _DummyFile() sys.stderr = _DummyFile() exception_occurred = False try: yield except: exception_occurred = True # Go ahead and clean up so that exception handling can work normally sys.stdout = old_stdout sys.stderr = old_stderr raise if not exception_occurred: sys.stdout = old_stdout sys.stderr = old_stderr if sys.platform == 'win32': import ctypes def _has_hidden_attribute(filepath): """ Returns True if the given filepath has the hidden attribute on MS-Windows. Based on a post here: http://stackoverflow.com/questions/284115/cross-platform-hidden-file-detection """ if isinstance(filepath, bytes): filepath = filepath.decode(sys.getfilesystemencoding()) try: attrs = ctypes.windll.kernel32.GetFileAttributesW(filepath) assert attrs != -1 result = bool(attrs & 2) except (AttributeError, AssertionError): result = False return result else: def _has_hidden_attribute(filepath): return False def is_path_hidden(filepath): """ Determines if a given file or directory is hidden. Parameters ---------- filepath : str The path to a file or directory Returns ------- hidden : bool Returns `True` if the file is hidden """ name = os.path.basename(os.path.abspath(filepath)) if isinstance(name, bytes): is_dotted = name.startswith(b'.') else: is_dotted = name.startswith('.') return is_dotted or _has_hidden_attribute(filepath) def walk_skip_hidden(top, onerror=None, followlinks=False): """ A wrapper for `os.walk` that skips hidden files and directories. This function does not have the parameter `topdown` from `os.walk`: the directories must always be recursed top-down when using this function. See also -------- os.walk : For a description of the parameters """ for root, dirs, files in os.walk( top, topdown=True, onerror=onerror, followlinks=followlinks): # These lists must be updated in-place so os.walk will skip # hidden directories dirs[:] = [d for d in dirs if not is_path_hidden(d)] files[:] = [f for f in files if not is_path_hidden(f)] yield root, dirs, files def write_if_different(filename, data): """Write `data` to `filename`, if the content of the file is different. Parameters ---------- filename : str The file name to be written to. data : bytes The data to be written to `filename`. """ assert isinstance(data, bytes) if os.path.exists(filename): with open(filename, 'rb') as fd: original_data = fd.read() else: original_data = None if original_data != data: with open(filename, 'wb') as fd: fd.write(data) def import_file(filename): """ Imports a module from a single file as if it doesn't belong to a particular package. """ # Specifying a traditional dot-separated fully qualified name here # results in a number of "Parent module 'astropy' not found while # handling absolute import" warnings. Using the same name, the # namespaces of the modules get merged together. So, this # generates an underscore-separated name which is more likely to # be unique, and it doesn't really matter because the name isn't # used directly here anyway. mode = 'U' if sys.version_info[0] < 3 else 'r' if name is None: basename = os.path.splitext(filename)[0] name = '_'.join(os.path.relpath(basename).split(os.sep)[1:]) if import_machinery: loader = import_machinery.SourceFileLoader(name, filename) mod = loader.load_module() else: with open(filename, mode) as fd: mod = imp.load_module(name, fd, filename, ('.py', mode, 1)) return mod if sys.version_info[0] >= 3: def iteritems(dictionary): return dictionary.items() else: def iteritems(dictionary): return dictionary.iteritems() astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/version.py0000644000077000000240000001242012454670716031453 0ustar adamstaff00000000000000# Autogenerated by Astropy-affiliated package astropy_helpers's setup.py on 2015-01-12 08:03:42.045141 import locale import os import subprocess import warnings def _decode_stdio(stream): try: stdio_encoding = locale.getdefaultlocale()[1] or 'utf-8' except ValueError: stdio_encoding = 'utf-8' try: text = stream.decode(stdio_encoding) except UnicodeDecodeError: # Final fallback text = stream.decode('latin1') return text def update_git_devstr(version, path=None): """ Updates the git revision string if and only if the path is being imported directly from a git working copy. This ensures that the revision number in the version string is accurate. """ try: # Quick way to determine if we're in git or not - returns '' if not devstr = get_git_devstr(sha=True, show_warning=False, path=path) except OSError: return version if not devstr: # Probably not in git so just pass silently return version if 'dev' in version: # update to the current git revision version_base = version.split('.dev', 1)[0] devstr = get_git_devstr(sha=False, show_warning=False, path=path) return version_base + '.dev' + devstr else: #otherwise it's already the true/release version return version def get_git_devstr(sha=False, show_warning=True, path=None): """ Determines the number of revisions in this repository. Parameters ---------- sha : bool If True, the full SHA1 hash will be returned. Otherwise, the total count of commits in the repository will be used as a "revision number". show_warning : bool If True, issue a warning if git returns an error code, otherwise errors pass silently. path : str or None If a string, specifies the directory to look in to find the git repository. If `None`, the current working directory is used. If given a filename it uses the directory containing that file. Returns ------- devversion : str Either a string with the revision number (if `sha` is False), the SHA1 hash of the current commit (if `sha` is True), or an empty string if git version info could not be identified. """ if path is None: path = os.getcwd() if not os.path.isdir(path): path = os.path.abspath(os.path.dirname(path)) if not os.path.exists(os.path.join(path, '.git')): return '' if sha: # Faster for getting just the hash of HEAD cmd = ['rev-parse', 'HEAD'] else: cmd = ['rev-list', '--count', 'HEAD'] def run_git(cmd): try: p = subprocess.Popen(['git'] + cmd, cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdout, stderr = p.communicate() except OSError as e: if show_warning: warnings.warn('Error running git: ' + str(e)) return (None, '', '') if p.returncode == 128: if show_warning: warnings.warn('No git repository present at {0!r}! Using ' 'default dev version.'.format(path)) return (p.returncode, '', '') if p.returncode == 129: if show_warning: warnings.warn('Your git looks old (does it support {0}?); ' 'consider upgrading to v1.7.2 or ' 'later.'.format(cmd[0])) return (p.returncode, stdout, stderr) elif p.returncode != 0: if show_warning: warnings.warn('Git failed while determining revision ' 'count: {0}'.format(_decode_stdio(stderr))) return (p.returncode, stdout, stderr) return p.returncode, stdout, stderr returncode, stdout, stderr = run_git(cmd) if not sha and returncode == 129: # git returns 129 if a command option failed to parse; in # particular this could happen in git versions older than 1.7.2 # where the --count option is not supported # Also use --abbrev-commit and --abbrev=0 to display the minimum # number of characters needed per-commit (rather than the full hash) cmd = ['rev-list', '--abbrev-commit', '--abbrev=0', 'HEAD'] returncode, stdout, stderr = run_git(cmd) # Fall back on the old method of getting all revisions and counting # the lines if returncode == 0: return str(stdout.count(b'\n')) else: return '' elif sha: return _decode_stdio(stdout)[:40] else: return _decode_stdio(stdout).strip() _last_generated_version = '0.4.4' _last_githash = u'ca3953a76d40fd16a0fe5a01b76ee526bb9a69b1' version = update_git_devstr(_last_generated_version) githash = get_git_devstr(sha=True, show_warning=False, path=__file__) or _last_githash major = 0 minor = 4 bugfix = 4 release = True debug = False try: from ._compiler import compiler except ImportError: compiler = "unknown" try: from .cython_version import cython_version except ImportError: cython_version = "unknown" astroquery-0.2.4/astropy_helpers/build/lib.macosx-10.5-x86_64-2.7/astropy_helpers/version_helpers.py0000644000077000000240000001436012425434461033173 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Utilities for generating the version string for Astropy (or an affiliated package) and the version.py module, which contains version info for the package. Within the generated astropy.version module, the `major`, `minor`, and `bugfix` variables hold the respective parts of the version number (bugfix is '0' if absent). The `release` variable is True if this is a release, and False if this is a development version of astropy. For the actual version string, use:: from astropy.version import version or:: from astropy import __version__ """ from __future__ import division import datetime import imp import os import pkgutil import sys from distutils import log from . import git_helpers from .setup_helpers import is_distutils_display_option, get_pkg_version_module from .utils import invalidate_caches PY3 = sys.version_info[0] == 3 def _version_split(version): """ Split a version string into major, minor, and bugfix numbers (with bugfix optional, defaulting to 0). """ for prerel in ('.dev', 'a', 'b', 'rc'): if prerel in version: version = version.split(prerel)[0] versplit = version.split('.') major = int(versplit[0]) minor = int(versplit[1]) bugfix = 0 if len(versplit) < 3 else int(versplit[2]) return major, minor, bugfix # This is used by setup.py to create a new version.py - see that file for # details. Note that the imports have to be absolute, since this is also used # by affiliated packages. _FROZEN_VERSION_PY_TEMPLATE = """ # Autogenerated by {packagename}'s setup.py on {timestamp} {header} major = {major} minor = {minor} bugfix = {bugfix} release = {rel} debug = {debug} try: from ._compiler import compiler except ImportError: compiler = "unknown" try: from .cython_version import cython_version except ImportError: cython_version = "unknown" """[1:] _FROZEN_VERSION_PY_WITH_GIT_HEADER = """ {git_helpers} _last_generated_version = {verstr!r} _last_githash = {githash!r} version = update_git_devstr(_last_generated_version) githash = get_git_devstr(sha=True, show_warning=False, path=__file__) or _last_githash """[1:] def _get_version_py_str(packagename, version, githash, release, debug, uses_git=True): timestamp = str(datetime.datetime.now()) major, minor, bugfix = _version_split(version) if packagename.lower() == 'astropy': packagename = 'Astropy' else: packagename = 'Astropy-affiliated package ' + packagename if uses_git: loader = pkgutil.get_loader(git_helpers) source = loader.get_source(git_helpers.__name__) or '' source_lines = source.splitlines() if not source_lines: log.warn('Cannot get source code for astropy_helpers.git_helpers; ' 'git support disabled.') return _get_version_py_str(packagename, version, release, debug, uses_git=False) idx = 0 for idx, line in enumerate(source_lines): if line.startswith('# BEGIN'): break git_helpers_py = '\n'.join(source_lines[idx + 1:]) if PY3: verstr = version else: # In Python 2 don't pass in a unicode string; otherwise verstr will # be represented with u'' syntax which breaks on Python 3.x with x # < 3. This is only an issue when developing on multiple Python # versions at once verstr = version.encode('utf8') new_githash = git_helpers.get_git_devstr(sha=True, show_warning=False) if new_githash: githash = new_githash header = _FROZEN_VERSION_PY_WITH_GIT_HEADER.format( git_helpers=git_helpers_py, verstr=verstr, githash=githash) else: header = 'version = {0!r}'.format(version) return _FROZEN_VERSION_PY_TEMPLATE.format(packagename=packagename, timestamp=timestamp, header=header, major=major, minor=minor, bugfix=bugfix, rel=release, debug=debug) def generate_version_py(packagename, version, release=None, debug=None, uses_git=True): """Regenerate the version.py module if necessary.""" try: version_module = get_pkg_version_module(packagename) try: last_generated_version = version_module._last_generated_version except AttributeError: last_generated_version = version_module.version try: last_githash = version_module._last_githash except AttributeError: last_githash = '' current_release = version_module.release current_debug = version_module.debug except ImportError: version_module = None last_generated_version = None last_githash = None current_release = None current_debug = None if release is None: # Keep whatever the current value is, if it exists release = bool(current_release) if debug is None: # Likewise, keep whatever the current value is, if it exists debug = bool(current_debug) version_py = os.path.join(packagename, 'version.py') if (last_generated_version != version or current_release != release or current_debug != debug): if '-q' not in sys.argv and '--quiet' not in sys.argv: log.set_threshold(log.INFO) if is_distutils_display_option(): # Always silence unnecessary log messages when display options are # being used log.set_threshold(log.WARN) log.info('Freezing version number to {0}'.format(version_py)) with open(version_py, 'w') as f: # This overwrites the actual version.py f.write(_get_version_py_str(packagename, version, last_githash, release, debug, uses_git=uses_git)) invalidate_caches() if version_module: imp.reload(version_module) astroquery-0.2.4/astropy_helpers/CHANGES.rst0000644000077000000240000000646112464715714021023 0ustar adamstaff00000000000000astropy-helpers Changelog ========================= 0.4.4 (unreleased) ------------------ - No changes yet 0.4.3 (2014-10-22) ------------------ - The generated ``version.py`` file now preserves the git hash of installed copies of the package as well as when building a source distribution. That is, the git hash of the changeset that was installed/released is preserved. [#87] - In smart resolver add resolution for class links when they exist in the intersphinx inventory, but not the mapping of the current package (e.g. when an affiliated package uses an astropy core class of which "actual" and "documented" location differs) [#88] - Fixed a bug that could occur when running ``setup.py`` for the first time in a repository that uses astropy-helpers as a submodule: ``AttributeError: 'NoneType' object has no attribute 'mkdtemp'`` [#89] - Fixed a bug where optional arguments to the ``doctest-skip`` Sphinx directive were sometimes being left in the generated documentation output. [#90] - Improved support for building the documentation using Python 3.x. [#96] - Avoid error message if .git directory is not present. [#91] 0.4.2 (2014-08-09) ------------------ - Fixed some CSS issues in generated API docs. [#69] - Fixed the warning message that could be displayed when generating a version number with some older versions of git. [#77] - Fixed automodsumm to work with new versions of Sphinx (>= 1.2.2). [#80] 0.4.1 (2014-08-08) ------------------ - Fixed git revision count on systems with git versions older than v1.7.2. [#70] - Fixed display of warning text when running a git command fails (previously the output of stderr was not being decoded properly). [#70] - The ``--offline`` flag to ``setup.py`` understood by ``ah_bootstrap.py`` now also prevents git from going online to fetch submodule updates. [#67] - The Sphinx extension for converting issue numbers to links in the changelog now supports working on arbitrary pages via a new ``conf.py`` setting: ``changelog_links_docpattern``. By default it affects the ``changelog`` and ``whatsnew`` pages in one's Sphinx docs. [#61] - Fixed crash that could result from users with missing/misconfigured locale settings. [#58] - The font used for code examples in the docs is now the system-defined ``monospace`` font, rather than ``Minaco``, which is not available on all platforms. [#50] 0.4 (2014-07-15) ---------------- - Initial release of astropy-helpers. See `APE4 `_ for details of the motivation and design of this package. - The ``astropy_helpers`` package replaces the following modules in the ``astropy`` package: - ``astropy.setup_helpers`` -> ``astropy_helpers.setup_helpers`` - ``astropy.version_helpers`` -> ``astropy_helpers.version_helpers`` - ``astropy.sphinx`` - > ``astropy_helpers.sphinx`` These modules should be considered deprecated in ``astropy``, and any new, non-critical changes to those modules will be made in ``astropy_helpers`` instead. Affiliated packages wishing to make use those modules (as in the Astropy package-template) should use the versions from ``astropy_helpers`` instead, and include the ``ah_bootstrap.py`` script in their project, for bootstrapping the ``astropy_helpers`` package in their setup.py script. astroquery-0.2.4/astropy_helpers/CONTRIBUTING.md0000644000077000000240000000216512403272746021443 0ustar adamstaff00000000000000Contributing to astropy-helpers =============================== The guidelines for contributing to ``astropy-helpers`` are generally the same as the [contributing guidelines for the astropy core package](http://github.com/astropy/astropy/blob/master/CONTRIBUTING.md). Basically, report relevant issues in the ``astropy-helpers`` issue tracker, and we welcome pull requests that broadly follow the [Astropy coding guidelines](http://docs.astropy.org/en/latest/development/codeguide.html). The key subtlety lies in understanding the relationship between ``astropy`` and ``astropy-helpers``. This package contains the build, installation, and documentation tools used by astropy. It also includes support for the ``setup.py test`` command, though Astropy is still required for this to function (it does not currently include the full Astropy test runner). So issues or improvements to that functionality should be addressed in this package. Any other aspect of the [astropy core package](http://github.com/astropy/astropy) (or any other package that uses ``astropy-helpers``) should be addressed in the github repository for that package. astroquery-0.2.4/astropy_helpers/dist/0000755000077000000240000000000012505171566020152 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/dist/astropy_helpers-0.4.4-py2.7.egg0000644000077000000240000063745412454670716025426 0ustar adamstaff00000000000000PK*xbEÚ2V£astropy_helpers/__init__.py+)ª´âR‚´¢ü\½²Ô¢âÌü<…ÌÜ‚ü¢7±X!>ʉǭ>=³$#±8¢ÊªO­HN-(Qð+r-*Ê/‚؉d¦‚­‚º:T®"PKu@,FkRÝÂëIastropy_helpers/__init__.pycEŽMKÃ@†gºñƒHÁƒWoribA‹‚A½xh‹J/CÚ]’Å$v·Òünÿ€³!y˜w˜wfÄß4ž?~nö0Ä ç3§{ct7 $BPl0èI¯'°€_Í5D*‚Ÿì ¢a.P@ƒð-#X'a«FFàÏ¿Ê:mš±Qh_æ®ôá‹Þ± ¥¿` ãD+›ƒ…¨×ïuk¬µÖØ$8G¸%cwЕÌvR;ŸÖùÞ¸ãl~›ÞÏŽ ZÜeª(²ÜykÚŽJUµ|/#ÒöDiÛùs^ñTy¨Ô2¼àb†ÀK¼Â)žâ?PKIz)FèªJŠ Öastropy_helpers/git_helpers.py¥X[oÛ6~÷¯`“ɘ­%Ý€u.Œ¡]²6@‘fK3`È‚„–è˜-- $×(úß÷’’%ÇMºÖ¶.çžËwnÞgod.J+ V—…0Œ³ŸÆ¹âµìåù³n­S†™‚½9ùýøôü83Ö {{{ƒ '•tRX6׆áŒw²¼Åå´R—L–x³äŽ®çF/qLeô{‘»Ä²[é@Yi+6ëÌ‹ì³#ÍJMo–úN0·®”^‘à\/—¢tÏX¥e5é?[ƒ‰[gtµ¾^U c³;|áÐæž9Í á„YÊ2Èœ‰[Y–$SÏýƒ\úB–[@ôRµ¤ÏËãW'§ƒ\VÚ8¦tÎñ<ÞiÛ\ÙzËraÛ'+nH¾ …˜³ëBÐ×ÖR§PWðåp2`ø8³ôñï¯E bÒnOÌn…ƒ^+¤ÃËÃ+¿'µ›Ÿ%^€ø˜‹Ê±¿¹ªÅ±1Ú< ·á»¯‚‚ŽYÐ;íó»Ç]”’HŽ<áÖ±ûìYrÅæ\©Ï?<|H¢€•ò0­©Ú”ž4z±® îÄ5 Þ9‘±Š»ÅôT—"z•àD¿žÅú ÈEp‚›ä.Ÿòµ1ÕCE+¶© 3Ž8mn3[¡ä¥IFÒGìpxypõU^Œ.{Ä_0*(ñ Çâ"^‡ŒŽ5 3+ rI5–+¤W±öæ:òG#” a»¾äEŸm_iG@È—òï¨fHÁTÝÆå–¢ä‹n·xÞ3nø’ø­¿· }؄ʹV­'s´ñ}£VŠ¿~qÈÜ.ØJâv&¢©¢ÈØÛÆYÞiÇ7¢r]ГšŽtQKÑQ²•èû‡·ÙÞ={÷¢A]¿}Qwim- ¬¡šDCúò’ Ê0ß²FlqÿÔ¶òzéÏ÷•mB•†ÊE«{<%ñ­D.ç2Æ,=²™£´þà}¡Ù\¢pƺÚARD/ô†N¹õ2®©˜Á±›g]unå(¡Ôœl¨ëƒh[§\—ŽKï)_m‰<šûWpY<ƒ˜©MÑõÎhO=–äÍÖˆ0üµ«|§Ê xCšû¤z[IÜ5F´=À©/€â~„„‚»¬Ü:*Њ‹h´¦ÁŠª _(AY@8…¬ˆ¶·]¬MC£PL:ÁÓ)†.òU‘{Åω"“¾N}ÚÅëiøÌÒoÚ܃ƒ"¸v‹¥u¶åx¯eéÉG(s05ïµ$i%Ás½! ¢Bs(lq:ß2ÈñM^¿8Úd÷²€ú—h“wãŠ+PÍ¢H®v”Õ.µ‚ÚD<û Ñá‹ÐBe«Kª›)Ø:Fôº·÷!Í?íܘéJ”éeBÆ_¡Èƒ{ÄßF=ÎLhºvӮē³ã¯cDéø6FYnó [$PjÏ€ÁUF PcdD'N7Äý骩è{Ë}S='÷ÔkîŒ.Ò$ÈA(|e€S'ŒZ'521ì+á•Rz œÒ¤ÓŒ)²@ã·„é”>}ö}Úê­ý‹‘°TPÁ><1ŸŸ° Kš'Ä!‰kµvLI²°x5 ¸ËÚ®M«4ú×ï3ú]o6õË4ªWZhtòêʯMŸ>ÿ6|ŽP=f6ʾ•´ºÖÕ­á~©AKº;Ì~Éžú½è1Ø5„Ùx é†aî«|ÕuÃjÛkO¦ìàû|ö ¾™s´´‚­øiýÞ¢ý¨±¾VMÈ»­ÁÛ©·å›ìß®ÓQw7»]ïQ"ºå³×:hà£]íXî÷F%¼òûoº~Ë«ÂÁ¡À‹¯ýÏ›m,HÀ3'óZqÆÒÐg¼B}nv’˜hÄ‚èи=ô:rV%¿ ±W4ÇC¦7'@>n–ç…¶CÿÂŒÇ|6£~çÒ¾y6=ðŸÄ2ÂÃlOxXÖËŽ Íœ/0Eç4D³RˆvWÂ4bS¬™‹Æ€vh¦–¹Âîî×S¯ûhz°ÕKÿ_À7&`¬Âxͱãê  ¬ ]]M£'ªÍ.A~òÎîNOûž]ÑÒ-p}m%jIJ_|¼Â™›Î’ËdØMz+vr&ñ?µ=®Ä÷÷òg /'?ìš@âÉhV¬ÐKÿPKu@,F;¤ZÛôlastropy_helpers/git_helpers.pyc­W_sIŸÙ•e[–ãœ]W.p™¤ÐA¬$G8R ¤HŽÜ>#%Üáº*e¥ÉcK;ª™Y;.ì*)žø(Tñxáƒðà~Ý»+Ë©ÀSôg4;ÛÝÓÓýëß¶â­6¾ÿÏ¿>ˆòUÃ÷çøúC*Ä.F)ÒHŒ¥Ø•Õ<»Q5Ån\Íkb·&ÒX¼„â­¤5ñŠ‹B/ ½Ì+ â%T4ï¶ê´Õ†ÆÓ`Æ&íÕÐ:åtpFšl„é¡ñÆfÊd¸3I͇ÎNT¢¦ÎîëAøžW# 9µÞëŽÛ 󼶦c|ðýí•a8þ@!ö¥xÁ‡»<½DΜJñU¶)j! á~(¤”År&Å×Çâ:±8š§„„k,lH¸¸Ó÷Ië„ÎH!Ý6ä‰'7ò0ܺèàcœ%»Ý¢ÅâÚ’±1éêa’C¹ØÀâo’q®9g‹§z`SÖ1}šš?ä–hÅ•UœN&áOSc{:ƒ"ȱ Ÿ‡%žÿC?7ãôf?5>´'ÉÀúç[·oµ´õüî§½OïÜÔ£ÑÍFíô¸·§ÇSíüMD¿š·§ÇaVz…{=Þsƒl“£BÆò¹*Q,7äj´ ¢u‹UŠþB)ºJ)Br 9I‹Ð‹˜C¿ŽÐÇgyBè»lŸ²ÔêðsPîg­F¨KëâÌ,ŠË§qe ÇÊO\® |žŒ½”Ö/»jiÕOQæ\|«t´Ó¬àZZjžÝëõ¯ß9FߣRä<Îà:Ù¿D»,ÆÑUàt!ªGµ¨)/É+Q3PL–J¼r?GP^Ãé â`I¸+×ýˆxåÏB€jè2&üA¬à·«•…jR/oásNe±š,±}IØ% žy¸t¯ µ@ú‹l­Ä8­Ä´òJˆWR òâ5Q#pÃÊ7X§uqºHõÑtÊ(/‰ƒH`N†ÀÕ ¶U#[o×„Ø «lʰ,Nêb*Íò4]ò3ûˆì»OdX¡ûXNW…êήö›«.Â×m­Q<±WQbuÐnb²²ÊJ„Ûá ôpÇ- {žöYw'qÉ„ô=_nÍ^| Ô«{ªoí˜/éõÅPjoðVÃ|[È]¦Ó¶úRîÈøR>Øœ™Ø< äçÀN&&”^ê9'gs¯S• 2ÕõêP33Åy¯—š/Ðÿé»ñ>×0VÉx n"¿±K¦4¡"V¾¡luˆbÕÏìMï•7c’Êý™¼î™(ض™žß>)Yæ†òS=0CSæ¬à5:q°jlíǪ¡7–Ô9³3—D6úŒvyVDÄåàÎŒÏ #ûÅö¼;#s¨385¤3 A€Ð›> lÑbB%ñò¸"dóà)ˆZV¼ÊÁ˜íúÈP4g@†¯·1t Iy>#Ï™?æ#Î,áÎϽ€Óy”wè#%”ÜÉ4—ÌÌ•¨¼¦Š:NUfaФ0N)K+¨1ÝC)0×Òs‡Øš&\N÷?zðÐ/•Ëcð¯'ßÚbàs¿E,Oí ?ô¿ÆÊñ¯Ê~ 46’Ä› ¢5~ïs›XNÊÉ YCçuŠø&¢– ìðUvgÖu½¬&_Ká~/ðp™‚ñX]\6ñ•“3šXZ®(îï‚tþVé,qÍh˜TJéEú cðmqÝ`íïøïJ{…´q&0ßå7-œp;1g¡)bá³…»²´°JˆãÒ…ÿkãìš)s›Ô”0ú¥eÓ—Ú¥>æNöñO¨$=éT>¹$åÒ´êðvûÇíOåè—µks âoaø%L ÔmªŽöðŠ‡Æ¹¿ Ì{´÷ÄÛ|NZÜtT}ÞÇ_‰öžã´c§8(¡}ç‹GÈ ‹úËÑeÃ…µJ ¤ZÏ¢tQ´Ue#D ÆÖ æfRü‹éPi'n’*žiç ¹÷-Á€ºEý1·G•wÜQáÔÿPPý²A¿,—ñ¦¦gMÖÑ®/DôÛD;t‘WšÑ{Õ MüŨHöÓ@Òï1”O¿ÆÜÚg·ŠÌÑ©¦Å}$ýQè|‡ÎJ§´žãƒž0.:BŠñ`mv6é{nMiŽ5bwÖÐω‡8èûÖd*UÎ=GºÄ¿3Óe®Ó¨Z„–Üéü€†ïÒ0ËAÑvžOÁ»‰~‡ÚçÏÈïñí¦\‹Öåµèš¬¡ç\Ã{ýêûÑF}]¾#ÌÑ"Â}!j­Ts¯—ÚA¯×¡pvnÐð! ÔÁò9¬êe;ô‡²Céá=Ï:éw‰% êO'6ÍÇú>‡š¶ª/5%¿ã嵿•ÿPKIz)FP#Л?Yß astropy_helpers/setup_helpers.pyí}msÛHrðwÿ ¬ô —„_6•»è¥Ê±½Wym×Ù{{[Z=$D)œH€@ÉŠËùíO¿Î@R¾»¤*U“ºµÈ™ž™žžžîž~9MÞ–sSµf‘쪅i’"ùa2_»Ö$ÿöñUÒv÷k“¬¹M2IZc’·o^¾~÷ñuÞ´Ý£“““GŸ®Ë6ÙÔ‹´œ×UW”U pªÝæ ÖËdוë²+M›,ë&AЋ]SV«G­évÛ'W»r½x²-æ7Å ¾Mºë¢KŠÆ`ËåntuR´]Soïá¿øîº^›œ†~´lêM2.wÝ®1ÓiRn¶u½¯Úz½ëÌ”ÿ'[¯ƒfÕ¼+ëêÑ#i7¯×kC_µú•išªÖ?à?öŸU»…¦úgm;loV¸@ý³1ú¯özm>»?üFíîjÛÔsÓZ(í½ýgg>wwM±•Õ-ʶþ­.n]¯ÆÉ|^o¶åÚ4cì h_–«¨}>ß,´Ï+ýòýWûºiê&nŽÿòÛ7åÕŽ°µ3عíA&˜c÷÷0»Áqæ5ì­ô~ý¹ÊÄoô²ÞlŠjÑoB_ç­?qþèÄÎã#~÷½5 Žª½>ÂbçÝŸùKnK´ÙÕµ7êvG»¹/`À¶Ã¿á×°²#€€ž8Lߘ÷{¡EvÅz8¥?oøËc0¦ëò*‚C_ Áz[^=Ú ¯1+À1{{äïÒŸäÛŒöZ– ƒ‚ie°¼3m7½6ë­qÄ÷‚ùÂ'£;œ'¥¬æf kº-Ö墎0/æ×¦'wÅúfÚÞ”Ûéu¹Xà SæaSXeg’óäË£>i±øë&»˜ê‰KÏ’‹ukÆü».‘[ Zhñ®®´Áuq ÃÞw×uu¥_ÚíuY}Ö_}}ô¨kîϨÒ?õ¥o‚9^ /aÊŸšyd>ÏͶKÞPg: m[»éçáéÞ ú;§MÑi[¢ÈWõœv“Úé7{''«‹'÷çb½c Ïè4¡«d^TI=ŸïšdaÌön“\Õwv®9Õ]n“«{ØÍ{üiQωN]!!`“‡¸Ú­Î’ë®Ûž=ëgÕæ[Âa^7«'eÛî̳ßÿð»ß ”7wšpsñzøÓ,—xuÜšõ=Ü»¶¸ZFì2IwÕMUßUÀ«çÅÚ¤¸“ͪ½xzÉ‹Åpòü®hªÌ~ƒŸ“uÛ–-Ù”ÂÙwMœçtÅË0‰©n˦®6¦ê’Û¢)qmr{ûrúâíÛqÿ}ùéׯ?Â?_¼ûã8Ôã?~~ñÇ×y’üˆ;“ü\l¶kẾë7§ó1É} ;wOg6°ë¢Zíณ‚¿ÿø"0Š{Ä@c6%H «vS yòüé³çOžþîɳ§O¢^@”HÆj;K¢=XßOêj²)擺ý<£¸)«b=)¶[\qONF‡…üøñÄ—ÏÞ§L<-nê¦hnvÛ¶XÜ~˜ðÎwð“ër~ hÚ*Å ~K'æÑUòCþÜ;‚>üúœÀÞCÓ²ZÖ@É¿ž'?@9 ÅbA’”¹KnÌý]Ý,pGpëéxf£ÄJ4þ…[{ÞÕ8ÊÅ%À[˜eÂ|Ìr±LøëˆŠÒþ—ÆU¨p;À/œ—¦¾1U¢}[:Yí]Ù!/%­ªaZ Ò›%ÁÙGŸÉË—tx>ãÞ”°u¸"ÆÂ‚‡®rY‚lZ3v´.·&UÔ€¾¦\Ð~ÀµÒåO&Ôx»k¶uËG¦F`¦ucÚŽ,qYìÖ<$x0:þÜ[7,ù„ÉV²iQH={dIô1uŠááÑÿËËza&ÿ”?'ëõíf²šÏé/º[³¢~0ĵÅ4JÃwónbV¦ÃãÙÛd›W 4oñš[ Sœ_ád‰šÑ §8øƒî î[‡*@Öo þó Pò“;Bž‚X– [¼Û¢l¸\‚»uÑà¾6 Õ"íl  ] î-`L4Å´ LfAÛÅ{Îx„½£ñ<º:·t;¼6 }‹ßì*-ÿù÷ÿL,ÁLEsWVO'ÿrùxâoH:NÒ9r²td»^>R¦]o}¹Àãì œÏ¦z$<äÐhÌ-®øAúЫȞµ„’²cú¬ŒYµÂ†6;àûpy ]±sЋÖ^E/_ÒõSƒàÎçÑ#ÙÓä嵙߰ÊÅ'2‘ î£Æv™Û±`$ôǹt­˜¡•¸Ï“•q\h*_g¬C½0å÷=†¬ŸM‹;¬ªR¾0 Âuá=ªemñÓKG_¸h84¸E€‰!Þå!.þ|Q0gí×áVp<µ°¡ËTmäxæ³qÅ,ò}ÓΑ£]¦ÀÏ=,‚NV’¼„¿à-c>—]ölä&†z8Ÿ¿1œèÏÀ.ʪw‚B„)5&§CiWÙ¼ÑYoß¶=/íXŽ;±gdþœ}‘‰Á¿GÀ²A)Z%¤Uò´vøuóÖ†D=ƒgâü !3ƒj@K[e5Üõ×zGŒxQÓé¦E¨ã¢à4W„Û½¤ Ér)_÷ ¤&ÿG®ÀîϼÚ6òx(‰ñ ²%M±gê‡éÍnö¹J<{ Àð¹ÈBdçô¿åâg?õâg‚A,_ú§VŠûu[€@¾KJ’Ä”Vï Ù”VuMBԪΓ_Œ®½®wë^ßeUv(Ôãq¥íž£¡Fo²ù­zpf3kÉ™Óá?§@½²ÈÑl˽ƒþ Ѐ$ÌœŒmtl@‹AJõÀ•ËpÔšêµ¢RòOŽDý›(µfœ)Nj²ie©½GñepÝý|kC£ÁÍ È#;hÔñõ»TvŸ1 *¼D[x}¢ cTveSÁ•á»7Ø$Úc6¾]½ë9WymÞíŠ5kc bâ¨Ã{ pÙ¼ŸŠ m”õÞÕ «sA¨•A2&»fi‹¿7v1E+H!Ó"ÔyÚ5ŸÿÍâÞƒéßKÄ–öðm{>€ã~Æàà.TS)ʉ´eƒ ì¹Êíeä+[Ä´îe@O¶„…ŒéêÞ2‰¢QpѾ܀)|ëµ á8àíÅÏ8á=cúWI$sh`’ì =Ôí¿CûŸ“Âz äœÇé5¼öq#v‚áó¥+Ëëžhû”‘¨·Æ³eÑûGÞí9ä’ï“‹t2¸éå8i»E½ëÎ}8o>¼^¿lw £¿ánóƒú“.ž^æhöØ » ¸†ã Df‚¨Úƒª…ùqæoÖŠ—ò\ä[Ue¶»Íæžn%µÀdΪò'ê…:²{Èñ5I}õW3ïìGó{³£Ãe =<_ïØ]™%¾ÌUèÁä› gŠ´ä¾;d¾¦›-ØJŠ˜ÁŸvUWnØprËTžèÔB/dýKG±cÀ7 º¢>”†€pQxµðù°§ß2Ö¾-Ñûå4ùИɶhHì2î¥Håä ˜–*ØÔÅU‚×'©ååR Ñ%¾ý.fú¡Îƒ}ξ¤íHµ›Vp±¦gx8·Ew_®_eÈ$Šfu :: ]+´&ÛëÙÙåבÿ€áÁ‰aƒPöm‘ì&o'™ÇVz—2 DˆÔ«œ0”ö·¢¡¦ˆà¬wSgñ[⋎Ñgäïdm~ Œ4bv§É[¹Ü»F+¡‰Þ&AÒéZ³^F`ÉrAC Ž)ytþÄÞ“ R™75»Qk’ÚŠÌj»Æç &’ñ¬7fÐ…Äø/á8ô€é±+þŠàËÿ+ù¶Žù$Ê}ȇo.j}[•·¦ò0Æ0ÄÌø¡h€ :X*Øód^^ר‰£4„T¬ð¹‘•»i^ÐE­‹qWýÞ6EL‘ŒB"ª;bNm þ²>šôoX+OeädŽˆˆ Ô/ÃÓ-¢·;š áG|VÀ>VÄè¾²ëvd ?àþâËçYŽŽ°%är´q‡õí#³Å‰ÿÒET¶Ix~„ÐôÇ nyñL®Êukz·#auˆ*¥Œÿó·P$ùo¥Ëo'žOß4é„ÜF9RÚCB–ø‹”ÆC³µuEpÌ×åñô=ÒGþ¿{—ÔëàÿïÓÁ}4íÛ92Í?n_dÍÿò êÍ_öÊê³çÿþ3uÔôé>ÃoÕ+ÛÛàW†ß¯Müú…æ2e_«+0’¬a@œðÚüð®X˜ý ¶? Zõ­œx[Ñ»:v¾Oôxë°ã.0¾°þH¿Þèé¨Co° o,‘œ©VVYTï½OoÙ£6Áؘ7 ãÈ-ø ³ 6–¯ýcm®v+€XÀñä ï²xy+ч¯î7ÓÙInx–\Õµ³ãëŸ5ôE‚Ž¢'PcÓ©}–·a(õ³’=\ø¦‚mŒü@AxݲÛ›•ÚDñð1ñ ˆ?hÕDñü"¥Qà8Ej|æùuÄŠÃhÿ\YˆÁ_N“÷øò “Eû˜ÃÌr]¬Èëün›VTE´:›ÃWÛ¬ÌMN|‰üVÛÝÕD_bP®Ó9ŠWNs;$6 Õ}&‚£/¶¾D9ÈÇ.=T( x²CGˆ1.¶®P `¸õŒçÊcÉ4üõ»séF°sŸâºDJò0)¹™·ÆÑp_4ãÍÍ´1¼{þ+¹ªY82;ß¼õþ,ù©¾Õ'”Êù [3ƒ’·º$â½ÐÍÖT PžÑ%  õ&ìcuš¾ò¸2pý5¦­×·p:³7ï[ˆ † ghôÈ ­—ż«¾ à?;nŽ>ð7‘åMGÎ¥;h¸A}#;}Pû´M¬­¬€˜FœO¨çìÎríaç´½ŸåÀïP™FË AñN¶òµh`!*zXVbÂl¦«™ÍHu1ÐÂæjÙó"!/=Ùƒ>ë­üÉ2L8¹œµÛºZá­öº‘xÔŠ$'П廮dr¨™œjØn¸Ú½½%̘®ÍÎn;;§É«=H PJ9ì?vesƒñ …õ£Äÿ¬ šÉen왊ýtÊ"'¦&´‰ ¥ò<Ñ¥áó–Ùl»ûÜû‚¾>Zw¹gÄv[ôˆÁWQz¶@ï¼{¸$|šàIù2Ç)‰‹ø&êÍÏ}W:ñ^àZø'!ù>I•ZÓ±ÿ $×g„€`)ßKÿ1ЧD$‰,¹"ÉôXè`D ^¨MûK}+«}€·~Š!ï9Ûß`V¶Ý“—€)õAC'ß[wlü¤è žžY~3%×pijýÇþëìÏt¢÷[*Qúö^"5StG«ô;]]áÓ¨sRbïd yÔ“œ>þÜùPXýЮC¢,ƽ&£×ìmyå­Øž(×ΆZàï_í{ |õýÞ;‰"WúŽýþ|tá±Õð! ~,nŒG¤éw1¶™·#wÎNNOm­. Ÿ°{ÆiŒCU¸å"É]Hü@±$·È}~Bó:Q8©þö^À±s:‘»‘±Ž÷IKôgyŽ_+õ²8M  P¹¦…°Ór‘à\ù Œ^!ôea^/Ô¤X;”3,‚¼KÑ7O~…ÞêwÖ(ͲàœÌ{C—ƒµiý§!h›ÛáÎ €îÝ‹ :Yš;=ø²#€K³1N⑇”b±`Çë}mîTc§ê,ÛÎÛ?Y (˜pxÂNNS4¥icÓÍ Þ Ü(±È›Üu·ˆq2&maä ˜¦UATQR…뱘í6Öƒï5÷•‘¬[Ã[oè¿/Sà]e9/ߟö²P; ®*Àñë \{­ï>Ž@bœÍüñ@¼&-ÌQ°$ß`¨€éıÁ´ÖûÕJ³*ÝoM°¨¼íÚdè@b¼ .ó¿ÆO¦_RðDÿϯ£Ÿ{o4>¡à´¹î¶´æˆÖõº¾c¾,·; dä=tÕ.jÂóôqÌKM8øúÉ/dÄc¥ÞãÖh7‹v„9 xµó—Kk°C™AÄëE¹ñE,<àÔD˜›ƒz¹Ï§˜Tr’.®p?"@œÝKÕ/ìX|ù„ºÞö6"Óãs#Qæ~nŪûA n=À:¤YDYÈ%XýVÈßS6ï}ùixÓí½éqÌ€çx¹¹ó& Å]˜K|Zx?Ê/0³@Rj…§‹Ÿç]&ÍéâŸÓ)3PñVSdȆDêƒ4ƒp°Cõƒ{×x‰¡RåšÁú£>:Úîb}\&q‹ ØG¾ ÊìŽÑÛª“Yû*\‡¢çjî H=tóQkú±7ƒC­åß—jñä2k°ä¾)9œÂ mù„ÀaXï>8”zçWUøÙo«¸°Üùà…ï§m3Ÿ¢3‡D[Pþ·ïS¨ þZ—U¦,ʆ|@¦äAÛ Ø iäaÆQä9bóyÒ`‹¢º°´†Ýqu>{8SP8¤æs¼ÝïN:¯‹J9lð½ø¶©\F8 7Cš_eOÇ8KÏ¥m¸Åê´„¿S´¯UüQ.Œu òüôgðã1 eSk›â‰`PÓXã fô?DÈŒeÓëb»EÓÔ’¹ô‚4_B*š^÷pôÀVî-<‹šEöÝÁ}º|wÞC߀/#5´áö×ý3¹<©£ûBì)¶èðvˆPïí>(TE³X£ó£ðŒà3Lh’©}R¡?‰ÑÈÏÒƒ½3p€Û‚iƒûZnµ¸8ë ×·s“‰hWõy4;þë bqElIZí6 gKÈÙ–‰‰Â5Ô´xA‚ 2÷Yªv°/L♈'Ü™«íTñ{õÒybK‚8•ƒÜmnÖ¶U®Àqæ}+Ÿa*íá…ùœ Ô~ˆÊÞ^ÄŠòØ[ðƒ»7f ¯5臔H¨OòíýgÆöË nÐ#ˆq°7»ŠÈt.~‹hC– ‘"÷¯8E¸Ca01¸ÌÍ«­w JжÄ~9š›pYŠÓIâ~Z’ðÕ̇9ƒþzq6ù§KºDæi]ëþ ó @Ÿ3Pœâá ô=ÉÅÌ®wUÙ"V3¿ghL†SV;3ëða—ïÀìJhÜÌ´f‡“ø3Ÿï÷ÁçÃ?o1`¡Ÿô%E`Ñ[œ7ñ–ª÷ô+‘¨\•üݳ¯ÉðZ`Fm­›Žy|yþ5WXÃÈ=P¢ªû>Ä  P™;àÙf~Sïº<ÕHƒÐð8óŽ=D“êÞgúaÔ7ïÙùšÒå¯ß½ýîÓÑ;F¨âj{%@D õ®¸G“‹Â…¸¿‰Í³àÞˆ¢ ‚SÏuGU²¾Le/ŸÀ4Ï—ux㢯-¬Àî³7—?=©ª'±ìyñæƒÏ iÔs<À:ÄŽÊž\6:2Gdàí\O"¡| ñ—ßÅrJ8”}Ê(›½ÄwLš!lÀy¨#xðPˈ÷+ºiÇ( Ä„^wé%Ûå€8œß5%Ü9©°tØÿ€Á´H¾ìšñ[5pÿÚÎ=ô~yú]óúèÙìIš£žHëø$¬”;°¿.¯8&¿Êp3Ì™ >Ëß“!'n>S‚*ÿ±f{¯Çd:”`¿mcnËz×®)lX£(*ùŽ”øÚìÖa¹uÅ)3|»ÇT_³;ú8¤\ò‡,íÍ­ÁƒgÎÉ·(Fwœ˜IÝ«ÈØqA6 zÜUþ×=Ç6…_|aY^ÔÓIšxDA ¼¿ýfI‘nbw"pM0=µØø?\œ]ú}ÐÆÕ`·è7ìÙ³—‹ÎŽÃF£1£vÏ)qÇuèx¦É›\RâÀ·Sõ¼Cæ‘æp OàÖµç=j¨3L/—ÍÅÓ³DE—¹ä„yš8?` ø¬BY8&N’•á{WÖKG&Sö±ØÐ¤Ù Ú#œöÛ‡÷‡X¿Ä+’—è!ʵ“5ìëÃckÞ® WA¼Q¬ëR¤J×Þ6ê/nx{pÿ¶¼ê£ÿ­å‰ÇvZþ­›€]ÿ×íwzÐ>àú¶òÊE6â÷Ç6Aš}óh¿¿ýVÆs*!Å­³tN•ä´ÄÒè6xŽé›ôYPUÕuxb ÛÝ•^À%û$ñÍ ‚ö­ñ]0P²Ý6õ_É냅4;ow™ˆk>I¦Qò Ó–M”²@¦ m„©™¿`äÍnÝ•[ ®ºùÿ aö‡Òì“°Ðý¬"n½¿åAÎ3@òJPûè]‰ n|JaFßyËǘà_ [&#V¹î$Å’ÓùœLLäg+†-gÙ GH æ'N£…ùþ·.­š³Kј°S<"e[³¿1²Z²Ò™œˆþÔY®r#ZX°ÿÅÚÄÂ>†>;Ãè¢éØfu‹?çí3¬¶‡ëÊÉn¼ÈðÑ¡=íï™ÅmÞèˆ9’}nPq¥7dr·°róáá-×äŒw½gwëÑÁb Ì“)L‘»$¥Ï»òzå;.°C%ùƒ9U—¿ÁÌ‘”¡¸h0ÉŠüÒ¯Xc’Ž{VZÎiWtŒÃ‘9ʇæh«BQÃôy úÅðhÔë00?RJö­žG}^à¡jðå˜c“ÅýÍ­}l fA;K6è#³Òu^±Î­s °÷ž¸ß²Ÿý]2k°Ç]%pœ’} ÂLGŒ¼¢õ™KF-à°è+—„MÑÉah˜X±YØ`6Þ]èSjæõªBYA“©ƒ:¶âjÒ®ç[aS!s‚ÕkÏ‘üãºë¦Þ­®®8ë‰ø¶‰¥8 É ¤l;’,ž-“ Ü9Ûo\­!þÈùgÑ qUaœ‰€Ê4Ÿ¾#£ÛPþz-L¢ØÅ5DÇW8m–fvÍŸ”ÊÁmœÁ¾söèj_S’îºì÷|ÐÿHÿ£Ôêgênë)hú•“,ÈobÑÚë•ò©:ß]_ Rm¢HfxsR¦òÙÌT†F›âÆHjQu´îTÜ%€÷ÞÎQÔýS?#i)‰^PŠÄ{Ù÷à9Ÿ0ì“„³`0aw¢ŠÙíÖu±ÐÇl½{ 5Þί‹I¦w6Ç·dà{Ksk ÜšZ)U!9¤·÷ÛÒÏß?‘s·¼Ì¦rÈ75yîûYœ'/Öè¾’ÜHàîe„R£ÊáC(wæŠÏΟb]´ ú¶ŠÈVVR>â Á¢©¸0e!yô O’çí Œô ¾¢2-œ Úˆ3R7Ö5ŽvM²LîËvÛ`Bqä6칫ìm€‡–.üʧE‚失zSv}§Î½f =ÁM‚9¢ìQÌR)Õ+%Å<ÜÂìðFÃ(`ëÜÁ”sÁ…¡u‚µÍ‹Å&’õCïÞðâä L‚ÊÎf%4Áœ0+t2oŠöÚaú¥à`›Úñ(¡ê2nÊ_o:ÞmoúWfŠ®½œéìùäm¢ Ù&ÍÀyrÞ‘,'}‚L}]ª &Ò“Môóž…¢ºiîÑ»8…Õi~MG×€æV,@@2_´áyòÖ4‰¸KÒQÚÆ¾ø‡P äßÉ#7sl78Y©› §åÎÙð8–µk£ ¿s(ý£7™ ‹ê¾»¶U”æ(Ú¹"+ù|¹Òt 1 %î6ØæNÓ—ã:"§ÜC4Mä£õÜ”…eF<þ€i^Xá¤Ö‹É(¸ß'nä†×[†ѹ¹Lò³±G€;¨^&¨BÎ{Q9l•6;Ž«` ±&çI’#WÊ,Ý2u»¾.vs‡QÅ$î]w›5†5WÁ‚fqýÁÂïö1:w'KK $Qì@,/:±^Ï%”8tBûUÎß >±`lîXc(bG‚)WÀÌvWp`‘0HöúvÀœ•Ù`^Ó›wÒ5påá¿ÍýÍvó÷­Lpž‰6¤( €±!ÌÄVtc½ô‰îôÇrI@lƒo%q/«õ¦bôk'|ÓaPVJGžÉÓ˜Ñ.Õe$ë%_¹€csRƱ`uò,p §Ør Ÿø8ÖôJŠžÜI¾D™$Ü¥¶žç< dÓ²“$ÑÚ„ý“#þrìñôp œŸ/W rßU}x£æ(ÝMÂqÖG÷ç¥ÌÙÕ/ƒO0¦ã%¯Í~¢Ê>,:qõ¢Ø–“UàåÒjÂKëò„U_ޏ=¾àªžŠ",]]ôÇ›r›x½øýŒóçTKtÏjQ#’Hü£;ÕŸ%ú Ñ®Àd'WM}×bà¬ñè\ߣW»r-d‰E"ý“̉HG‰Ó\i/¾®FanÌ ß¢5æ vG ã—; K"GÇïúêGÈq^Y÷ôU¼ ²ÑÑ^Þ8Þ8¢Ÿã·ÒÃÃ¥…)ˆÕ´1Ÿ)â?—¬9Á˳‹ÿûÛâ·_./~»»ü~t‚žæùÏïÞ¼|ÿêõÈ¿ ¢‰á'ÂôQM ?ì@EK$Ò:ò#Ù6U=õ0´¿"†@Aó©RÛÞÖºµS·µ¡R¨8öŸÓ—°Ž¯Ç¿dº–-É”JQ™±m9BEߘŒë&%8Šça‰V\û¥£ËŹOô2t h©Že–ø©\?ûý“c@á$"‡5ü X!É—¸ç\®ñY~qÀß0]D–â>‘ñÆ9¢Ôb¿g°D…5›®1&ÛÓð°¶d¾æ¦€¾óVh;Âñ“ŠcKÅàN…倯! Ñ=ä!€Ÿ=ïÇøÑœ2ÿ†/,©b²­šSÊP6'ŠH§ôv'0XQjžž_³H”xl`ñFŸëGb·ÜõÑs(ýðëÀ«>ie»f™!äÔ)($´.?‡Ÿƒ~{ë¤A1fDn§È(I˜JÈ9œÎðb_˜9%¶XÚôõ¢F¯8¹YPrF¸ê[±ÔAV®Lè üL˜Y?¦Œìx?>¦A†û|cØßˆ€©¾{e‚®cñT”µ²'w꫽_ÑÉ‘¸;&y>ÕœŽ>f6q\œô]'=ÓùS´)¿³‚ÎÄ¥âžäùpiŸc“ßJï’Â.ÄÔ-ÄT9Àqû!'ÜFÈ/HCµŠ÷ÇT¤/àDn¶1Õ"( b­H6ŒQDpòý~6jû=éEÂåR’Ÿ$LÄc]ùÀzi+77ä]ïVQ÷»úŽßkZ¬¡©Ê©58pòI)åœðÒ ÖókŒ'Öìu º×gB?OžtvÕá|£[Ð7.®ZBâ€Z„ÎâZ2n‘%•¸iúu ˆ&öŒîÁ¦†v2È[$î‚2ƒšû¶¸«¤z§–ËàÈÊ]š¡œ{óùV‚‚B‡c ßú)YCÒ8íE®Ò·¤ùcn WG7y–ÿpõ,¾{ÑÒ¤Ïꈰ”º>Ï…´Ãµ<„ǧ¡¤0 ¼"¨ÁIb/"z„ÅQÃF)Í}_ä_4‹=¥âÃåüÿN—C|†®®æN¬àT&ý‡äן~ús¯«Kð¯@7ÚaÛ±þ«ªaÊRré™i‹Údý­íÅþ÷ý"GCõŒŽV~~Ü—‚á¼Ì¯Q¬ýÒ6Èé¾k¾×nãÀFå Ïýƒ»ÉI¥öAXÐH]iBØçáŸc=íçòßý†^Òy¤»„=Õ]ÃÒ {Í´Iˆ¥©~Ù§±gl?²WiÊ×­?R±tš¼X¯“‰ù®O¬c êp‚¨ ¦¨ú³°;‚G–{hZ`}Vë ­¹„©„Fis˜ÊÎߪŸ‡…\¯ÑäÇE©¨0:>{6NÈÖk>Nž…&ó+ª×ð¢ì«˜¤Ü%?á'Qì9(Ðà^Ø1Å>ösúÊ3›;®—zÍŽpÆÙTgt”f$HC“]õo&8~‘sÙ{TD9ÆdyÙ6Y|õJQ÷kÃPÊÁkAìþ¶ ö¡ue€óÝê«z¹rÓøÜ;À×reŸ½â/Ð˱¤œSÛ'Ú’£œ'pk1}Í€5ïÝ2ákǹ°`h¾+8çƒ<ùÀ*Av¢Ÿu†}&uÚbR› ¦dº-W庨ºïú,4@¶÷—ó Qvž|ùºÇÔÚoù[ê툖*û-=ûòõk¬Õ£iR\déGôS§œWŽ7ÁJ1› ksœÎòì·ê˳¯ñeìMé-Éëw¯.G.¸“ôT,ªËI~}ÒêqÍOµÃsµ£¤ª0µºQ.+Mó8/¶´\¬,'­'¡…¼#wUûÁ/#”_“E8­Nïåø£,E0@hAǽìІ*#±åƒdÀPØ?%ˆ‰¡zm!Ö.žœQVqá¶oê>Pøí›úEúý?~zõþçOCj좦BsF*Éeäü³ayYºë–“ß§1Ñà‡äÅ !üˆ_ÓEˆ†«~RÔòÐ…rŪQB(ïçä`íQ”­åé7°i×ëÙà\ô÷ïì!“¦<¥R ¢ôÓŸ^üùÍGÍ FVŠ®Ù™t¿­ñTìqEÕjU^¹Üº¦¸Ux1FGVvUò0£±xj@Òhй}?l Á$£Hmܶ üñ“_¼yûúÕq3gª÷¸Z0 d½D‡¢g8ÉÚySÃ]²Û’— á«A YðCÛNÞÜoE³ JÂȳ4Òâ:T0'áÄÀU]MþÓ4NU}2Ö7è,Vö­:,¹ùc郹à0wëÏâï`'pš¨·ÿ¼3xô”Ï=í=¨Î²hØxˆ.#Ž%¡¡O¥AÐnp®1`-´ƒc²¤Ø¬B²1Æ”*Ð$§퇃æ·]³&åþyöä Š{¶íÌ µŒ³Ì3û·>“pèÇЧ_â¯ø’ÈC‰}f6ÖzÈù.y³ªêÆËÄ'`x¢n‚b‰x8OîBî  Ç}KøL#úA™Ë"ª k½JŽZâÙÔµ­;˜cIž ‡”J‰c7–M¹º&3¬-œ2\Åx(0ÐÉýä)5Ó2Ž3.ì 9;'–š—•êx"¤ ‹ouž€„îKp\-'܆V ,½\¡Gëf«¶•„_VOìß^¶†°àv¸’˜ä„¶ofµÃ(x‘ª5 †®½ÄøQ­J®€EÛíãû¡ÌÝ’¹³7ã-n]åPE>A„×¢hsï(“ Ç6‰­ÿKà8­ ÉUü´ÁQÙ)½ÙäÍÌ.|¦¢-;R©Æˆg8‹B¼èuÞìãÒœvʾGy×ò¤“||kX  }ŸÔÏ.9C5bѯ›G{t˜= È øðã"†‡”1Ÿ>pLfôF’ðM® 9Rß”·D‹ŽxõÃ1BƒêTK÷Cc$?žÝ .ÉJ'øÊÁŽöà‘ÂkÒÉuºgÑò;M5 ¦JŒú¤=[±7cÇBa•D1ùz³lé”r\ó™ ˆ¯ïÐss,G‚HQÛhðF²ªëieôB*v_鯵X€|,îáÉo³ÀÚM׋Ñe#‚Ø^£ ý¡ ö*`PÌ’¥öáA)ëiŒIcM(¢·±…ÿ6«ÕŸ÷=ý>-Öeájþj9—þf€\SWYøûxš#eKe»—+ 1%­Z¦åŒI‡FgX¯,Î~FÅ„dùŒõëm„éôc|BKÈõ˜¨"ªu…[áW^åláÈ‚,>mŠö“œj!®–̶f/ð¿ ÉØO1Ôн]mÇN‡Ã¾ÙP. ¸ÙæådˆÆ$D·ÔùCwzt¤'OM®JPcù:ãЊ%Lc¨5;?Ü/úßê…¶³YåÝÞâA8£²$Õ™& «ÁošÚÍk.X”`>— ˜þ¹È°ÉEйÝ%m´–ñ ê½H©lnìÿµæBOçÄ ‰‚ï¿O8T4&÷«lÂJ‘Kç1‡úcnØ3©éMÊ«ß*H×{Ðå,²§;þf*¥_¾Æ·˜ûÒOœtq©"ùÏòº‰é|§Û®I3'žaˆ“ŽÖºŒ&ÅÙ„,˜,ê Q|/ÊGV= çö䊢ê1)vÌ$9G_,-ñäsH sÞ9Zù DYéY€ $ )æ£i»±_µ Ð)ïVZÜ—WL×_‹Î¢UG:+1stóÜ^´ÐíÍŠ/;À`°r‡9ý"L„¢é (½c¿€Y¨W>À*‚.a)§½K¾©êÒþÙ÷yI¼Ç>¢E ±¡ÞJø7ºûm³áÅDàî3ùï±UÌ ž|𣿀ˆ…ØN}[b "(´ ™9‚6Q«²õ©ï->.|bçh+ xI|þ>MÂÓÁ9¿µôê–’ ÜkÂN1p1O¼ 'æ´Éã$ÆàâÝñ˜¯j'= Sç!Äè)ÑXCÚM0X(8XfùVX3 ‡ª p„¹ïKŠ'[—M©@Ë‚3e¥†•O^í&¿~„ýƒJ 3[sÔ5qtÊÖD%kAϸÉã›K‘Gé·8'±‡º˜$Æ~×o¬?~!.‚Ðù“=¾z…3(FŸã$E0{²z¦t$$½ðXÜÊõ~áÑTœî“½$%®žaDƒ$†Îý“<¥h©\¹ !f‘‘ž”uPLŒF!»‡Ÿ(=§~ð¦å{0kŸèV%Ky_%?•ó¦nëeg«)…¾¨rDÞ­ƒšJo¿p£ÊŸê{W„5À!?}üóËä_ò§’XFoÚŠ6G„\möì©m×ù–=6í]ïšNäN½óA8¬æXçY¥F¦À’s]š5iÆ6ííÜC•”-‘*$Š­;ÈI,€+ º™Âª]ÃOh¥óJáú&³aw†ˆ3wz¿’íáÌ—î†Ú 9 ­S®•åúФŸ+ó«ÎÀ9Æ_œ¬5ÁÊ},(ª´géR> ”Š»e ›[ãÕá'è “HÎÜTìªzÓ»/Íæ‡e›9üc4Wþü1ãK¶Ä·r4“^q:’6…â~»õ}ËüRÔ¥-ðè‘¡n'Ú§Û0£¹8°¤þë£kÞàÕ|ÀôóÛx3?V-m°ú€9‹Q<®DžøÍ£KRp|.ô4è´§–^>MÃE)Ý RÂÊœûˆçe˜/ßLj2bª0.±ã'ø6z†îßLÏÀZ¨9†5/«‘4­ôê8ßn½Òˆ ’í•fÅ . rò-Q'Y0upZ]4bÛ5»9:ä±ô1ãIÙSC”Ù9Ÿº`À<ØŠå,¦*FÛ±õˆaÜë›)14Îmäïï(äöËJÓýRï^]ªeõ€JI¼šÓ;ëe5à¬{š|CF/(¯ ú¾m¡ÿÃÛH™þÅ-÷",Á·¬¨$Óe$>1}xAo… [¸kZÃQ˜a¶n9LÇ*sÚªœçärf”>%ñ²-A޼/ƒ ÜI[e ¯ˆ>Ã'Ãõ#©Šrèq´>ÜêÌj¾«-¤— ú èA“T&hÊî-³¦m«¨Úôt*US¢ZlS¹† öùŽâ<À)Ш|ù'h ­Ç0‹P‚ø›°2æ— §éTÑÍU¸Â*8 ½*:2Í´W8F_V4ìMÒE’« c@‚ʼn!D=½PzqH è<êžËN]湆EbÅKC|‚azåi¢‘*>ì@=!+‘ 1/ü*J€¹1×ÇÓ8¶ßz9‹(Ý;gËq°g©ÌM..–«)¦¦—è„ù¸Àâk µ%VcL%Á¾‹äÞt½Â’çÞÒF9»t6û”ËUÍé­†ª\RºN†èD_™©fU8Æ4;¶EW¬trõâRZ)½eCÙ¬lݘ8€<óƒx9´ª^ç¡  ¡­FÚINûlø}˜<›lƒs2Ògkú@kÑ×Qw¸/ý÷m]ß´qµ6Ö• ZW6¶%ÎË^ÏÉ~Îkˆrໞ7«®­ƒEOf gÚ¢™KJ¼pùT_fÿåW—nÌÀë‹©0Öÿ)Ý’XI`?ðM߯CSŠÍ”m¼êÆj÷•l»Öâá!Ý›'  Šx¡BðCŽ\½c bŸùÕ%Ãò˜ÑsêÔ‘ã¨8"iÂìÿÜb´Ó~ñ]K?£èá7Ó³N'ðL~Š}|Ç é`6ŠnËÓäÏEû"ÿ)S Ñs½^Ñ<6 ±Cùg@€ÁNäZ3PEá@"§À%ЫgV&™kîÝ'k8Zx²|“r0Z´ÀP.Á‹ÂF»Çq…þзy ²; $;¯0/6Ñ‹¬š?“4?OAß©IJ9Ž ˆÙD÷¤iÏ O‘ŠÃº—§Þ••ÕÅœîZ(ƒ·boÑÊ•=!¼u2¸ác*4:ÅÝôy¼rÒ’aȬÅò€CNâÁBm¦ûÕ¨§®O¿Y_Ÿþ#ö؆E²=×RU#|_ße}d@áý±ÉÅU{Å-t€ðŒEx(îï¤o:ü»æºÂ òb xB_=ö(´Üy“ëš NËåÔ†pfzÐÆäNâÙÂ~Á¶ÉŒèéåO[ÎÆš« )(ÛÎR^^YüµÀtÑ*ØÒ V…‡HM{ÛÕⶈoÅgÉÕ}gBVN?Ä}¼„j9z5¨ú4ZÍMÆžp×PŠá’*qÕ¹2”«is%e(£ºÙšmX_¼— $ÎE6”">nè$áßÓêLênϤ`\Ü’ˆÁò†*f‡âØ5yäÖ’ø©åÖ»bý4ùÅ™éWuâ“UµpZ¸ÂJ³îBTíÀå|'ó¬M`úކDN²kcGXy*×{M:Á 3Ò“J^Rfyôû¿áC0NÌŠÕ%OÈÄZY(øÔ‰×½8–ÓÜESƃÜîWÊÜîЧú_Ïï…Sr" ôü·½7:ý äLßýüÓ‡_§_úùÃt|ð)E[çQÛxDøOüí¦ÿ%j«°ý0D¸Òq:•QýaܼŸ¶¯Ã±e„sçÛ×™2ÇJ6ø7çxáï²À‚°OQÞ&ø%ôõ ~R[¯g%ŽŽž£7ú0¡fO)®:ká¡E+:ô-êÊPˆ>B±p„±Òóݺ°"A|X?²/"»ÝuM¡OU²›´­Käj‚‰(“ÿØk6-÷¶ŠÇ©”Ä™.úäDZÈ4Nʺ)"ùîº\+”k~·[Ù‚¨/ïlò³ÍÆik®Œ­Ýø”þna±\¸Ï™[Ê€³1ÍŠXÓŠ¼ìÑ‹²ûÞóNÅ,*®Ñ¢’á¡‚–ÎÁ äƒØ`͉Cï®Í{Uù;1-{Ôp†mr¤k‚ì ,ªÙ‚S§l ´. œ…·º¿+ä qÿÿÜgÿü‹õfXX /«=Æa+=YâDJäÂýn·#rYÈ<ð(j™l1ü.œ5|œ¼œÒlÇɳ‘«b“vY™êE³ÂJXp°d.·èØ{Ñ·rÏÅøŽÜ+ƒTó­ 3BÃ(G£øþ­œÕè=ôr†+ÂÅñ£‡ýÊ÷UÁƲÞ)^_usŸõ\{h«T#ÂO»Ûš&Æÿ˜¢@G¹BĶƒ±úSs…¬ï®€Ý¢‡sOùêÉ}‹Ž'á¦ç. í¥zoP’f¬X©]Òî;+•ÎÑúQ¡wƒFéž§ÐgÂ}Òˆ¦~ÆœÚîgÏYÜÒ‚ '±HsôÁ‘³¡4½.Vèù‡N››”ðÑ>HÛÎ÷¢‡8±ý{ÓAåè£0‡VIΜR"AX“ýíA"¼uœ Fv/^Øo½9ùŽõ¤Üï¶¹%h~ÇÀª ?¢©ìu GLIÒãŒx„7¢Ç2Ä“ë@t‚{<ò6”O7mïü™;jèØÐfgÞ’=Ç&û¢å÷” ôTdî ßu‹³Íqº)Ð 'ì@߉Q2ì„·årÞÁŠ{ÙuE¬pä½vgÿî .ƒýüŒ'G5¡ù O¦—AOãtò&=ÃÐq·xMÞâ·>réÛµûý;û}:y…MtQÏŸñk!éW!@Ù;ON0cÍdÐ1ÚlÎlá˳¯'šˆÆOB“&iàÁÐŽFcµ PÝ­ó}—ç4¼-·^>—¿ÀÖl¯Íz}Žã=V¼z&\gàœ I PfÈÉnJר—¤Û}࿸؈/ž¢¡‰P.Ôî8ø\=»P½s«fä X®I*¾Ë½TœØý9Ã|B®CŽe{m½D9Qs/¬½×‹ñ÷àoC•K3æ"ò«„1#_þB:¸ð¨Õ^=Æ;¨Ñ-y½<ý.ûA óøñÜæ4Î ÿ/t›µ#\¸Û‹Aèá'}rïµzè¾÷z†ùۀܿ Á}$ã‡<°jÌŠ‡Rm»ÈÕ–ãÓäM—òÃóœR¯SÀ?eQ%HΟ þñ;{›Âõ7j¶¹Q^t'èø{8ŽWp0¦e æJÀ®WeUhYÞ-ežýøòÍ›$SŸ²€û† ˆ»lðY|¹Š]KÆ9O]Ðÿ 5#ÞÝ%e¤N6I £±Ë«Vö#ãO¥²U]á[ûÿ´±L䘇u‹Eƒ1Ê®Ÿtg†öüâìù%è0œÐ¥hçe9ºD+6qçg¶Z•@ouØSäeÎ;%é)dÅ’ûoo–šà9_fƒm‚YÑ/W=–w‚sÑㆺɱÑ9\ÀX——j;'(ß’$Pa_bHc ¾ †»y½÷†L Uîöq$”€ôQ9€špiPˆzŽATU*{¸­ÜáZÚ Ñ*6P¤Mf˺–ÚÖ4iwI‡µæ8Õ:ÖÑÆ9áIO°oôp‰‹µI\Ac´q2’ç ИR"²·j.ü*›ŽÙ_Ro`Ì:¡ø?øh’j,˜ ¥éhÓ÷=VkG džշfÊp…ºˆI¨^Pß…¹Ç®)$ ‰ð[ç²Hš]°ÛÜ.M)Èß`?˜Xí]Žø*#Dö£°cV"µ³%ÒņÙ° £G HÑá·N‰ Wz¸7nË…-àK¸ä~‘6eÎ|¹šýãÏÁa}Ïmª”…wêÛÀî=x+BûŒ0'Ë„‰ $d­™Ê1±AgÅ%÷(ر›¿¤–¦$G?úzDΉaéî·:½õhR·>ÒЈ¸ý`¡Ì¨læþõ æq˜jœœ!*v!Q˜dÃÜÞ?O„×°ÉiÀü/>û콃‹W.‡ }v/ùðyiM’?7Æ/%ø’©»g{\ì6›û0`P6j6J›4½tÎ%Y”¼Ÿ3´âUv[Ö )G~>ç^²syÃP°&QvZ3ù`âZ=#~ý:O¶ÏÒ%Üœ×SÝ"›ÿ“&>k!f½ž@‚?Ô"lÀïéJ:>÷MmÚB ôFM˜±Z(ó}P ÿ~5𻤄Ú?†æþê2¼·AW/Šûý?£oBÙæèÖ æx9´—,ÑP®$}g””By?/voOR]0ÕÒj¬v—é0X-îX§ÅÛRfbjG|@¹®¾g.ÕñëÊg'r7R›ÃBkú—Ã|2òyM/—?ªt@³”ÏéYò`Б`3´==úPKu@,Fd;I|ÎDù¶!astropy_helpers/setup_helpers.pycå}{p×yßÙ½¸ ^$ø‚D‘«— J(êAÉ4e‹&)™Ž Ñ J `Ñ‹» à÷Åݽ`Mb:‰5»O5FÕ쨴µGÕ÷«Æ5{@žKª~P5©ÙCòÜ«ê‡UcLÍŽ©Æ]jö.IíSõ»U㈚="Ïe~¾GÍÞ#Ïýª~T5Ž©YOž÷¨ú½ªqŸš½OžTý~Õx@Í>(σªþÕ8®fÇåyHÕO¨ÆCjöayVõ“ª1¡f'åyDÕO©Æ#jö´<ïUõGUã15û=ïSᨪ?®O¨Ù'äy¿ªŸQ'Õ쓪ñ”š}J5Þ©fß©œZQEgUx@¡ ª3x:$«3³çÔú]f8ŸV³O«èÝ*:‡,çfš{U1zZéWñ˜ë8NÓQ×Ö2¹ŸQ³Ïðý˜ªŸW÷ªÙ ÊÑ¥£ôKTú"—ÞpÙKÔλTtI-?‹Rc+%ÆöªåçTx·ºå(çÆgÜæ½ö“¯ó'Ñ„÷ñó§M¢!µ|™ë¨‚½÷«E¥¢Cªò *¼G}Œ`÷y囨ðßL©Ðã›Tx/ß\Qá}|óAÞÏ7¾ à›i>È7WÑÓðêcŽš}Q…Ç9ñ%ŽóÍŒ OðÍ5>Ä7/«ða=¬hXN"å–R/ÏΪpBE“œ:iS?¤ÂS*çÔGlê+<]§ù‹×Uø¨ŠNsŽÇlŽë‹¿TWÑ~ÿ„}_QMZºg¸=s*|’o>Å7ó*|§ i ÎªÑª®ªð]œªðßDÜå§¹ *ZD¥Hy7ç_Rá{8[M…ÏðͲ ÏóÍŠ ß«¢¢Z®sƒ.Ø5TxQ…—¸Æ¦ ŸåÜ->Ç7m¾on¨ð²ŠîáÂï·…c||züyÂNÉ]ú¯.Õ¯Ñ ;õÈ«¶šiPk&^à5;ù(öZ ^'­Õki-J¼…Vìu’È ;q­¹ØŸDi§}j¾S«‡§ÚAu%X¤T/] R/ˆ#ä\èÔ½´åI·Úëô—*^]jÕ£Éþpä¸K—t˜.Á|ÒªwÒ¨Rk´[qšQZ›¾’V:ÍjZk5§Æ ÈŒK½µ˜–éoµÚj´kõ(æ§d=¡ö/ÔÇdÜO—‹µ$Eó“Ú¨âR·by; ßƵù^IK†òe8wº/Ÿô,},W ¾zi-š jà¤^º\h5A3”lIHÈã ]¦é«Õô¥(Ί¡&ÈJ´¦söÙ¤özV7MNÔë’°'K¨ÔkóY¹8Z¤/FqöÍ…Z“*âIŠ’’³*ÎËô\¨‘󡄺ڬFé^þÆÍ ^ šžjP]¢|#”ºÔW*ÉJ­]Yª…aÔä¬A¸Ü¡/‡;5£¹öH:'á//7©Êõt‰àÎ>'í¥Zs-ëÌ{1[Õ³Ói®4[«M¯Þªõ(9D¹®´’¤6OÐÛ¨ièÄæÀÛjFø“.E^Ô¼Y‹[͵Իĵ€Ê$Þó*çŸþ$þ^¸úò•KÓt{~깓Á:n^<ÿÜ¥IÏ{–ƒ¦­v«\j­¶Í#o½Õ‰=Â4jO¼zÐ\ìÐ`w}–ÚôÂô5/‰"o)MÛgOš'XžŒ£FÛbÒ&i|N=úÈéGO=òä©Óœ¢5–ÒªšÐý¨¶â8ª¦õõ‰Vs¢T'ZÉÚl£Ö êA»]¯U¹ó§j˜Ê*FƒˆÑ½jä?R mŽ‹ŽÚtTʨh,>„:5 çhO]µ\PØT¹§Ä±MW­¨´¨6\ì0›5Ó|V ʱ£|¢%-©å^PË} Q9È[˜/÷«"oN4áË  ð€mh­­6uñú’zÅU›=j³Ð]R=j£ n¹´¿)]{9«(zKô†•°Q¢ïßè{7>£èw†{=ŒŠ(1¾Çáçµ¼¸r“ªï¡±B_þ²C˜`yƒ€ºï8 Ÿv²azëÃpV†áÔí‡á꥔sWnü C¿3ئ¨ãXœÉOBë÷èãwƒD½0J |o>n­DMϬRBÌÍÐKVk)–7ãìf‹ML yë¹Ýò.\ðè Ñ@¯FIàòò lõ”ëHÚQµ¶P‹B¬T¨±A½ÖŒNz͖׺Åq-ŒPc;ŠiÃiPæ‰ ÎÜîÄíVqMÔ4ÎD-m5é›¶`@]\:õÔ~|²_Cd¾_Íõ›º¼äµãõ¤‘`ß:+Ùñï!.´µ>¯Öô®]h…ÑÄ㓞ôêõ›‰Åj•ŸlQêk´ÈåèKv¤±A®VBÖùVE)ʶ)©™§}´ Ìzóë^u‰°Šl²2 &s¥AK/̬`ÞR PàÕ õ¢þG'h»Ê[åÁ3U,Ôbz_“ùhµXJÊîÔƒóG v*¯tè¯{7eûâ*4‚ÝÒ“ S)w°dÈÓ%s.ãì‰I;ÒÖ¤ÀÈØqÎfˆ—ê•|GÈ&ep»rùÊ%f±Ä™V±8 ±Ëm®ïr3ŒÖ„ÿF ÿ¨ý´ŠšÔî¤ oÿœûÇ©ž ¡Ê-9÷¹‚³Ÿ&ªÇeÙ¯“ç¶~L¦Šek4¶}*>†I ™mø¨ÉpÍŤy¢ ¢þ€c I¹ÅrØ3:¡G#žê 8…_f&B×­ šÍOžUÎúaÎ0€gwƒ|7Ó¼‹fxòZ_ žêRZ8Cíûà5Ê=Íó—| ˜z³4È®v//4ñZóËÄMØí²ˆ¸Ã¨^È>"ÌCÛ.m\f›ªi'¨Kþñ–Y‘­Ø?Œæ| k­{r&»'ÇȬ„jjÐÚ†n’OË–pçÚ}uuFtVJtB ó›T–•fЈjΖĀxù©qÈCüû ~j5#;ùfZkˆÉÄúš<í ]ÁÑX¨ÙŸ0¯¨Ê›B!6BÚ44° oàóþ±+ˆ“È`ÖÂHIW2LÜ–ßkPñùTº' âu6ÍBŒK„ÿE ƒï³ëíÇ¡ÍV±m¬ŸÁn£zFh… ”÷ÛÚ¯ÁÀV´}ÓØ ®cÞ±Ðýãòu„Š·A…æã-à1ð(2x ;–kp €¼Ãr –Ü¥BÜÃ}šå#gšiõ‚Ý.F¢жJY¡e9ß|d)uq+$ÒúßdòÎSlëÜ-ö•ž##i‡¸Â–ã£'=«çd%A†ˆm}z£~—§ËmÀ› Ûõ …òž&4}«Abk±âRÓ©£dÌ„Ë+üG-`ÝÀU[„52Jï€Q΀ÓïZ^¸¢Pø"ݬßÓ….°7{¶Ý!¶ýbêX°à2GwŽ™÷^¨÷À×ñNÀòqÖD›bc€¢úV†’øÉEW]¼Å`o‚`"fSxSQr5¸a7غóÏàžHê•î_SÌ¢–´.,-ƒÈ®ôƒ»Ýp CùSªHk P`I× œšï,£7DÉxÖ›oµêÆ„at­ÕN3³ÉµXÀ1´(¬ï¨B2'½gƒz’C4P}­ÖÓ¦âV5“\š™ÁªYº¥Ç0g"š­ëû•`0< ÌÅKÎLÁ¦Ç… e{Y;\&ñg-4^}»‘…8ç£&´:ï^0›TIeHsj|¬åËÚ+‹F²¨e“Ìç^f+ aa}»˜^4„uÐ\g¦óËmô `ªYX¢R1OhÅÕ¨GÜG^£ü-ÄV$=™Ö ¾_5¥-F©%/Ë׎ßÛ¶†G rÇ·¸Ó1<êž‚S&þtÔé/–ûœî€{Øv„Guõ²æ%ýA€ýÍ­êCš´ç•=ݕ̋ÏÁúuºÖ/8[Y§Ó´”§ÇY ÷ÝN&´ußñěԓh,}±V+2ˆÏm•‡˜YÏ$"R‚C{}n’–h@Ëêc®%f)nù°Þ¼Y'¦WíòssfuÍÍ1?J»‚Õ+ÓƒQbÍ8DKK ¼Tòµ‹1%/¶õ¶è²ÒZJà?j±Þk»2“þ*ÕóEËcöîss¸©?’)yÍÕ È{WÅã]N „¹œf [pX‘QTŸƒ1`œHˆ‡æîãŽI)še–,„˾HæS=!…‘ÄðunƒQ>G w½”æò]Ÿ:÷šÜ•)­Õ×Q<õËS¿<í¡’Œ)¦bKÜ2˜/ùaç¶@eñGYbÄ\¯·VÅê™kí±› $’ƵŠËY[h~¥y¨zˆLšaÞ›>j-ñ,n”!1©5«‘pF°³‘ÄË(Ó—¨1ëàåÃÚÂBÄ\Nµ#!r´°¬J8+ ²†ËL  ÄF äwÙݬF\!Zw­Ž'Ù·DüNÈ1 B³ ;n¨­ZN”sB“t/&Z a2Û“zˆ'³þ̯›lZÜŸQƒ†€‰;M¦À`çZûHdÄþ]ÚñQöEG •ù,ˆæe˜è›¢¹é´ŠÖü–Øp:ZõjsnðB ·Y «]CÀÓ¯ƒí[’Š„Ïvʵh×·ˆöwZ B=8M&ï4áñ%&õ”XJUü°³¾_sêõ!Õæ9Óó¥Â²¾%ª/phD*ÜÈ‚ô„É ©Öô5³½oŬŒÀ}{ýëTÏïÙšXϲó€sØ¡ýØ9êtœÁBYÌÜ~zvÊî0åâU3¨·^57\«8uÔÚEG¶ê‹×ßéð†,ë!膂tNßÃøØÑ„l'ŽNêÑ™jk_á-Â…aô-TþÛ92·‡EH¼ãÀ#v‡,#«k³W5ßar±åtüóü¾‡Þ»ôžs#—ÒöÕ´Ö6x‰'¿«n´•õÿ9ï:Ü Ú!ÎÑ»¬€‚ßílôvç€9û ^ë¢CØY6û´-Å2->.\€Q培1ªf²Õ]sºV7z£ê5–¦Ñî¦zÄl–µ@o?èa-Ðû!˜“ÓfG/yK/®Ül”y7\݉ƒ¨³ÒoºuHmôc{"Ú£ÒÃjƒ·Izüä„Ú¤ÔòïÙÔ:ý0ÄÝ#™¿êʯé*ïâwìdW¹!GPköA~»Áß iˆî¡=O²)ŠA1#Œb°Ðšq•XcÖkµ¿øÚ×¾ÆådµöW¸ÿf¬ÕV‡¶Kf­k´G_ðØZõ‘MÞe%ë´Ó›buÍk c¶C¿úèæ¤ÉlìC´t>/‡<€¶ëÅZêU—¢êJ«“N2ÏêhËÍ?‡¥¼wÛÊ-F´]ï÷ž³²4î]°E'ˆ'¯-¬÷'‡¶Uà=M½º7Þìgôûë(¾Aþ3‹`¤sÅ1õù/M½piêª Á›‹Ìñíwâò· ‚µb«qM›ÕêAÎAŠøJqþbD38Ëo}ðãÌÏ~Êl3ͶéªÆÜµpÿ.‡kþwœOð· ¯« MÿI3åydÅ4IÏ›žð~ôœOD Ë:Þ^œÿíÀôô¡ä ª%ü>Bx}ñ^£…#tWröÒuˆ0ý>§äÒ[ú;R(ö9÷¸…Áø´» ¨¤}bŸ#VˆÇÜTÏa§ßå­O&ö5I´gÆÖÌn‰—n+#pþq\þ%.?‹ËÇ |Š]š0Ö,lºezÅ@ Êšøhžmp~ ï£<°ÂŒ±VèûpùSÅÛ6}ëTÏ/`˾ŸÚ3ì–œQ·äb ÷¹Ã÷ï{w¿c~†œ!×Ê­MÈ;3ЈŸÖŽ@,A¾HÞɬ ‘£&íʇ¬zyJä‘„9'S2.«eΕµyVØðÂf ‡š­b­ÑXH‘áY»™IÆV¤|Ðcˆ'Êu\¼ ‚ ÀU…µô%j?–ç\Ãþ:ÇÿU¬U¥ÿaDß‹‘D'Í:*â1<:[à»"ݱCÁ¶Gù"t­s «§}BVCSBx…L]ÆdÅŸ _€”7>T1%b0 ˆð+µT¢•ù¿€¡d3Ò½]kDK¬r^?eæK«T¡ ¬lLvAҀϿäI+4D‚²2ÂÿfcÕ^ñ©{Á¾®òâ··e˜rX·'hL ëÉõ7þßÿqù…îyÄV³§©¾6¿eöý_ÆåßïÎxâSÁígÚÿ\~íë7¿˜Ëë[æ÷#ùùuÍüž}sóq˜ 8Õ³‰}˜tëGÛ5éϽñ¤;˜t}S0`PÐÈù6`PêƒL»Ùî_L3¾*Ð"î¯70Ô]cÂØE'xϲk•,v»Ú°µÌ¼â¢Ë·vElsßæoí=`/^H3}¢xY.hÍ¡cX6ÌËÅïPWn¼CÑï̆ cøóŽ©ñ¸K^ˆX ùÑ—wöL@“ó†Æ<~즭ÇdŒš2ÐìÅ˦‚™¶Ú¶ù¿®Œ¯}§É…Ú`$,ŽauMC‡­*äʼnÿ›JoˆôNœá%SQggÀ.LÖ—©ž¸Öga€HÄAúñœ>7'¬· à÷’<ŒŠÚ‘7vt]ˆ%ÇtyZ|›kÌèÜñr7¦ùõí˜FÈÁ/ÛÖíâ’YBÃú-â) V1å<ä×+Saks;¢›â=Zú³Ç7dâpègž;Emª®¤Ë`!P™u%ªÇå’Nê)dn%k7AëŠÀ„…- [z!µØ`c1*×ök¾=ìÕ㆑‰:R|£W=­¸‡ø'úâ+ݹrããŠ~g¤ Ä,?¥•¸PÊ *~ÀÑ%s%‰§.„²jóc“\sˆ¼Û‹XnaÐæˆ-^¤šÐÚý™ôŸÃLȯÍÒàØ.~&FÔol’¤ÃJ¸ÁA`Pë²Sêq„ë^´F“ˆ÷zn©ãΆ–FµpgKK“+0Æ ÝŽò|7äk\êΕåmj¥á¢-eÎ{Ä®ÅÐ!ˆïŠŽ›‘õý¤U³ÍML`Ìy(Iˆ –*kIü ¶Æ:©K™]Ö 1s°Îš;¹Åö?ð4+iÇ™º¶¢¤y<óW£ZÁ#H’VµÆ¢6(Õ80•-ëÖ0§SÌ™Oðµ’€8`ÑŠÑ%Jóêi¤mÑžô惑n¼WÅk ±Ðë$ú H¶AÆ’Y*Vˆ¿ q DE°Ãµqt~þò8ø_6ŸòQ”™TjZâÿŽIˆ#"å«‘÷B‘ºüc‹/Ÿ´Øð‡pùʨÖYª#v""ÏR1Ó CF«œÁ0,Ê)è}‹CÎÈ‹Ûv@ö@’m‹[ø“Js{»€l?Jõ¼d Mu°ì §<ì]â•ídÜ#ÎÑ¢ƒ„ˆ‡QÚÓÆÀQ÷Œ”†é¿©r!ZÌ!FE(BfsUÄ”9!@xPMˆç’ñ¨Døµ“ƒÌI ]H˜7eˆŒv¾âêX@abׇU8nTê9íbËK:mØÆøÌaYq¹¹¼Á;ej+¢ ÌâçX­›z¸²~år—Í–ˆ£º7^ΰ°L´10déï’|ýÒ÷IÝ÷y}jÃ.‚\± [«Íz+#-"Å×aÓ›"7–®Øf#:!YVBû!qMA5%Äïr‚¬O‰×i†QlBã´×ÛµIqÀžlÅ‹ül&sŽÏŒÁÑt¶ðjÑÇâ¨ÊçZ"+cr¾N•uµ÷ÜÀƒúj°ž _¨ ]ŠõëÈ[æ©õ4& ´æÐ7­um´bcSÐ$ü\cgÇÞ0FÀÔj¯ù›µ€kÚ“ž÷>™>ªT¥žpTiR e"¼$X Ñ0Tž5!á6õžÔ*é\5ÄAí•é`ëÈôÅ¥àf-³ÕËÃbÞ;¾bZšÙ< HÆdRÁ5<^‘jÃÌÅm!t;Éy×V’35ÌRŽöd-\· °Ë@§Ö¬¥µ.å°„ºÛ”êŸQ=¿Ÿ‰›ÅÚ¢ rÎ=Oå;˜\0{ìqfxøFh&˜DóiöeggӀΜf>¦‚E¡ão ë÷Ÿ•öÓl#-†J¤ C&(bV†-DÊJYvahþ+ÕóG™ÐòæœG»l-!MEiu»á—‹Z5¸É¡A¸Ê,$ìà_áÑ„² ë0 &:v­¥b³6æéh/m%µ´¯‹à娡c}ubÃø¿aÆâ9+–C‹#Á§ÌîiÄãN`y[¬'%1³P+¦™ÙËvÓÑ–mˆ‰Ä:aލh…A»6±Ø¥¨OL¼kDÐŒVP2a ÔlM0}(}ä7“G@ž¬ÔÚ^îÕI/b/ƒŽ‰(B hN¶¨†â›{A•NÌÇ­U˜-¡ÎV·Åèµ…T,ƒÀÓ™¼q g¡iV“*—Ý^V D"%ˆï—tªˆ—²Ð¡ñœäïòé•Éñ}ø•ð•™ëzeõúÃ'¶ÓiOÜ–NÓ7Esc„¸•Rž„³A'¬MdOÙ@~ÜlÎÂd`­¹Ðò¿[˜FG‘ ߪHeÉ=LgíðB wIràƒM^¹eçngØ!¢äÜ^º;R`P‚ÇxŸ¥o*Š'(!;¥ÕNñƒÆl›£Êoº ,:©h’ÄNÀS2†i_ÖF¯D”H:ÍuÞ&@ìÉë¹lÅ®¢Ó™+Ø›eÒÛ‡¬ËLÀÁ4o¿Z> ‰°Ír.OY‹Ä7yelîQëã°¨J©åÃH§û°Œ›•E8–w{ÐÒ™f¯ –”ŽÁ.½voz4Ôæ ÛÀÝ£–jroùÛ£÷±oN?È>4ÜS·TáIª3ËÍVì ‰½Þ§÷ªåûx̹6JY[UéýlQ÷€N$’ñTg×Õæ’6†ÔØ&½ÍažÜ,¿T%¦âº›Ï Lj¶ð“ÂçnŒàµ¤fI3º‰¦!èÇ¸Š¿Ï¥”åJè‹! â!µü0¨g€ô¤ZžÐ¦€fê&Uü‰BzJ-?¢_î#ò)§S_ßâ›G©Xas¯ÚØ«–CEË#Z»4#¿OmŽªô µ!t<ý‰=Æ-Ý¯Â»ÔÆ~fßSYÙ,a…[û]PñÏ0gÔò“Okv‹Gô;…ðµy€KÅ :÷”ÚnàÆÏš«Ûu!ØnÓp©ï4ìÿ³E ËYÏñÍ»dé³y¢ôsܧƒ¹wQø1*æCÈshó0oO«ÃÒÎ EiwxŸ<Ï›w鮄÷«ôÝJÚƒ²ZW£1ÄFýz›d-7a&=•3óß—t âïG;qÝoYÆQ(á¶CçSbÚiÎÎRó.BÒ È5¸ª“­'YIjlÒó> ­5s›Â$kÍ%_7²å芧'›?Í› Ë*+•…‘Q¥â‰k¢×b¾¿Ÿ©äm±¹°4T‡ 3Œ–®æ¡í¡$[Édu 67¯&q•þÞožØ–‰ø£IŒÚ¤˜©?rÒ{ÕZï°=ç›.,eù» 0 Õ])Ï‹.  n"ëÈkv«dËQÖ@¶šøÊ lS7ÙÜ|[òñ™f‚6?ûêæfCÙi¨ÑÙ}ÆF' ó]‰Á,&¹ ÙÎö¿zz³ÿC^¸xÉ»4uñú ˆpÿ]fï¦Gú6Os']˜x*AëûYÇ-Ô.¹`Ö&9ÿUÿüK—§Å+îD N¯ÒØ€!1d7k& ɳç/?é¢%O ¤BSnáÈ Ýé'Õ¸E<1ÐG™×'&“—ílèú„ReNA,&>Å-èŠRaÀÞÊ×'¹wà•™eƒßI~Ä„c=u*™º »a„½«F÷(b}Ë>ª UÞë]^l¶¡›dñ¦æT/vµ,7׈2lâ/ä9Ìñg —±/Lc^yù1†]Â&ˆ— 5 û¬:$](=¦ù2²ðCú?‚‹ÖXa G9y±ñ•XÍÆ‚@Øv½Ø/„Ì'liýc&¡½²È>(À RˆbÀÂ* {™˜SÚ„ÀL(T!^¡ÚM„…ù‚,4Qö•ðr..UÃV¡•×$VG¼Nc„Òö yÙBö³f!ÇQ;ö]ÿC sì .(¾8L †_D¾§ñöݸœ7]˜¾zñ…¯úï5Ï3Wb0 $êCÛéÏ(­‡ÔRV+‚(8ÆöV@‰%öú¾B˜AÂæÄþ*­}$lîCr9>fHr‡=Èô‹:4åƒ^ØÉi¹±Î–Õ²-ԣ廄úì ›D ª\§¶ëáášô?ãHa%JM½ÔEÄLÅÅM( [æ&Ò- [2¿Oš$0B;íBÍ03*÷.ÙÔ\¿/U`Ûã‘b©0\¸Û îæàw¿3Rv T†•þ÷•œ½¤wE÷°Sî=ì º^qŸsŒµ®Ã…cTfØ-÷”wÀ¡¿û˜pŽºýî0¥•Ý]ï.”ék£8'á T7ýŒ§3Z(;{Ý‘_ÿ “dI§»ÅYþ_"íë Í’oiù…ô¿ŽDKj¼XËÿÞî¶TKÄ™½Ø_(½Îs†.‚lY™Á¢Vfœ2HZ;3òý‹S—Aø:FݱÅcàí_«@õ.Ö*ª-õ³ºÃ)9½=ô¿@ÿé¹î÷òãp˽åQÖL‘(ãâcFµ¦ãÆlÊ wû G›_†ÚpËá}^‰ %¾kÄ)ƒ¼X2f¯J{Î.›³QèwšC %ÏåcÚæÔ „{c°ÑàèŽvàuëJ-BÿZL‹®õþbµ„è_´vaíÈ¢¶ €%í+LŒ0l,aùMLˆTìÙXÖ\ àL|þã\HŽ'^#JhGÍiM&ÎÞ @¢‰ÂÐ*JszˆÈö ×ú-ÝÍšœ_ÕhÑ„4ZlòcL3x޹GÇœ"&m,fþV?’2&Ž-Óúþï*Hevmü^žo?ÅCn᱆€#bnö©µ£Í_Ä.Sfkú”4«)0)Ë:øK\VNÐèWkwC¢ñúûÔ÷jɸsãsù‚=\ðw¸`€™8Bq»Ož…âÇ8°ZN" ¶€ˆˆo<«èwf-ØÒ¯+¹~‰3Àe^ƒÃ\|2–õ’©—3u°úör¦}&Ó£ø‘âé¨þ Ð$.}kïQ’ =˜‘uìUð ‹àYû0×"!¹þZ´1¨ž¾ñ9g&=ÌqŸúùeÉ]caõÅëMÁ1ÖCêAü ŸeWãH)á€:³ÁA†Îm ÑŸ"ä÷gà/0¢ÎLó1 ɽ%Þ§U¯K|Ä^ж%rر°,ò€ï×KQ£wûÌè&޲C0%1o+Ñúj‹ÐNFcŠK€6˜GÈávEX]gô1—ÅÁáÅ3—³ÖÕÇÛYsÝ< „ߢuµèÈâ*1#ÍÚÒÚrnN¯17—«œkbœôŸ¹£n&V¢BÑ·bä².§Lˆ,`7q40ÖÀúóô‘9DœŽ"cÁBmk­Ê˜å3刂¹ýbd“3¦/!q¡õV›O±vE­ |nHt;ƹ‡M¥5/{¾˜?å c~]âNê¬Ä˜úÊuØç€‘"3§†²[k.X†«;a tFv‚ɬ)&D¥–z˜Z˜eTdÚšœÕCƒ}!qÌãIšßZ8=W"8SW!T7>8VâôeEÑ£¹9íw‘ˆwÛ‰9«—¢H­¶^ C­f+Bb[ãi@²U•· ÷ò ÄæŸ´gìÎég¶V½u¶,ZO&8óvÝ/ùÔÓš¯Óª»ÁË6[<[¾¼m|·÷ÌÓÇ.Šàa>|£‡5]Ž:²ØÃp‡ÑÛ>_ækº¶ì›YôEƒ•¬cNíØÅâO¤,¦n]‹„‹šÕZ”èmð`&-e‘‡1ÎRm¾éŠM Þª˜ó´j@£˜û±-*ë›\ËÎõvü<–Q‹Ÿ„ªÂ$é4D»ØÕ(Æ™P[“h &"q× Š:Ñ„WÙ>æìÛÕ{œYÞÛÈ8¶¿þ~eÍp5Õ1@Ë5’›Uæ+O}àüÔåg/M_õWØ¿ŠË QÇÞ£ãw^P\Hí‰Î>ø>¶€úªta Äÿ}Tr•ÀÆÿ0hDjˆE¹¥ë~ù8 ËÄ2¥ÊßÁå»py YæpAêN.‚Žˆ’ ¦ÃD”6CÆ1~K㢦?¼p2Ñ ž$Ò;&k_Á%i;*ìNÛ'\u§Ý^YôÿÉ|P™id3i½öIwï)\>­vEn÷"Õ=\4áYÆKŽþ).d¯ùAg¿þ‹@-ˆÿŸ{܃…a9î*îs‹"ˆKi˜rr N¯þ±qY¸`ä{këbvC{žgNé….[3¢£^—Ø[¢áôaH:^O%Oü«ã^ŽÜ%¡9jãKÎ^E¿3|š< nΈ²;·ôÉÕ$„”¨\º³öJ^©šs2ÔƒF%–»³ð S#¼³YSrÞŽ[š·^‹êÔ¾q*Vé$ Ÿ8©Ï £‡9sN¨Þ±ó‡rÎéR[ó°ˆÑzMÞž°ù£ [³ŠÉ¤è3»­Þ$pÒ¤¢C-ƒÛ’"#vÅðqƒ9° ö.žUOƒ[¿/*Sné.¬“ˆÚ¶^4‚ŸÖ59eç° G†ó>Í2œ#<ÓÚ·f‚ˆ‹××Ô+í÷€`˜ ¡$šœ£×@|¿Ž³\47ÌXlôpg#þå턈s‹®¶,“ˆo û~E¿3Wn ʹárPË7YoãÛ@–Ž4¦!X41ã:Z'¼îìø‰¼eû[v*þ–-MëIš’…æ í’l€ÙVƒ\]nÅʵ®,òЉ»¶Êô@½v<0ÍK«k)çl@Ó¸S…UŽœ='²K  ™?q¶ëƒ:ºº ÇëˆcÇM‰\9ëÁs‹Ç“(G¼•p¨+fÒžÁ§CNŠ_“'@æ‚”¦‰±þöŠT†ÌžNýaÊwµºN aí½î˜³Oè:'µuoÛ)8kÈeÛ4WI,Q‡ã ¾ÓâJœA9ì£OÅ7™—ƒ?nªõA}v(N¹q“йxŒâô| %OâƒEÙ<ŸæOô˜p¥5},þY,½ä§Ù"¯‡E?‹ûiš“iú°v±=ºõt­5 ë¥f¤²ãöÇõ™¤ÇåˆÑÆäÊ1ÌúD³N…¤}ã£rØ(̬@íÀá™s«@­²›¡zx׺ªÚs¼á€*qôN¶®@4Õ¡9'E«±Ågk¡,Š1šq|1g èC ’aªu” … aì8h¡£Š)Y .Šï²ÍèÛÜ÷+m™/þn›, —݃p]Ø(þÕóYÀ<ˆRÕ[ ˜Gœñ~÷°S`åg¯+û{ûéMÑåHC*g2}·£tÜ™E$®UEüô! ÿ5Ÿ¥pˆ»ÿœÆù؉û¹"‡<=lÁ"÷%óa¹×xà5Ïšw},«)è4P×-ÜwÕÅåS[x}Dõ“ÀáýLgÿ<èl¼Ü£_2Ao™V˜!0@v´ì£;ëÛ€ê9Ðc¢ú–G¶ïàXÇ×Ü÷¡:â]ZÑ=ÔJeœ×5†7‹ðÛEû©í·Ì¡á$¨>Ï11ÅKÅ]!µöB™;=Ctí¯ÑEóTó.éœaïutˆ×ë3Lëé8?pxŸØ¢ ­!#dQíԃ؈/4âAw_ôOéÈél!“dçÕ!+ô“ÿ=Ž~/Q(~Ôn«[XøW½éêVmžv@’fJÄ£”ùw´Ôy¦¿Au?Öc✠ìsJÎël kK$“íAh±n‰UŠ´hB‘&¿¥¬È‰YÉ ž×L¯²VΞтø#‰5Œ«¹Ît\^-J¿Äì.têÝÊñN;g¥iË ZÀ”SÔåÈ?XÜ´:©·ÚŠãuT²ºi52}½™R5§k¨7íð;™Ù5õÿŒ½— …œ¢&–·Ä⨠O!ýDW Õ®±F%¨m1óB·Ó¿ [ÛéÉàWæY¦zLKGlôw¨„ÿ½ŽÞ"+x£&Í¢Êpx5ÆŽ°pZLü¿¿+f;þ? j?Ð£ÃÆ(§\v,åfC!&ÅÚü)9¥î•ÞáPEc° ›a–’n‰úMJëŽr½ÄXði«¼ŠW¢uÿìîôšª«=6HÓ˜#ûE·8gÝ-«nÌø%3Ô¥Þ’SîeèöÊâ„DâºØ²¬I”ã²1Œ¸sŸ Þ1Â>#VØgÄ û ÍD¸‡#óáŒÓp‹ÏZÛä äK@ÖŸ2á¨ù¸®”MkÒ‚¸€»¢ãZ;¦yë¥^"26ˆÈà#¸@g”g³ÖÞˆþ&6 ½|/ámxëGqW5|°Èb‘M¯8ÐÜ…–|hYo:«&)ô«DÔø ¥a¦ô?ì„X×u0×S~Ëî[©÷ûÕÚ§3Ó©‹×? üµ+næcÆé™“ŽQQ–ð3‹È–ØHèÖ?vp¸J‹0ÅI÷óá*#pBï6ê†v{gq e[>€\¼hV¸uGTwšÈh`E›ü\Aã~>`+šœ-ÅÙ™«EÐ7! CÍìL=XD€è䑵@!Û¦§ë¨½$;À•‰È¬9õVk…öøü%'Ín”©ÑYWß&ö™Ù®Ã¾{S<”5Åé’¤ä4&5צ¼ÝÚG¦¿µ½}oT­Ö&ëcdãˇá ÏVçgy/Ï}1·µkC!l«;Ÿe*’·fë$]˜§@fþlæ- #.áÒÜÙ\— ¤äÂ#u•ÔC²CI3Xw.I©;ÛšY„q¿qkKNÓÒºîBˆ+¹pû22ƒM)ÙUPÌ´xŠ-º‹‹ùN—Ù¬þò³á™ø½|2šÀ¤Oâ1p™9¦üØIúóþŠcòÔ™ƒé긼¸(dzä:'é/rÌxVOà|V˜ªWeq¿zz“iqOˆÚ˜êìQ-k×¥ÄUwÒ˜ªë9G8}fa‹31°:ÉÚ(áø,|º9Џçe®{’:È©âª')âµ=ÙµRMæ¤'½‚èW/ßñäÊMrOOJ™7ÙLqmg‹¤Z«ñ@<ͬK ¶Ï5Ç^ï[æ@¾·Û7–dà Ë^±þSÑŽcvEŒ›Dp‚è¸þIwY¸Þ—,Sâ9f/G椵A KB9Œ{ÜÒâ÷qv4Ëå¨#-îÍÑváøã†¾ÄìÃ%ßÿOÊòÛˆ +~«µvÄí⸾²QzkEû¹ÒøÿkwÈfMé ‹/ƒ@© êØag¯sÔ-ã|Ô¹ËÙǬ4dŒá˜ê–øD»ƒÎ~w´o”hºvb=ìȎͱ’GذöŒ¦¢pØ:¦œÒçl‹<2äÓ9à­€Àêöôg>õVÁqnŒQkÕ‘ …ã@ãy>f¤’¨ßí¾ÅÎMâÕðFÂâá+f® †|S[ŸÁ¦wýmj´›³)F+en¡ÕÒ¡¸¹Ñ™Š^ÐŒªÄã››˜È÷Œ²ú„tØÊÉéÑàz}¼¢ÉÈA]_4î³Òc cˆõe‚ºŠUÚ)Ǭ5¬+áAŸAv(q"ˆÕg-˾ç 3JÀT5!Ï,ÛÃç­ÉK9³}TûN²›‘8Ðõ™QQk{È._UïNhókÚÝu G_uͳñJéI;ù©Í[lŽ ìš‘¯g»NM6…-PßgÛáø·Á`¹;5ÛÊ9ŒD;nݬAÇ#½Ó„ï@0(íX}WçÞþpgª‹š^Ñ#*ñë3"j‡Ù{ÓS¡ÕOC²"ô*ýéþî¤Ì˜—á}Îì7âVß/};µaý –9>p`‡vï’uc)ÒÔš‚• pMwE‹9'9‚Ç»êÆ³FV•]#8|0‘£”-aÎ"ǜۂY¼6dèEæ¨{K¬Ñj'Žs!¿1#bJœ;¦»Ò^ÔÜ<&C~ØÑš>‘^3&§¼®íÞ¡áS¿fñN©Ä‘üoT¹¶À©,DŒš.¡àÞƒ8T¡‡xOá}Þ> ÂUøW‹{ )”·á¸„œ•‡ù‡‡òK€¿»YÌX‚˜”Iò»½ya§ÑXï”Ói–ƒ©ó\Ðr™6j¬â6›*>ÞA|!i†]ËÍ€æ,‘d•àµÃFWD¤,MDÍ›<—8¦¿ Ú&ä쇩96«fuè‘ÐOûßèh39iœGÐ/?sÉjbÔa¤“æ9I»?Í¢äAÛâ<Íœ´ëOó—À)OÈ›°.¾s‹"=Ü.ÃÃ(l߯Šg}DoY·8ÊÞLó^èƒÄ¦WÇ’ÔN³:¨—£®eá²Yæªgqû©ÙQäÒÈä´â“>[0éxÓ¥DÀÏ8>ÎÂRæ\“øÉNZ<¸‹Á;ÿ²Çï„n†D‚ªºàÏÿëÖ –è†Aÿ§»_îŒüz* ó‘ÁåÔ–’9õÿEwÅyXõfû;´S[Ò ünM7 œOÏ :Ÿº€çÞÞ Ô·T²èsooþ¹w\’-Ÿ·ˆtY!Åøø3µ{Â] ñß5JÀR±TÄY«[ÊE²£(-HLKõY‰&D4ÊgîTà¢^WñÄÿ'Ê(9ïwŒbÌÃb—øïÁ!N…UåµÄnó€Z+”÷ÂÖ 9Ì”| Yï¾SVš2¶Ðá³ÜîÚ9§ÆaÌâðñ•éÑ;f9åctø,ÄÛ}ßÝÁ¡!äàþ®œâÐý¥]Ι¥&!x±$øÐc±tþq ïl¶ù½Ê)ؼó>ãö³S$C åx8Ü— 7ÑÅçÙôÈÑ †Åéõf¬Éëïp \»™Œœf„(?>vŒ„¾…ÏßÄ…‚þV\@òɸrÞ)ŸÝ‰ƒù°5áþŸƒâHP…â2‹Ë‹lŒ ^Á\TD$0Uò¿hçYG«#±œ’Uéü.àýŸÄ¯åÝRb‰œýô»Y÷SÀîAwÀÙñ‡8qò5÷ãÊÿ#ÖA¨¿P üC„]Š.îFè~¸8Šÿz±¹¹ÅÂh±\(·ËCå£å#å½ô³¯ÞïŒýfùX¹\^.*x ä œ¦»£å}cû^ ²cå¡ÿ PKIz)FzÀ u%astropy_helpers/test_helpers.py•ZK“Û6¾Ï¯ÀÊJY‰›ÄW\:8^§âÃn¦ìÙl¥R)H‚=$ÁÈ‘µ.ÿ÷ýºR|i&«ÃŒHîF÷×(3ºQ”µMkT‰¼¬µiÄZÆVm£"÷b+Òü1·¹®¶¢6yÕ`E•4ô|#®|Ú*Otª¢"o”‘…ÝÜxâyek•4Ý£¶Ý7{l›¼èŸÚ¸6:Qö2~î¿6ª¬³¼P77Iæ¶¡µ6L´QouYÊ*õs0TÖ²é£,ÿµV™H×$ˆ½¹¹¹ýí¥ØÓ6á£2$m”W™þýÛ?Ä~/^bBRHkÅÛ]Ÿï”mÖ~­Ðñ'µùõ‘*›˜œé‚`ð¡­DsTàÚ6VdÚà)·¢–Ƀ<¨à†× yÁ¢ß{Å®?qlEp T¾ºÕJ–JèLHAzͳ<é(‹Fóž[¡ÂC(‚\‡YÞØ@€ƒ€õ„ 2 ÷>•sÕA€AOOA ZVÞ“Fxÿ¨ø%‰ …ë³ óÍÁ¼!.ûù$-ô·9˜ô*Ø «Yú-‘)”LI¶•tGø·Õ˜ž•"‹“æ<ãfÀNhÀ¾cgΠ±“憡ÍY|«BŸ¾a&w»T'–5u™ÁÌÊžË!¥M»Ø¬µ-NãÓÑM(ÖE{€Só‰×#R·n„Ô¢*JœŽª"³©HÀej8ç“‹GÖþÎÑpËD7Ñ3Šw94 ˆvœ‰gg”•æàx•#^ߤiNæ( ˜ö¡-UÕ0ã1iÑZ•ÒÃ"ÇF•ºQ»T6’È~à?äòì'Í “êSUh™ 7WÐܩܪ~E+_¸ò"ß¾»}%’£JHo‚<1êÐҸ͑Í|PÿiaZ– Îq¾£]„;°éþiLÛ§c—m$¡-Öôã [ùí¹9Â@R·‡4ŽïÊmì„d¢aC„p ›Œè¾5JB RtS Ár(FL÷£Þ›'ôu­ªù![±¦??áÈEÇ­Î^ÿð&°Ì³-€·Œöj¬¶„ŠWv«%ÂX¡ ¶O#qÆ“ìæ’jh GRQµeL*ËF¿½ý—uˆS©C‰ƒ\§bÕ*et†åÇÜ#‚¤Séü±¦¹|î=‘\ÿÔ•aÁñà f:aÏpÀÝã`Ç»ÆF?æ)‡ Xé “Ö,€b¢A0B_’òRÁ ·Ú:’ê¤g‰ÇâØ‡¼flK³ú»®¾žf5qïƺ¤Ÿõ B––—ŠÁÂÍ §äöY'€cÏ)M`æ`(…íóAˆ…LÌn ÿ±˜Ì’—õðaãÖx+Ž8?@âó DqX( NùUOÀª"óÙ }è1ìÒˆ=K>#é"6¥Q;"d0ç'„§É$7 ôà¾4H¾8àÐ5"t½²%ÁßòH/ô´8Jˆ9pY&ÛÁ^|;!½®@2㈦,“õvæWöçšåÕ“§úóMÉÙà ¢Û"X‘“Kt&†8 ŠÛ†}/À x3¹d^ ˆ!ŽG yý;Š”v0>å 1çË}|:î²~H}NT݈÷<úŽ‚Ëx™‘9R“ÁðzVˆprÌ i”á4þ9ÀF¿ç0[†§®æ„`¤C$¢á8¦à  ¸™žËÀµü¦ë€2RÄU(¯.d¢ö| ›ÉJèr²à2ƒŸ£¤L©<¡Ù…Ìvz}]¥N‰ir2ˆÔþ¯{’¡ûVäñ@DЉ‘"ñ$[›^ÖÓUŸa¬ 'Á懙g6?eȯ¼Xt4&ó,‰ñ„8/P â »ê ui<‘À]Ä›KäqÅ‚^kj˜¥@M&„´k@mç 8ù¨óÔŠ„’—Ï&l!Q„oTQw¤sE‰Eh$úZŽ¡žƒ‹§”€Ü@Ì®Ø Ë‡”¾¯k£öCŒv(ÿWì8Þô蹟êì“ΫµßcÛ¿¥UDiÝYÎf`¦\ž‘Su™²m±8aY5m&Ù!˜NïçÃ#HæBÕè¥¶Í €±P3ÉÆh=7ÀnFÈ$ϧÑÇ˯²hÕlé>«Ý®é)ê¢ý åê¼n¿!V\£gÖ¡bG{6ç9xKò$L.‰2€IÙ,fâ„s¤ìiõˆ.‰ýB¸L j„dõÃc6R6dT"iNÞ,èytºâºÈ:Œ ÊrW&5ÇÖ = =øB¥­‡%ˆKVPéë…µále·È$SŸZTÊÐä·bæ¸[§¸Œ¹PU÷oågX= >©KÏ&é2vßÉZ dó…ÜI®™CU97!˜ÚÉÙt)̓ˆ¬hvŽ´8(R·5ç¤DOþ{qùþrF€Ý„Ò¨õE¨Á¢œ¥Ë†}™QA5Å“€eºÞ,9ÿío/¯øÚ¡B…È&#¯/›ß͂ҳT^Ω,2?IYå Ë&µú²¸åWÔK‹›§É9’Þ(É&‰ÐÌP皥rÝú36ë)‘‹ ŒÉaÝ)v†€eÅc <™¼Që ªŠzÐë m²Ý«`³àP—¨³¬—`ůÅü(y“Ž|õ˜]Q3o&‚*5]ÌÌk½ÉÄ_ª>G ?Ó-'e/·.æ*ÃÈ›Bªô¸ë3!BÊ@ ]æI(„Añ©-kÊèöpD‚E)®Ö5÷ Kù0••µpÒ”wQ{ñ›.äü-(ü]¹Û RXÝe-2®)'}VìºSŽ%JÍÀÖÏú¤€¬|}…©xªº“ÓàËšÈßÓí°åʆ3Äûû½+>Ø¢ž,õ/'Ùò A}¾"íQf/Ö2-ó¦QiA·1¸àûË#¼ ÈLǯ§áK©,ã£@‚‚°0? !‹Fé(ž*„ZS¤"p¿ûñ^Xd w¶ï]¦tÍÜ‘æSMªd5;–®·Ë×ÌÜ…f¦Æ®.kðÐßTr7é ¥"ÿ˜Mã\"§ ZŒóamòpæƒ5êµSÇ1ÄŒ,(Ù…AëJ‘Hº¹=â ’¼e†œ–¨W1†š‡ŠóõŠn÷dÒ)´Ñ¨ÝºøÈ½mò²\:ù™0¥¦,cº“„ñƒUdsøkÎ\”źmÆ&aTCj¡fV&!Ùæúw‡‹*i¹Á†è·û‘bà. òþx6ÐúOrJ÷ã¢+)¨!¥vÚ~ã>Z1)Ä}ó”Üêðiì]aýñlá‹ï޳L›K÷s9ÚOú¡«Õ%(¾a Ã!o4%ßóÉ]î#éÒݶ5ù£JéйWåGp#HÑýHƒng»zÐW"tä0]–éE±Ç!ç$Mzaìöý˜+Æ'ˆÌ•^Þ (õs:îz"÷÷ôƒ‰¬Šû{á~JAy‰HhÔ•ªd‚þ'd¸ˆ:M8RÙ°Q9ËR&YÉhìé剿ã< ?›–<Ñ»ª(Û¹àìú™²+w7m]Šå¾°Ôwý“ î7&é‘Ã?·hzNLŠJ²+©»oÌôæÙ%Bç } ;r’~»ÔŠJJÿ‹!êzû—$4³´™ Å ?‰ï‰žvókInªŠk¦ò'rXZ}Ý nþPKu@,FÜ0~,$ astropy_helpers/test_helpers.pycíZ[G®îÙ½_¼;ŽMŹì8ìŽíÜ0r1"H,ˬIœ¨Ý3U3Û³=ݓ7žyÁ@â ñŽ„Ä<ó xBâ‘g~¼p¾SÝ=³D‚8$lomu]Nsê\¾ªrí¯+‹/þå·w:¢øS£Ÿ¯Ý«‰ü÷TQôϱOxbà‹_ jâ &3â`Fxá‹xVÌŠ¢^õ²>'æÊú¼8˜/ë â`¡¬/ŠƒE®×D¼$Ëâ`™èÎ5+â1X«ÂÓ ¢¿†QçU]ëBÍ ½,ôÑõ…š?â¡ïl€è~cØ Pc† ³FEØÎÓØDƒaš3 ££O?!fÐ-ã´b+dûDb¨[.”™Ž©ýCÍ`3”²9<‘Ý(ÖÛ22à¤)Hζˆ‘B´m™§,Õ6¦Æ:TàÿrèöùêeHtGçy˜|lÕ©e›±ùI˪(Ó“f'òŶŽÓã¹ugG¥œÅŸŒ`¦Â 7âX±¹%mžœbé[!©)¦m-ÃD–.âôdá5ê¬æz'Ó9íAÎj~×>‹}·Y"I­Å™Z3´$G–äðªo:“‰m/Jr·CCû Ç5A<„íXËãC`[0]Î^`ƒËnG‰›Þ¶7¨¼íæ¸a²Q0Д·#ÒYIë̬’nÕVÓÎ" d½‚—ÐnÃ-•Š`aL¦Õ³f¬ -ä¹Vø(9‚gz½£B2™–}®ô6Ps©Òã$NC%Ýh‰ÑM‹X4ÔÃ<ï†Ý›È²w{ï†ìêÎ@q…v4çžL÷lfŽxS¶ô–ö:g pl퀤tjnZÄ›¡jóÊ^£rß„™áñß(ŒuØ´öNÌ!ížÒmÛ둺¨®³,Ír·k”ö^:Vû[™I”P–}Ä"é#LU½…›8OM‡:Ù;JíT~6FFäÉI¡<²[âÇIL!=-qŽ˜1!íL„Bs¬c·«}û‹…22ŽräDGcdbmÈß•oí}7/‚‘î±ºä¤ ÅäAØ¡XEVQ/ |õ1NÝÞܧ}4Õæ@•ÓÞ²?+Âg Ø×Ó¡‹YUhÈ«()‡Yúa¤8:’0s6ËhÊTœèP ábát#4 \L¸¼í õ”¬Îü(rd± úz;M¶\èýdîì»ÆLäö7ÒcÒ66hö(×+5)Ïlt(ækcÛ?çœìŠXGÂu-©ôJÓ"_v°ÃøñaHœ?u8eD©×++¾05®Ì”-³e¥^VæÊ1óee¡¬,–•¥²² „ÊJ9}µìZ+[ÖQÙo€±]‡<Ü \~7M4c†ÂlÍB‘ºl¼™eOˆsm¦nP\7ÏÅK3?™2‚™™¥aÆ”QÆ¡ÀLû³)1à}+H:ß`¾°óޝÒ4™zµ¿í`•\ÇÝËŠ"“#t««mX}“Ü$Íïï\¿Ö|uçþׂ×^¹ª{½«E‚ u<ÔY~•5Q|P6Àn å0Ž>Ò%z+¥oáþVâ•2ã,dŸÙÞuìrÜ>W2þX¹lìFÉ)Þ¿ ú>ãkæo“~°k5ð÷MÚ¦“uXqI`{ì‰÷’‹bÆxâhQdW…çyT'XKØîžH/~L†Kú8/~$˜9 Á0€´ð˜+\À€ÑšxÛ­OÝú¾zZŒ×Y苨¨KbLŸÁ£uPTŸ#ê•bDG’g@â¡_£1æÑ¿,̳¢ÿœP—…z³z¤‰çÀ¢zÞ™¸?Þ`Ã2ž‡¢ û]ó‚m;È^þB€í·‹ôºÝ¢œÈ'6ÊCSiºpçéãJ@)7.Yb‚;09ÉQ‚s” ã°£ØUQr˜i:ZTw¸´ª6;Ý'2û"zw*¬„LˆÜ^fÃc°ðËÈlož>%Bhþ!ê⯤pl3bRÎ: ™2._âòeû$•¢^B€'2H h4NÉc»‚¾bœùÆQí¸Íô­éîܰP +¬âé&jòVõÝ,+ ä+ND·.?¸6&LB¸¥õʦëãËWxr3†m\¹Éª¬æÛž†ºÓ!õºÃG±¥M‡˜]h.öP9áË`ÂØéïU¶¥Ë¼Û²`©`ƒµÓ¬Ò rë&Â7TbØaFì-ež©. Ã<4&s 5—´I@+÷ ™%m¾þkÐeSÑfKØ»|œÃ‰çïK¤ò>}zÂp,q\¦ïzÔC²aõ“Zn=¸þL6Þå6¶ym’òÆ`y¹EóZëÒÇ“îc’9G_!kÔ÷‡Ùë¿)mݳW'†ÈÇvò†›U­¼±§õí½÷ƒ;·÷ïdœw2«í«“9APŒ ‚›Óÿd&Tý 3Pyÿ˜4t³´¸×›…Ãì1t@?!Fœ‘ÑìGûÙlXLÀ»1™µ#œæfLs›ú~dnþÖx±¬ÃyÅÈ Æ¶7ݯ[açXñ˜N ´ÙUyc«´ØBå ,ßa)nãdhž`8ÍŠˆÚ⫆¡6)ÍYg A †TÕ.ˆEÆ©š¼f;¯@'[EGíh´æJ##ÁÉ£YL£C ž;8Rø6Ë¢‚جK^¡ŸVÆ”v˜sÌbRù!Α2&Q3íFã£Ú‚° –ß c«0Ø™+tV¬É½÷_6ÅéÉ€ñüq·’NpƒØ’•§Ð²:cíPïn>tÆ[Åkæ¶M§<ÜÓ8®(ŠóR´ýܯïëŽåŒäpù€@Ï>ЃÛ0‘ÍÒßZp¸)Í’°ä‰>ª 0úQÆJOQÒãÎîzZ|űQªd’?x/»Š1û¤5Àñ“ÔÄRþÃT®XrŠTÍ5µžÇïy—2ƒnöœ½T¡e…>‚ãW­9#FËïc ¯æ­{+T®Ô6é÷šwÖ_ó6¼ þ¹ÙóÞ3Ô·î×½º_££ÇZö«ñõïìì­{ ã-c6}?]«×ÎùõÚ¢´æox+>ðë3g½µ'.x›þªÏц„íçc̯\žÉ.1¢õEì!l“þ)T5‘œ-ÛgñûÀúÔþѾ ƒ¤0߯¸Ÿ´H0g_ä14M‡:˜z(t¦î/a$ 0q«¿"öߣEÀÈ/±2qF€–¢Ê]¾yg$pØ_”ÅŸ7ä!9%•Òdú¾9n™Ü·áR7·C„?íwƒâ\y+¯(qh¼"Ë+z\‰¸ ™®5–HàÞ¦6V|¥))LF½CCIê8ÌÔ„±½wNsÅ×ÝZùž42S”ª1%w‘{÷p£ßb¾wOvâ0wwçQ“qËÂäqÃT¼8p¤w¥Yb̺ËPrÚw'ÑLRB‘*%¼Œxˆ+²mÍGBЧ„†•Ë%ùÆÅÅ™œ¯u«t³2'r¨A2cç<æ8ºOeAAñ”­W@ñ"Š+(d™JˆìPw 0 ‡ïRÈVb“qê=p>wwqÔs¹ÁÍzìgõÈü ôÀ¯˜‡‹.ûËäŒ5rU¸st‰´–þËAOÿ ùŒ_Bœš?õsÈ”ý»o"ŽÄã~qT?í눣òéžHÿÀ;‰[èÓ?–Löô1¾˜LÜú³y6™¶¢ÿ•·“݉R&/(»ÿuO(ÕVï(»ÿÒCŠ#0õš²û™<§4–ÊôðY©JéƒTÙŸ tÞÉ"¾ÄvÇ0œ¦ÿ{C‹s7gÿó(žBä¹u’±kÚÆ‘Žüë'ýzPºO?³@ëÓ?\úÕjµâ‡Zf– u/œY˜]8æÃR¡& Ô€çÇ/œrZؘÖ÷Pì ø"Š·PÜFñÎ@2ÎéMØ}‹¡NãÀŒ”Æj,`a%ÝÔ1ŒJÛ}25ñ³Ñž»$r»ü:„ËqÒ½L°§úë¯ûëµÍÚßPKIz)Frz—¯æ6astropy_helpers/utils.py¥Xko·ý®_1×* ֵ݅pU4¹IŠiQÔ)ò!0$j—k±æ.7$7Šþ}Ï܇d÷æ>ôE«åðpžg†º¤w*—µ“µu!- º]æZ´NÒË»WäüQKÒQ†–䤤woÿõú×»×™u~2QUc¬§ÜÔ^~ñZíº7øêëžÜÑM&ÞW§´¦¢¸‚é‰*‘ïU-í‘„Kï6ý»‰ü’ËÆÓÛðþµµÆF¬sAZÓ¯¦–“Éä’~;ú½©é6»ºÑy9d¥£Ri ½¼¬ÈJQà…±T ¼°I›jò{ ¨ p¡±×ÉŒ^¶0ÉTÒ« @ʾ–¹tN@o`JÝ ­ØÿYhU/c#¥ÓÁáž'±2¹¨©Qù#µ PéhH3¢;É@{ï·ººzP~ßî²ÜTWPÞšæØ+çZé®~¸ùv¢JÆÏ>K딩7ª.ÍÇÕÍ=ý¸¦Ùí‚nçÿ.4ƒ›¨þDj'SÎ×-ª]!V]$WÎÑæU[UÇ7°afvÊܧ#/..^PmLC«¼;$^Ȱ4 2’ÎÈÓ)Ñ%ý.?µÊ²G²>Ê_¢l!ˈ4sR— réþ4Pd*uëöAê‰Èä§!³³ôˆ¨Ši'¼ÕÁŒ:—³± IŒ’\ŒotÁûΩ#ê¢û Ã+.6Id=’¯A~Xð6‚^Ý<¯ÆOVc]qJ˜Y¶ÒµšSkgŒžE©oèf~V\4ëO íoA/.\~Ÿy£Gj9¾æ,I«#ÿ¯Ò.DäIàCå6,”¶ŸoêBú Á¶ú´ãÈŠQ~ˆ¼¥çÞ …*—r4‹Eñ›°¢â½.ü\öŸÉIàW[†"L¯ÑÅÓC"rªš1lxN%² AyRc[.²mWeºW¹78<ÔЛY$Àù¸CAñ«Y÷Bì›w¬4Ê{Þñ4çáòÂx¨–%ÀA3ËãÀl7ͦ‰ßûmO¿%…w…Û¾’) B?nÜ£jº<ð¦Y€?Bû^ó4°@ËÖà ü£[‡ :Ë‘hÞ¢iÐ?¹¹oá(Fݦn ìÎÑq ݤ ªB™F¿¿ß# e[j¡Â@i~/>˳¦Ë(ÚBGÐ]½ ³OØÜº ²#tªZРÐqt´“pšs$@–ŒB‡}JÖqóc=’nßáÌI.Ç&ÏEÚ½1<’ÒåVŶhÊSÅÝi¢±³¬1~ÁêºEræ×„9;a‡—døš“yˆRú^œrë(h£çQ6^r½9¾28ŸÜÿ´M&WU3ûç’Û}gäAi:ÂH‘y¼_d³>®î‘¸ãÜǨám×ÃÏ8¨˜ß÷›ƒ7Òî2ú¼;9éÙíåh{|žº·Ëz67ªÜª,Ñ!k #V-ìC†`QÚòË-óÒ¶Ü.:6 Sdí»xwäÒcÿÇ”¨ç)%À°†ó"ÖâW;tcÞc¶9ÙÎ÷Œ,ÈN2u½1@GcýðÕ¡ü‰Ó;n”YLNdšÔU¢W§v7ó=±,NÛræAÕBo‚¶˜ŠŒ/w³çÈð\6ÞV:½Nѵùû+JþF)(/$!ºŽ/®¼ýÜêŽ ß¦[¨ Ê-Âng‚˜YtФù«|à¸zÊU§ š^ax•·ZX<渙d'‡\Ò]#sU™®`+ Å„ƒË.èé$3N¸}¶|£ý„‹­*~‡â‰0ÁÄ™"pŽ º­v W$ñ2•ó9™0MwÓi¨¹Ò´ ïÖ$”~úGg4š‡Óè¨ 4[cçÒ?·‚OX‰è~¾¨G þ¶Ê·®TEñp‡»4‘ö!06~@}¾O›E ê´½»pso‰ÿޏÜX9rE0Zç{.Í ‹à½G©ùòŸ@˜üjõ‰™•;Ô(@ÈGvd…6 ídþta-¬b¡Òrk‰dˆìk€Ñ|baÓ?¦ôÜõþÛ{ú'݆¤GÁL‡ûN<&äû¨Ýh2šV\£ßh‡üf¿! O7ÓìO£ê~¤±R‡‘¦œG^‡ç¯W÷CùŸÿ}3è£àÿ¥ÖOD²;ÓÚ\òìý.Ȥù¨W²‡€øÏˆ ”ñ×&æÁ³lð\E³ƒŸ­èˆ ÍN`“Å Ë‚0V!Ù#Ô‚®çÉô4cáípM<Þkº¦sD‚9¤r³B…iBØãÓ™|XË¢ðülÈÿ_`lõPKu@,FrF9¸Õ Úastropy_helpers/utils.pyc­XßoKžÝuìØqâ6iúCº?VÔš+âÐöÞ«’¢Ò–R.DtÓKJD묽ãxãõ®»3nb)‘ ­Wâ ñ_ð„Ä߯]wáâcWLª€Õ/‰Z>¡A¨ñ¨?r¬ðKÁ,sä 5ùšîT˜8…Õð›¥Zj¦ážÌ}ݵ¯çiW*_MTKé(k?L£â“ìØÚ4æÇ¦¨•Ík‹* ±AØwÃDIëã|,›^VYµí°SŸ4T/Ã_‡]9Òq–¶³nwœç2š!¤»Ïo£ú´–ªNÕ©Ó¿²ãQÍ#¢¥â–©41§7op `å"~g| “;â‘ð5Ôɳd¡ý¼ùŠÝM˜Ü†MöËb¿"öç!†.ö9gà õÌùÒ‰Ð芻pÅvú¾(éôö\>]~Ë`¨£Óú}‹«þNEÍ·?ÔãlïÇ=ò±ô÷â2õ{d€Q¨û~?TÜÜ£ˆÚC­ó¸3ÖÄKéTÍÏ·Ö¶ã4ÊTË÷ï‡JFÔë‡þ(SÚïË\nLEûZ6Öו»ƒì…Ì{IvÐêfÃõçc©àQµ~ãÖ'ׯºÞÍ3¥ÖFI¨{Y>\3ó¯a]k‘ÔD‰ñ©ðÙÂçHs±€P¬â”æ!7²:- #ÙÍ",Ad¾'5Ô­rHnÏ¢8ÝcÉ®žŒì ro”$Ì*™§2¹yƒ¡ø©Aþ÷ »¨m Å÷”’9–øcP ¼“e‰é+d¹/Àqg€å…áyͰ¶™>—jœè¢o“sÛÆ°í©cï@;v&Ê ç2!}ÕYv.8+Níh^Ÿ=ƒÍ~¸ö­Ù²(ŽÓÍ7‚?y5Ϧü‰ø2ÏÆ‘ %r8oŽ#ñ‡¨S¸E¦—"¥ñf ÅÍè© J0J,Aþ»ˆ¡Ä|HIŒBô„§bÇÏr?Šs‚i–OüXÙøiÕxÜ/œÎ%«øsmúÃŸÓØÛðÉSŒ?¦(äfÑToMb4Ûˆ>­–ë6|7| ð­øßì Àª§KfaÎ"ZMTÃØp= zµLžaG¡#À‰\)‘B1×ê ¦Ž«â!¬‰W9jé\Öz¦Œ¾dôbQîÔbU¢ñÓp–݆ÓÅ‚æí/ǤâðK ¤#>!ióĺà^ØxåxžÆâמ8¦ÿtω=âú’xðô²8.ƒãÊŽº…Ê3W<¿…î&¤æŒT…¥*,õ H=Cwóȃ0ÕzðÏ?Û”jo5Á ê¦c1xrÅpDö‰'ýÝLµÂd°kÏëA<*É~U|\ ‰¥²ˆ|Ü'‡÷Æ)Óªe$˜fDÞá ɘˆõwu6"ªOwý^ž yðtÒ –=¥ÝŽé“ƒp¢üŽô©cœã| %kÐâô-ÄÆD×{4þÔ:ìÚ¶¤$*;+üaç%X?¤½‡~D÷„<æÌÀÏzgnb‚jwÀuº,0C/€{³„Ž£$Nj“3ò YàÓ`Å`°œ/RR\GóB2ϾœþÆÄÝs–ÒGPÄeo†Ð>g×Ö†§-¸c(®Cýb•¸û¢wÕ¹êðÕ˪lù¥ÍL›™¨UÀû¥c3“ý9Kzù¦ #ÈàŸÄþ°b‰‘²Ê^øÛž¤e„}µœ®ä¿/z<ðB1° ÒìØ‘|K¶w Q±ë…¿K·¿pl· ‚!v¿[pg§©.¼\PV÷z”o¤úÿ&Z¨ý¢e…ÜGópqã¡ é«ÅrXØIÅ™Üñæ˜S;0ÙDóÎ&ÿ=è4AE'|øö‚ïÀI|E9$xÖÍF´A†š £øæÂö›æL¨ CZOÓ‹4r#ŠË½8 “6:fˆDß Ûq¯=õÃo   «î2¡q•î>uú˧7°¸PàñÓÓ›€v…1 ^xRº4—8vñÞ1˜§ {¥Cà‹8¶}`‘ú(™ÖüZ¹²øÐžö|0åB¹¿ÝÐä‚lju÷ëŒî9‘~_ÝŽ8P€â&û0ļÂgBDýŠmZç£'DÝ[MœjªS¤ ?Žˆmˆ†}se¥/°_bqr:kæáôš&0%È‘~VB¤¦ãî8 sªvt?3°Bä›—&š/¸Ì¹lÇü€>òÖf³Øp ¦ L\á:§½Ì ê}@”%1nƒŒ¨ý,6Ü™ŠT•%Ì­®fðxÌ;mOŸy¸q+ç]‰ŒùgYH÷9æÝ„ªörÜ)˜•†71Ip·`Ö!²ö54}\DEb”x¦7¸/fú¸°p² øåÏÐyšë†/:-ºý-; Âõ5—Mÿv‚ŒÀÆ}ŸèÎ1øØ óÉ 7Q5óä<×_Å;Þl¾q­ÁQ¤ôÛ3µ0+þÛÉššÓ—@óx¹°Œ}ŒHâNðhŠNFouê#tBK€;ûÎÄš¹e1¨?Gáà1/kæ-bédûà\,À_ÜAƒ÷0É+'|Ñ ðX<@ñÅÔRBÌþñфǰ ȯu×£»Ù¢S«¬8+nÕ»X_¾Ô Öú¹j©z©q©z¹úÞŠS÷þPKu@,F´Ð„¾uastropy_helpers/version.py¥X[oÛ¸~÷¯`“ÙX[GN“´õÂ8ÐîÙ¾ìv/]à §p)‰ŠÙÈ¢@Rq¢ÿý|CR²ä8Iwë‡D—™áÌ7w²«ÆªQ Í­ÈYºcWÆjUïf¼(d)ÝÓšg·üF0î_­Ö¢¬…6‘aFئŽëS;Kæ³d>›Ÿ±äå"y¾8?‹“ó‹ùù|4ÉM­´e¥Êx)Ú;eÚ+Ó¤µV™0Ý“-ו¬n xsQ°U.2•‹•±¹Tcè!øf²1ü¬Þù ú¹÷+QÜlNŒo„…Þ”Ö?O®ç˜Ò,jl1{9âs&jËþâe#Þh­ô#r[¾û*XñÙ‚Àë{½ÇCþIÿ¸÷•$’׎ðàØSö“¬xÉ ^–)¼ðø!QÉ­¬æÑÄk¥á]9Ò€bSçpèêFZàyæñü(U5…ízù‹ªD@õääÄýïX ³kÁÀ¡w’8èhBBŒW9ü_îèšÈH“†¥Â8ŠÜIË¥™i¡Õ†q'q«ô-f­˜±?×`•i´;•['³;¶j6©ÐLVx¼ &t Ƴ¬¡xŽ;Kî{é”ýÖÈìq¶cV±\X¡7²dÄVD•S1R)ËfNâˆhð¬“屄;e}pÍš/ÿÔ˜2³VÛUéåO¼4" NÑðë!¼¬ô–øóù}›Þi•òøÒë`€QìSc,Î3HXYŠ xJ|ÙI/$݇ÁE¸c Yƒ¨èĶUÊ0á66u)í8ŠIú”Í'×ɇoB1@öŒ啸ùcqá{Ô!£ ‚az+A.-Ê/‘^ùΙkáÈiQ ÖÂõŠ.Û¾Ñ!åßë60} †ðWE¹!/YJ-je¤Uz{(ÞqÍ7ÄoÜí¬û¹[èÃ,UªìÌx[0¯ U4eÉþøùjÎÖܬÙVâ6ÁT‘Çì×,Oo•å{Q™jÐ3S›´AKÑS²“Øô´Ùɽ8òöžƒú¸=¨»4¦A¯j;E³QŸ¾¼b‚2ŒQÉœ²½ÇÝSÓɤK8ßU¶U* ä­þñ<” ø·™,dð™/zd12§TêÖa¡X!Q8C]íERçD'ô#òq:ȸ¶bîÃû„bÜWçFÞ‰ Jdâ!MD‡:eª²\:¤\µ%ò`îï²~ðŒB¦¶E×ÑúFšð0ð:V¾ÇpÊGàGÒÜ%ÅÄ™ØIÚÇ*¶ûp ¿ƒ.!çnj» tâB ´Z˪P¡eî %bPæN.˃í]×kÛÐÈ‹^€àéC Ù6OÅω"–X]:Æëhxjèÿ¸½yÌs+>KcMÇñIÉÊ‘OQæ`j4™Ük!QÔIrƒ!“¼RAØbÉu®eð­~~sõzŸÝ›ê_£MÞÍj®@5ˆ"úp¤¬ö©K¨Mij™«=¾Z¨lMEus ¶žƒîí0¤ù§›ãwªÕø:"ã? Èƒ{ÊàצΣ?Lhª±Ë¾Ä·ïÞ|#JÇ?c”Õ!ßdt@¥¦á \Ç” FFtâñžx8=P5C´œÓ÷ÕsqO½vàŽéby9p…« uÁ¨uR#“¡’!¼Æ”p'¹4ê5cJ ØÓPÉeË%›Ÿ½ü>í~Q¡¦wͤƸHõìKòL}ÆÞÒs{ÑS°k½G é†aî›°u/†ËCÔž-Yò}˜ýØ--gÛ5þuƒ>Üu¥'uµjAèvn¤Î–dÿa~Œº¿Ù{Ñ/ŸƒÖAíj„åé`TÂ+·ß¹¦ë¶¼Ú\PÄ‹«ý?¶Û˜—€gVfMɵK}Ÿ]óõ¹ÝIB¢¹ D‡ÆíB¯'g‹QB¸zE{‰e„ûÙžâaÓlz‚ösv¶ÆÑÍ*!rú"t+vŒ5sÝÐ ÍÔ2÷p¼û Ôë?Z&½ôï9|oÆ*Œ×;®òºQÁÀ:°V9ÙÕ6z¢Úï„“»?=:ö’–~ÆÑA¢†Xv‹S8vbÇiô¿*šô“Þˆ£œQø&SŽ+áý½üÓëÅyrlyŒ'¦Y±¦émUbZu_ÃVí¸¸dQŸÇçQK±–¦¢%k¢Œ?uñœ¿¸ÌÏ“"Ÿ_ò¤<™§/.…¸8»LÓWüòU:Çìµwÿ;ÌGOFû³þÎÇ…‡ë™Û3W+šòW« UúMX]7ü“¢°JFH wu>J››B~v—£v^º¹›.^âÆ<ucšû¯à5ÎÒá;kïGabyë÷¾yt KvÒT·•ÚV'÷Äf;„qÕ9¨•=xúð Cæþ9ÿPKu@,Fò–1Eëúastropy_helpers/version.pyc­WÝrIîž‘eK‘íÄN"²M'µPÚ"VìÄq~`[$Kr7È »¨¶JiZòØ£™aºÇŽ »€JŠ„ Šw7à†;^€Ç€{8ß™;©À ‘­VO÷éÓ§ÏùÎ×gÜÎ7ÿþ«¿<‰â3KßÓ×,H!|ú—"¢_õ¥è˲Sö]Ñw…ïˆW$\ÈïŠW$\zVè9©‰W$ÖþŒè7…_ý3B“@S¼$É–Ð4• Ïa•ßz^¼nòG¡Ïˆþ‚𛢿(|êŸåö„ûKî/‹ÃóÂo ^„çÅô‚è_ò«¨-jú¢ØkŠôBJé/`<’âëBzQ„m1m‹~ûmé†,¤Û,MæouÎ’_‚ÓgsDÎ.}gèû¸+¢æð#a…Ø•d3Î{)¹KÁŠ­ÃŠo±<Ìf,‹#ZãŠ# /;$¬H¸ÆÂ„óyòg>UG™S£-7Xb`FfÇ+wmz¡gƒh­ƒÁü9y¡¶0¢­¯Ç^Úb°Iƒ¿ðÂL?JÓ8eq_b_Û%ê>ôòKtÜR«±©ö¦v»~tDRA4±0Ìê¶@qc>£f˜¡cèÆv§Þ(6/VÖV»·W^ÜÝl¬ßÐ“É ”ÆÉá`G‡‰NÍ}j‚8ê&‡vž4 rÓ¼,70RHW~$çeÓq岜w–‘C£µÍž?!ÄÏî¨À¨¡fiBÔ>kóƒT,‰ŽÓxª<Öx§{‘‡»J=Û¡¥:2YÊ»z–uVÛFÙt¨SD¬SE0*ƒŒòF£,%«»¹  aHQ‹ãƒÁ—F% `,Køzß` KFo€næp]È1: {´)/~–fÚBà /4Ú"¬_nåˆÅ¨IÂÀr>ðTah¯UBµÐÔ:™ =£?(>Ï!9†§Œ¿Ý™W]ç atÆ©;5§%/ÊËNËÁsVÙ{_CÞÁ boN¤—Õ]|ò!ˆbðè{$Cl`6Ë‘™²S/¦èÿ­%³egŽõKà Ð L¦o€XBù„¸ÉÑboŒ¸y-Äk)Æ ÷ß qLùP°IË7$0#Žëâx¹ÑJ?–G3`ñ=GPŠ oèªA×ûW΀Ա¤-mCÕÅnŸf vFŸ@zSÚ3˜§a¢{µU=í¶à«-rßVgþ¤½òôz¨­N§ATdXîx\ÞÔiŠPê$6ÓÃn“×>õRoŠõ†Wª?âÕ}5Œãñy2V@ìuÞjœ…¡ÚzüùšÚñÌŽ:èqˆD³Yi¿«¾$©ô 0…¼­w¢jg‘…£x: la¥>ed¥13ÚWe¥ºVªR“Ÿ÷Zq ÓÉù_mŒÉ4)+åˆtr^‚Ý´K¤4P‘¯«¸j*}‰gŒ2A¨#¢£b&®û E 6ãHŸÞÞ+æº2‰ã ˆYÎi8±UÇ{ì‹XâÅ‚6+=§‚ÈJ·±Ëvîa"­”Ì©ñD1E^ìž6gì눌ã „EN ¡wmÅ‘õö“)Ä‹ãör—ONÒz¿äTvFµë£Þ¬A&½;”mà6,gnü”Xi:Á]<~ëì9œÞV€¸Óz ‚;Mìaa@¥®À@iuc 4ôU[`0ðI9Bæ—Pcª§E–ywb%ñRâqÌ=~ôùC3W ‡Ä½¾²ÂÀç: Ë~ ¾¦‘ßuÑØD‚ÚD 5¾„‰0‰hŠÎLÑy)kTq1E|ã ”"vø*Z¯ª­—B«É7R¤¿t±™Ò•BtEäÒ¦¯Œ˜œ©0 M’âþ*°æÏ嚈«¢a,)¤gñ?v‰oóç&¯®ñŽÿ*WŸÁj:1ߥw5q)qJCKì¹"}ÌîÊBÃ<4€Ý„ÿ©ãä™)s“/i ¿£¿(öü8³e—R<¿w©‹ âÂw±J³ˆ€VßW½6îößBìôÆ}T¼•Pá(R²üzõjz|U=7œŽyŠô(‘Ö ~=?§æ—q–²&0€Q1a¯ãÇ”Ž4d²5©;þѧ?@Jdª²d’z>§f¬ö׺wº7rª“uÚåòìRóSR1ö(o}u°C?dA~i`e•z Ìû؃káM>'7.8¸.͆I´1ì§§qBÚŸ>yúˆ"CŽ¥ü˨º&z(,R  ZâxÈKª¢ƒ±öœ‚¹HG@Æq:õl©•Q¸©o‘Ûи^æ—dƒþPð,Ê:•é3~[T å‘–s®ìQñ~ÖɽÈà ‡ …âækžûl5NÔ :\?â¡÷]œ'Œ û†jI‚p^ Â7!Æfc½¡á’}³ó ýÄ߃¨÷I¹”ãÎ^.°ŸIQë5Kgæn…9½ï£ùšÊÿy¹ù¶ûÿÏ÷P2ÃÛ†õ§%%yÕ¹*kTk.ÒßÒ• Îr}I^pÉÅÎ,¹zÁá7ÆÕîzw=ò‘wëÞí[Þ }uì¯mx«c}Û[]ÞÙÐúöÍáðž·qo¸öÎQ9\Å…|G–@¦%”@¹§³h/Š¢|ÖŽí•àÅ:ß‚:Lö®£ùÍ542¢=”Ð=¼¿ö€ >²EÆ BrÌ`¢#׿T™¿,æstuÒõ×[.M p3lZ1Ëz»Åëe|ñ*<Ì&ãàEnjzg`_Ó„…yƒò¤½ÛØžyÂïaLˆ½;UØ«æäŽñÃiìg¡~P+É«%ùÏm,¶./m×eÞ2–ä¢K=êãëÊóÅ[2~ÿPK*xbEÖ·U2Að"astropy_helpers/version_helpers.pyX_sã6×§`7’¦Ž&m^nÒê!m6Ó½ìN6íN»w£Ð2m³‘E•¤âø2ùîðDÉön\M&¦H@àP'ä-/Y­Øœ´õœIBÉùiYÑV1òÇŸˆÒÛŠ‘ÊÒS¢#o¯œÞ|˜fRé(zóæMô›æל)²’,YÍ$Õ¼^½bä‘IÅE ’$N!Å%ŒE³% ŒiMèbüT³yÔÐò.Y Óó;굘·›ÍŠ—+RŠZS^«N>¯ÂH6/'‹¢\¯xmd9ÅÀTjÈ<¯T÷kú—÷ðÚ P—ûY»\ð§ûè‘JNgغ•ÕQ2Õ°RóGF*µ"b1°¼n×3ðlbE®H|¾ˆèL±Z§¹Ã}%«Uìžø-òN¶ð‹òàþ(qdV­+Z©n=2ësöÈ*ѬAr§(äM&WÖE„–º¥Õèx&þâ"Š< )Ö;®âëFÈNr ¹Ü“…#, *‘¡*ŠE«[ÉŠÂÎù#·ý”ækæßáÇ…ò£æaÙBìùWµUnƒ9WW”—_‰¥[ÊüÔ’ëbŪt+Šé¶ñsžŒ«¢“†£¦¢ÛB4”@Hé”謴äÄ àõ#­8ZU”´\1Ðôýç$G¥½s ŒáOgÿ%yNÎ#xælA:Ù°3׉{K/ŒÏÑ¥øû×àðGÉÆk-ˆ‰ç 1Ñl£Æ¢KE’ 䈛4Ò¬u´š@0-h[Ù\ä,ͺ]í‘C,5’AHÂV$‰3¾xBbŠÿføO–±SÔžÜéÚ¯âã Ȼ̷f[¶œcwÆUcó˜0ÎâÔP³a|xj`w‹èŒñâ7nѹ''g¨pÅêŽ$%ß“sÂLÎ…œß:N $ë‘Çc£èòÜfq‹x;ÛpˆmàÜR28ÚmBس˜«WT€I†>IsèW©ŒÜíV1©m°6Q#:3%ªV`(^—¬G’J £HUz&±&ÄñOúzjç°&* w5F8Lë¢q¶òE+ëpšIÒ€ï¾[˜CÀìÕÏ*±a2I±>Ä®ÒÆ=~” 7v]VlÖ³¾Dyº‹$&_‡ÔVÞ½ÌJ`2ƒ8W”3< ;™‘™v J´²Äý-‘¡·s!}V¸±;û8±¯¡ËÝ«-f.IòS =àVè2 È$þ‘ÖH ºxýJ17 ë[›N±@ÉïH¼?nb "ªm\£°­›û åW5^»¯ ÙClr.pÏܻ AOa¥fÐ)˜ŒûHE*ñtÙº«ì•¤AÙ©NÀ‚Ä#¦ãÁ¹ÝdÚ‹lïðç{ZùÖÀë{Gê³ýéÙ-–îÇþ0Tëöi7ètíNi/ˆÒ‰þ :ŒE;O+ô´,k?ÐÝ ]ùÆ”o{ÙZÅÜB5¤žõ½^œ<[g"ˆ„À^ž ƒ³gÖ‰—ÞAÈgíÆa¶ÇD¥ÕÑÁ‰²^¢S;>¼ròhØ?P‰ÝÌTØAjßݼk‡–wªHßkÙ{X7Q¡òRõÌ.–€ä^2ä'ôq‡ž‹eÛÚöÂt2nɸ¯NTú¬y²ÞPqd{;3‘íuôÐ _ºžu{˜ª>°,›?‡IÜÿ©‚þ N&š-+N^%^ˆ¹n.躖ü—?MƒÝFW*ÁI€¡ÝŒUâ&Œt2Î5nŽívU8`-p5Ò·¹ R×R=d·jzçn<ЬL¯`’Òîàøh²vv½™Òë˜xaà³+¸¯ÓUi€8°ƒ„ÊyTÿQý&Î6‰ÃæÃ¯š46hÄ?¢ã2%=ç…ÈY=¯à·Ÿp¤òÈØ$Í“LA¿Tô+Y†´‰>´Té˜(ù²Q£«er³4*Ñh†F³tˆ„…Ò”¹€§ŽBö€—".ˆtl‹S¯ÛâÒ™ëäÞ˜9gj7O9Pr¦hËìé…ëìQ‡Þ0Ì:¶7ïµd<……Zìm&ó¤=и£¤#öNKîSL`¬‰Y“©,íTÀÊ&6!¨gÁÀaÄ)xÿ™s¨¨ y ùüŒŒA¢8(ħÀ–‰P!gÎ([d³6±?iÒ-a¡ÿ>Õê{8=Ûxg³õÞÆÙƒ÷Ý÷ß½¯ŽŽîç~]øâýµò>㓞cM—“]ÜÅ€I*7ŒºqËœ7øÛ4Ò/Ø*ÖÛö£¡Ž/QéàܾÈ+òúj|7µS¥‡€_ç…ú*Õ^0¶¬‹®ò|•0%§´ÚBŒ-9«ôAŒ­üž™‘Q<%‡ð˜[¾â!ô„`œpÓ-·÷AÈ–‡uÑ·ÔYG ´½#ì­$a4y“ í·†ÑqŸFoý@mç\wÙT/!ËUîëW¸:yzô?ˆˆ‹)èà#¹!_¡;1öÔÄ :y“m• q$xiC9‰1ërÆp Ø؉ynó5ÚïY—ºJS3Ò®÷à¾n§ÝøÔ=õ’ˆì¡úºœð•Ÿ§»]—¦rÝ{6ßô•=[8ùÿ]/ðëoìjZ¢±Ç?ÆH*q3àú²Dã «4®  Í@†Ë.’-2Œj‘…¤Ï£«ÜaøIŽ Ž¬^Ñu,êUÑíÕÀœ£l_£Ñ5êYÐ8®Ó¨Néßì=)9XÌÐ h¦ ²1`r ½˜1ž26Žt¶AzóXöïîЗ&¸ã9ÍQohÉÉ·ôäù·Ä¿}FJ®sX~Ôd¯ÞÁææI/R²`ð*ãŠæ±\o Ð á`Ó7Pée”@Ø™cVs’mƒ[ðˆM¸B½U”E£y”B#^~AP›JãE¨õ¯C 3*sôM‘_Äý%q]wƒF\x-ÓˆëºUÉgùù7q| xAÕ§Í[|{»t9ð×MéíKzã²x²sì°µÛÇp/Šb ׳Óx˜t¦¯¤Jz ÐZSÑò+›;v:H<2*¢ñ[°\¤p6Aø›zÛþÝÖãÝ8o ÚkÀûP>ØfG×uy^º¹#©¼œ¶Nät¹ §ó—ðŽÜäà“R` u ó 8E:@[¾ï,Er’€€[s­`cY)CØvP%Lg©HAa|ª²­q1bC[yqƲ˜œ¢àe•®‹Mº®ŒI&ƒH¥ÎÄ80ƒÆ:.f9ƒo›ÂÒrJÅ Z@%S¦Q`"U‹ž^ÌÉû~òÅÏÅ *ÂK*ºŠ7"¼ÑoaÙmç“öÖ®ûÙ–ótç“]÷ÉîþÎÞGîã=÷£­Gn9¢ý¤ïi)¹^1coëã'x´·ÕÄAœŸ¢i ùI‘£ó4ã¼ î*š7мtEe±4ì)dnÆú„tÅvY%àŸÉ9ÀÉÎxé´l=çvQ5Fê´@DçN‘êä|ï¬Ã,P¹ Åæ²±l.5Ó2ËÆ¼q“ó}Ùh0§ÂÏ5æTU©•çÍ›xš5æ/šó\”'ßîGoèý=ûÌy e¸=Kç pO0|?ºE3\t[”< Ã00RÂHdÐç¹ä à}?ZHºd€g6Ä 3 ü ¢sØî³pE„ÿ*ÂU¬Œ¶,mEÚª´µL‰)¥k•’;¾Œ›€¶lèŸ2$ùkàH¢§'ÙÉHjJ&)CK”Þ0XkÎéT1|gp2âÌÑ›£ã ')ƒSÍt—S'´×%É`¥Eä Ä›[šŒÍ þóé—‘Æ^YfZA¼IZ/RÙ*`=ÏXì §«pϘ¶Ïgýôs½†åp¼Y}‹z·a]Œ?ÿK²ÐÓ&â;m!TQ:¼ú¥ox‘ê¨4õ’ó–ƒwœÔº„I”úyã¹ òÆÆóa tŠhÛN”ú•ûK/£\È_lŽ¥D?•ØÜm"n„—Fÿ5„Ý#ÍoC­¤“¨×Ë9yà=€¾7‹œ*à$†wcŽaqÊkCœJ޳9AéóŒë%G'~b!ÆFWwù½ïà2¾³»ý‰S*ðuÿ‘³+þ)à¼_°ã¿#ÄN“@+ `g¶X)È ££Q³~Ô&‡c‰®¾]Ê‹çklVŸ e¦ÑHqa’ðvÜ%å\OR•žºaF7¹«Ãÿ˛˒¤‹l×SÙèÏXå#¬5S2êfÉhà›?-0< è²Ì:ƒþ–M€ßÆ’Y+-™+æ"ƒàšYaГ²FRƒëúq'O\Íõ0á|é`-çm4Ÿ¢yŒæghv0á2yïgHÈÒpîÃAq0ñ†ÌŸqÇÙ$¹íú”]ÅAÞ¤d±_ yÍ»hÄC`g§}%‹üØ€¢á×™ýûH‘¤Ëæ‚Y7ò/Ó ÆŠ±`.ÍÔîYuk¦þ^ÙøPKYHáDŽƒu¾Ëp"astropy_helpers/compat/__init__.pymP±NÅ0 Üû§NeéÀÛXÙLEm“ò,¥q•¸Rò÷¸y$ÀŠäÓÙºóźf¥lŽä¢á]ˆCZ¿{è Õ÷}í/WJзrÄs‘+ÜS°¸h_xÛ'¡™c3ßd`Dþ±­K=tÄ×CÖöC·wÍÝ£¿G„¤–¦S­×dñ@ÊDž' “Ýí«wgcÊ3£ŸW.oK}Øÿ/PKYHáD_±6,($astropy_helpers/compat/subprocess.pym‘1OÃ0…wÿŠS ¨ÊЩ#»åÆbáø,ß™(ÿžK“Ò ‘ɱ?¿÷î¹ió stŽ˜¦ârÆ®PMd@àzÉ…:d†‘|¨»NÀyϦ°û²T%WÇiÝ“c ç…@• xŸe !Á©}iyK,胇üà'Àç æÐ-`³€LO‹T}›n—"¹¯2€ò#qÂ*V‹Nh$½cÖ G˜3As‚­ >l­3µðžt†%b–!aœû²nEý“š€6 Yö­¬[Ò3OŒVCª‘Âo¶F©Éeõ¶*ËÏÚ£`œ˜†È·RïŽd^uÝ^Íßš 8 >)KO"c”2½¿¾.KOãLÓ茪€Rùª6.'þ#ò²¼KûIbäY#’É}åD¥‡>:¤—QQÿ£.ez¡eÏ"°­7*  S3>‰9ë¤FÚ]£4ú+žÆÜñšd–(¬ó¿&x>> ."PÊMM)–cÜ NPºNâë±>]f{Zæ¢}ÑõÃå$ÿÿa¤â«-—«ŽÕÆß_¼zY½¹¸wE¯^¯Än·ÚN[¡âáWÓ^WʘŒ¿ŸVúa´–`ž=ËO‹³ìiþPKYHáDÞ@‰"r2astropy_helpers/compat/_subprocess_py2/__init__.py}SÉnÛ0½ë+¼x,;í¡…‹äÒæKb´i/i PÒ(bC‘—8é×wHÊ[ÒV0d g{ïq¦5º‡²l½óËD?hã€WVKï°Lv–µ!Îúj0ºFkwqó,Ël¡î°~,µwƒwÓù TÜ<ØæóÇmøš­3 Ç0ƾzµî{®Ø ×ù}ÊYG ŠAfªœP½8Œ%¬3B=Y4®Zp> G5„-+­¿Ñhª† ‹!ÿ3—›M‚iŒ6Àm—j¾u‚®~aí ”Ðñ'Œ}Fl±“Pá(±ŠÇá4šÜÄŠÔ‹|F)|Oi2ò Ç2˜ÔÎòû–ð{t¥îŠ4ðµ‹.Ÿy?H\¯S¡‹‹‹Ó˸cÒ²ØB†÷²Á§¥òR²ûYŒŸÔf»H?8£µK¯³Þà pöàÝjõö©?ÕäÚºF>#vA~²¥Ô[lx½%K(‡F‘ï¥H4Ô|“GuH+nÀ¨þ¨–Aë¥ËCvèD¾óo·_n¾ßÿỬ„ZÚ.’®YÊ¢€Ó‡d… ³RÒôXGàËVH„OišVìþ©'@F¥]¿-µ†kM;Sw ­F ÷ö4Œ(‹ÿ¢…I’r¸§I+,L1üàÒcœÎéäµîG¢çAò8·5}"¬¢iP“„u·Áçiœ¦©ÒùæjsIëú·ÕiI^º ®²¤ªTa¬U„uöJÔÜát¶[‰¸%‡˜AK9:‰íè?P¬û†‚SÇâÝ”…/6ÛPRˆ¡YºÖê(ñ¼Ç~·º%ÝÛŸŽò<;Zã‘iöPKu@,F§s•Aˆ3astropy_helpers/compat/_subprocess_py2/__init__.pyc½UÍo5³_-ËVEET.Ö^² Ý™¤…Rˆ*A½$Q’r(F3cg׉ÇÙžlí^çøSø×øxϳù¨"82š±ì÷ù{??{Ú?êqò×Që§…ß«Wn'ß@ÁÛ"Z·@µà˜·á€·mà8uÑV’÷(ÂÁ?Æ!ËQµ©,+c}£ áëê~äµO©þ„gÁyì—àCš«~@7Ôú,lÞC´Ây ÎÚpð®«6¬:AÒ!ɪ Ë.Ø÷d|Ö„Š¡V=Xö€wáü!Ø%…B䟣”< T_µÖ)—m¬ª‡°Ü  pXkV˜²Ì4gség,³ÓºÚ;F"+|m5“¸4µ¯jÏ2T°|áEŸá㼕z÷Ãâõ)ó3ÁÄ¥ô“ 6Gcmôä7a Æ`6“NÿO™R‚XSçv­56fìxÖļ¯d&?…G€J±Yv!Bž5¶Ij÷FLÒ°Ìi^¶Å¬1¾¶Æì9ÛG¶^2ölsó;vãúNoÜ‚vžªgI¢×J™¹à^aíp%µV£n7 +² ¹£8ÈUf9ý5[V¸Zù1yS&Ôýxtüóþ›ãø?êMr©7 EÃq0‹ã˜}ø -l¢¨WRìç|z*•`ß7Ý´9<ù×€¬YTnû~¨m¶g˜«‹ ±,.­ }[‡äèéºç7Ó[:ïp9&&C;æë!HÎ…Ž}‡î;uáÊØ=¤«¡Ã/™ªEhfOwChž`|ðú`׌:…µ–EæEPTF)'¦ÂÁžÑÂ?ÁÉý2¢;Ǽ00ÅœÏÔ´UcÄÍî\µ¦fH±€`…‡‡NNÈ[”|.>ÜòZ*žäiˬ0îr²µ;¹|ù"}ñM"¦Ó$ÃÓ`ªE:ªÖ%XU•ù$uu¾FV‹gIšJ-}šÆÕÂ(×® »ð”’>D£Ï¢'Ñ êál=ÂùÞ¨sMjšžÖÔ°izײÛD‡Ÿ^ƒÿ_Ê ­þ¡4¼Vb‡~Ž`~Òê·ÿPKYHáDòËF­ "astropy_helpers/sphinx/__init__.pyU;ŽÃ0 D{bà:жLŸˆkS[D ‰o9ÞbÓ À7pš&wK¢¨4?èΘK6’¬è&«˜°‚ò~g•2±4Xbü¨µRwhM’_n)sßx˜mP¸æ‘ÙLæ¾R»|N‹?-~tÅM¥¯ ~²ÕÒŒ‡ÞÝÁŸB8@_÷eåÏŠC ôßtdxŠ&XÁFFWF‰îÿܯGÔFæÝ4þðPKu@,F"Æx*¸#astropy_helpers/sphinx/__init__.pycUPËJÄ@Ì*>øžú¸7QÐŃˆŠ`I˜þv¹ò ªàЃÑÉ@àÏŸƒ#æ'|B¹2¶µªèÊs ˜dS4V÷Ÿâ×Zù¿¢£Š“@—$#æÞÖä.þ;…gÛËwC¢Ûý5©B¾m+«Jù²it³×½£¿áS+ ‰ ®„®®Â¥‘¿·Š"î=mU‘»(n ÉuÖRH°Ç ~ÔH*buxã™nÊÔn®z›Æ[Û8.žo„Á-(˜öúͼ ùà›¥]€ÈXxoÚäH_Ó&m–ñ Ç’”i]#aôëṎ½ham}²¿í˜Ø=Žu3߯H=•û ÇŸâ8&Ší8úw¿|ÔªrŸrÕTi)÷’„ù E¹_ 5G.”âr!+Qh}N>Dîèå1gE£QÙ÷Z)di¶A™6çm}"þkå•ýïˆlC˜…Þ£¤Ð±ùu@N¥ ©ahÀh‡(w¨þ^~Âò¡‚ž~ì(ÒjÞr°D:ikõœ«3UýéÒ'ËX¼ ég#Bëƒä<Ñ´5ðñdÅn©'ìÁNlÿ¥yîr®åƒÈIÈ[XÆùç¢çZiÆîQ·(aíÔXEUKWä±7•‚­7/ôÖßà€Y«BÓ¡ ‡ÃA‹Ä¹áC­Ÿ¢ñøä«ÁHÀ.§ÿUtÒá„£ŽK-tíÔ&»5’öE~õ§ÕyºüóDHCm žüÜEsI0£ÒÕd–pkÓSeÉ–d“ÁŽcÁiG  Ò±“’ÌÊŽ h”-îöçƘQõdÌ{AÌa»ÏÄn>»ÿfzŒÔÐòÑÞ(— G€‚ƒ#tçy2k« û±Y,˜Œ™tWGC>Î>!*2HB°¬²„£)•¼ƒðuHÙ¬mˆˆ+oáÏÛÝÒ@¿ëµ råÒdª½—¶LŸ!§Ú3- ËŸœŒ¼BNx‰ã6EŒdÊ¡G¯Žà2r™éT#°\9XN'( 'ŽÉ-–ì.ßr´upz‡˜'“Ôø‘ŽÓ§]`TäKéœÕ[³¼±¡ ²¤ÄˆG 5 tŽÌCYúC§ÓБ=:-2^÷µ ŒûÂ)ÔãÖzn Níš4¶75S:…žPœBð‘„Ýa¯e2bÓHЭE/ÍKËNñX ÅWkþW‚I2§/›¾â&#÷ÕÓ×ÎáˆþZYë&Q.ãPûâ«b)ifC2E±ÏŠÔ Þ:äyWŠùqÄfà*1 /áò˯“ «+½—¬Ü!…u’J|?@ pI¥–7ú¬Ìަm™Bƒô`ªíâ;Û@íTô-½IT“$=ýiu§uôÀ¾$«ƒ¶¿öàçOï~~íMúåðöžÏ•HÒ³ü¬6oaË"aê®ËûÒ©‚[+º–Ÿô'Þ1ÁþðÒ+t§E¤È½sn;dDác3rc¹V›NxªáÀ¶IëIðy;S•ËiÚ¬ÛÙ1²A½v\È6žBøî•ñìf=Îyð :A/ÌÃ{LdчPûeÚd "Oમí=«—“€ßüãëm‰  Jnõ¨=> Ù(ãÃïºS®Yz¡2Wp\”q–® °ïìÔ0ˆbq}‰H%·DŒÏ#¼%o?|tuøˆp×ñÑÕñ„Õ((…AwÙÌh¹²l¦ˆgàÎÊ1èöD¬ýiËóÞ|‹õ3ø•Û§¯ô·þu¸@“úÑÈ÷ ”Ç"TþTD¯iöØÖ9wÖè8"A½„—µ¯’s:‚i»Y²gb;Î3¦Æ„´=W”Ö»nÍõpÞMü6ñ«t­[.v§¡s{ÇÎÀ¶Ÿ…—rÒͯ)<\ôª?\HЈϤ,Ø'¼MÑý· A ž„öçü Ôhz9ìO¹Ø›Õ¸xëÍ1ÜLu°Ó; >¿é˜Ý”„zd¬ç+go$BÖ§aØšcßWùaÁð;?dÿ^\|‡¤$Q™¿ßTcØéA=conñ”¼·áq¿qŠVjîr¢Ë¿ð£åmCZ#:ÖBà ,ïÆ:]¿yJ€où&­ìº£äW†§Xñ{«­›æ‰<5 é÷i—µÒ‡i¨¡§Ë†ò­À&•U<™a .a\¹¬y™u׋¯¸Û-z3;Îóën¨íöƒsN¦>¯±û†œÖã…¬æÖN»fîŽà9]¼löž°h7¢ br]¢ê  æ*ÛîÛ×bîæ'¸·wÌ:VS4m©,‹S*oa§{çã…¤¡hwÂÄÒ‰ïZùN>w\ó\Ð]xnLÈj?Q žs™8Rq›êÃçä„㲇 “!ï£7•påp†ÌI¡Üó\’·¹Z¸…º¹ÒÞó‘xŽ$ØÐðAÄqü,“urnY é×ZV§\áúsW?B8`3v­E8"zKÈÏÔT|G¦û^Øtî®XdÑáZw¯ëæl®šAU—‘D‰I‹¸ 6%hÿÛÛ×îFíñ¶p š¡&Œ7ÎÙª¹Øt:]Ó½3ï„'v½Ñ¨“]~vÝ¡7 Ý“ñ`:¾"ÃQÌ ¨›v‡œ²ÿ^§ïä¿þ*þ Ù¸Nѡ۠TìEÎí#ª×Qúu4âѯ•W S%L…]z² b†³jtá":<Ä¿,çðŸÖ’ˆ¸ÄÔ$†Šº ¡8\1µ>6X³é¦¥V×JlXšæÝ…=_þŽyÄj©ã­i6ܲtTîvø¶‘ õ œîº'DΨHð„‡Ò§»å »`''0˜[sË$—Bø£Û7DêSï’Ø6ņ´^ú6ÞÐU+wô5rC9¥JäOɇˆ†¦á»<­p7Ü”‚±î$\•ºÒ@æ™;¾Á ä°"ƒ‹iÈL‘ÉwýK[*T€ð;ºæFêÄ®Zô~ô ="À¿…!áçƒ`Ä.wC…/Ó%Mw¬.­ÌZÛR¯.ö¸Õ¶½F#KÍ·Ë8ÿË?æ+¸«‰‹•‰Õz’KYË é,ó퇭^ÎNh'<ˆZ>dk¼ª|"oÕäba¢<ö—) qÉý°;pžòvÔ@^Ëk/d €µ~íÚ)zNC¿ðj÷3¸”¢A²‘Îf 4Žfâ†Á]imºªsÚ6„È=cSô²î“³þ¨_fý«ô«ëÕµ8›Â×Î eÁV9u÷F*µ4ôbrñ[¥xbå~„áï.üÔcغ—Cžî“e†™g/$úàFzþç 0ËÕÑÁãƒëÕ’.\††¥«ÿ\_ßMpðìÛ-úÃ{è¶èî¡?Þ¢?þ=ôÿz‹þë{ènÑ?¼‡þÑý£{èoÑ?¾‡þ›-úoî¡ß¶ÿ·÷Ð?Û¢ŸÜcÿmXeªÉ®?½Êñö)¯ÎêÝØ}lÛ‡íÙÖÌpãŸÓs×x ýÀmÈ©pXʆ|aü ×¤•™X¨™«¤Û»H“NDé~#BUžÓ8"õI^ÊêB5º¢2¹‚X€æë÷Gh°À\/pOÑÈÕÎá5½È ‘î$7ö‡Cì'wîöÌlÅÿNg«ò~ìy›‚hÿsâ+ÄÒM(SŠKôGq‹Z·IÜ¡dxD-ˆñµî~Ü SXÕ mZŒd…xÃRx“¶ºo5­å¯u˜ãÞˆælÐ--Ÿߤ÷jA×-j-9) ñ6µ ôSjÝ·Š¾YùÛ*ÿÏÎ ö–LÄ7=]Fc­±Xj¥øo} GÎF°|`Xrí‘ áï J™Þ•h¿bU¢SÈu‰Þ¹öQÊÉ|Fðã£çÚÿ½D±ó­7+vÕ'_.Þ9<Eª¥ŠõOh¿2,¾6ìMÒ“ñ1+ÆØ`uȤf©ø[&SÁ™Q¬ÉÈ\Y$bã`Œý ²˜³ÁÚ°±b0U«§chf­¶R›ÌÈPï:æðø½RZü’/f.€àyÅÒžç»Yld$~—¦*uü:*|ã2—ñljŒà£y»3v–[àÒÉò£Á{ ÝC¿ÂéÒl[¹‘(}\_[mlÖŸny[Oš¢ÛmÂ&©Jú^O„ x4s~Í@ÅFÒ7×À%è‰àÀ_è¶]ŠG¥¹Ò噫¥y¼Ë¥êŒ¾ ZϘäy³ óiˤã©´Ûtúå}}ëã°¦¾ÑP~ØÌ題tCƇng ¢fLt “¾ãn3΢¤ß„繦~t&Üõš©èˆTÄÈ':¢§˜ˆ½IBeBÙÎUªa蔦'–(Ìë°"njã·C°¶JCú‹‰)½ÍS|è¡MÓ6KwôܶjKk¤Ú89eÌű±gQµ÷õ=¼kó^åkdñzaœ(xˆß“Ü“¸Ùpqw’{O¤Òø0¸Ç¥ßMýH/gä–¦¸½´‚ÖÏÆCV-E‘Ÿöõý)3·h½üIP?‘Ó˜p‘˜^G;ï8 ¥ìv;?=ôü¸+BÕõÜ©˜f¯C)ŽÅ…~x6NÃDÆK…V¡=äcŽý@3ÛÂ¥ˆFòP°@e“±2¬-˜Œ„/ÁL71ïu É„›¡Ù‘ Ã\„Gœ•1"¬`*3Ifœß”ÎÍÛÊôœ›c<Z_q402©ŸÔG‡æâ(@À¼ž‰BmÃâ£GyH~ôÌy4»"vGC_pa£Ž=s}I'ñÛF÷ÀŲ‘q`ZÕ—–Ã2gËm¶ü'=º¶Ì~Ö‚ù,R©Àƒ‹4®‡Jȸ‹n¬tâ‚uìk{™èà0  7bžÂqö‡50y ÝY±Ä’TJìË`>;óÂ,kÕa!‚¸f>î;Q7À¥¸Ë"¿Ï°V~e†íd&KÅcÛ=êÉ Ç„üØnE*"Uîøá„F„hKÓ΂a\jËô@Ä[¤¸¤Ö™hnoo»Øt\Ïw°n”ªs!’°_·2 >¦þHÕamO c5qGb°¶é¬ñ:—9ñqú…6L['Sñc¸µ§C9—ò;wèŸNÐàÐ>¶7ôÊ[gp0*1Ëý5ì³Nª"¶cC\¹¸Ý3W°ð; uŽ©kÓ…½ÿáØý°1®Ðq­P(fÏ™;¤2±r½÷A§†NçCÂà¿ðƒá`ÈöÚ©ðB¿-Bg•7Yb•SVgö´:8û9–ö83Ø´mm±8k÷n1ËáCÒXËäéÌTÛû­B?Åüï{0 âM:X_Ý^öD¬á26Hþº:~¿ºúݳ üÚüú~} ~c¿qò?™À?™‚ßœÀoNÁoMà·¦à·'ðÛSðO'ðO§à'íÿl þ» |}Šý'ýa°È4ž½ÊÆä.ö’¹í´i“›]L; 7þÑ?¹‡ù)BzwÑ…ÂEÜ+B/Žâ…; ˆÚu]#±è¸PŒ¬,¢‚E„Ø`ç"r¹0Ž“„O‰øP¦*¶ùþle †^ÿˠƘ;ÀIÿeN5ýD –Ö†v Ð1‚;çÔ¼\Zƒ><³(v£;÷nwKÖû¡óädÌy9¾Ì)›aM¾°©½½åÎJ±wrħ$ÆôKŠ‹IOˆ À§åÁø2à•ö¶ráÚØ¹JïÒ¨ÖŠ…ຨSvk£"uGÅ"Ï·ÛÚ¬Ž¸¯Öžs%[jÍë{^G†uÙ‚K¨OÒ^/ò“+å˜Ë`¼ÄÕX›‰h•¥H`uÖA–W”¸SÏftV48Ÿ…È®p)¹qäížH$2 ×…càX6KcyW‘ ¹ z,ÿÚµ¹¸«:O®GzY¡—Í^»L-/7/¹Â\;3EZ) 슊ü×õQýe<ÝSGN²Ö^$Üý㦼M3ájŲm¹J#ÌÍb O˜=¤l&Å^Áô‘¹RŒåþ-£(¿]Y(UÑ›«Tgð­T«*Õr¹TËy_(ÍVªÏ«ëÕùÿPKYHáD¾7ù¤ÉD'astropy_helpers/sphinx/setup_package.pyuAKÃ@…ïù=DƒÉ¼õ¨í¡P¼ô(ÆäµYœn–‰´ˆÿÝtAÅsÞ7óf´õ‚¢§)ôHÄt[w“‚îv+R; H>ªIÚnî×»u“ÔŠ¢Çž°6r÷´=_]/ šµ MPc²—:‚ö^ ÙM°)zËÍE%«¥1žÛ‘´Ñ8øp*—ôøÍd's†c6¨«\UÞüdìX\ÕøðúÛÊW¨{G›Ó8Ö_¡3ýgÍ¿ìü”ù.<½PKu@,FÕç÷(astropy_helpers/sphinx/setup_package.pyc½PÁJÄ0MÛ]‘•½(ˆ7/¥ÐFA‹Á›‡=Ø› %mBL7ag*Ý»_ä¯ùNÖÕÃ<š0/É›Ç{C’Ïùìôå£jÙvET÷T0'Œ½3öL—ˆUiL̯nJõt'& 3™09azÂ䔕UºG½ª9ªÞ[ xÆ38 ÖºVXžfùgôÆNõÔnœCÀ•ð¹ Ãù5I28ÿK(дÝ1é¶tÝ)ëÕ ðYŽi|à‘ Œ•¼‘°èEë`Ì//Šë|¼)ëòŠ+­ùŽ#ÿvä pðµí«Ðªðk<$;­ð‡ª¥@‘„œYH‹“8‰Â^¤á£Ÿþa }²»í¬ºÛ B¾PKYHáDvÕðL^&astropy_helpers/sphinx/ext/__init__.py5ŒÙ €0 @ÿ;E(®´lÒDp{+â÷;ºÉÄÖ†Š9Tºh’p†ý˜r†7üH5b__BJý=lCï*åÌæ¡éPKu@,F@Å‹%ùP'astropy_helpers/sphinx/ext/__init__.pycUNMKÄ0¤[‘õ.þ€^¶]A"^½xèÞ Û&îòE3‘öoù×üND&yÛ÷¦ø¾X_¿}íGø{œþó;ƒ¸¥FR10–AÇÀrè8غ˜ä 0+°%t%ñì«’–t¶© <ÏúSGí^é‡èMB%´ ~B¼¤Y˜´Cñ‘܈$Ó,ogÀl¦ðZe¾&$Ä4)!ÚÓfaËÿ³\²a‘~lsz'_†¤l©#Ö¶}œ7·Ûú~3?ìÄî®Q‡CÓGœ|XÄQ™ ¦ØÄpÔnnÔŒÚi¢ËoÜ£õ2õ”ˆùˆþPK*xbEcxÈ’W 0astropy_helpers/sphinx/ext/astropyautosummary.py½W[kã8~÷¯8´;X.Žh§»/…2tvÊ20ÌKçiÓ¬£Ø'‰Û2’Ü&0ìoß#Yñ%ñd kp"¤sýôéø¾ä)V3hª ¸¥…h4ÂǧO Í¾@(Z˜F„/ŸüúôÈ•6ÁÅÅEðm›kÐõ6¯v€;C’¹¬`ÕäE¦A®×ô²]ç´ÎEc¤nÊR¨ýŒ ÒEM Z–¹Ö jÈ Ô 5V†Æ˜-ƒ6JÖ{Èdªy@nJAkNƒ$(Šu¾³ºÚÉ{`Ī Ù “WHã¢ZáZ*«‡V™ Ò)‘G¬R´N]<©ÐhÝÙLó²–ʀ X+YÂtRàÅú© ¸„Æ‚LV}ƒUN¡%¹ÁRíM+ÜÁ=yâ©,ë¼@¦Â¿Øüaöç‚_}xæìÃݳþñK…Q‚Bë Ãl0Žî 'Ã5tî˜ÆbC%JÔ~Ý>”ê7‹›ôß߀3sù¸qBœqH¬^‚ÕKÜY²—Zí“6@«ItjJ»ë*&>U›“.n÷ J¶hC,`\aô¸n‰¥9‰ôò‡HHé\|ŒÞ·-¤2_ôs¥Ø¹íJÒ­Pvñ·ë~‘8ì6Å2ËmÎÝ(á,×u!ÚtIÓþY»9›’2ú57[þFc#ö˜ßÜ-NÖ'qšÉ yÍg7ƒ„ìcÔþÔÉx{’Q4Àñ¼'×Êûà ÙÃ]еÏNõQ)©Ný¹Ý|ªbá\´Õ3à×Ö‚*/Â;Â;—\t¼Ý:.êšNæc Ãöu§*©¬ˆ9 Ž¡¹´EJ…_ÊŒ˜OíÙúrÃßó÷®öÜðöx' ¬Ø$„ÜßÃíiþ]Æ Wß R¡ˆÐ'€{+cx‹uøë[RÝɬ¡ºóä™ö~„ÑלŽT{ wFa‹Ê^ Þ€°–I‚óO]ë#3öÙ¤t˵Aô…«‹|³5]8ùz6Ðb?.®Îª/ò~‚ Ò‹ü1Ûy'%(ÍÀ'5Ý‚Á&*ñí¤uvÚÊm‰û“\#ö«¹gq¯~†ÊçSó[Kè`jþ[v¾$[Sÿc‚GšÍà%Vmóp¸7ÆB4M @‡v)LͰIFÐò>ÎV£ÆSQ{o® ³›ëøø.™¹‚1‘yëòøjd4Š{÷Ýègè—+$G)²ðÊ¢>_…ÑY<ÝÓP„p$k¶é`ÚQ2E­m §}U²(:rôº%9[ö<õ,_/¸mPê)fÒ:¯eꨂ –̰k£v@¨tË.à‚—ye£‰VOö¹œØaßÝä|£dS³›Nÿô&ëçLŒ“zizUâØ8Ú3ä¸àUÇeÔ™ðíbÛæíC©q¢ìÈ¢Gû*¤ÚÔ{lÛòT6tŽ9 ’åN+é>4X8݆‘·é> <ñÚò-šÂ m}Ü¢?t@V½K‘eI–+:g¨ fáÐK<ÑvGÁ?PKu@,F?ÇL•ï> 1astropy_helpers/sphinx/ext/astropyautosummary.pyc½VÝnUž³ëØÉÆn'q“þÐ¥áV©Ó"ˆÑ–òs„záDÒ¤›÷ØÙíþ±ç¸u¤]¸H%îx^ƒà9à‰à`fÖvRµ¸ N<>?óûÍÌ9Çü£aÝzÿËŒ?&~?¯ÚAâì"à Ø<6!4 2a×!ð*p‚Û3àÍ€4¡LUxpðõn¼Mvk¤f»=KÚGbíùÊVé‘l9Ò2V~Û‡C?ô”ôûøµÊýîwÜ¡NÔ0ŠÜìøÀÖ‰Õ ¥ÛÃÔVI$m_©¡T¶¯í4“JÆDZ­¤}Oé,Im/驎…f¥¹¸ÇÈ^ôýÉ*æÛ°µ{âê@jíÇ»7ÔìÕ¡ì'ÉIKÆ9ÉBhQÆ=IFÙŸž«$™óÿÄÏý¶Àˆõ<’{§Q¨Uœ?j?¼wcw¿sýî^§}÷ƒ=•¿qíšngé÷išHÛÇä œ`” èn³±žä<~«øý„x1¦Éˆ˜F “’YT ª@1"f ¨BPƒ`Š*ääUÊpQƒ@1K5PÌÁè{#ðéþwFaAnA1O4˜×CöM±$®”ÛEeqÂE´Ž¼1Àq r“¹j×pOuxß BõØ‚ì7‚=ªƒ7KŒ-”ù, ›£ôÙ¢øfb_és×Ù’ ÈæN÷Ðçç X€ø-8å™gž›ÌS9å)Éü9r.À ‚€Ó Š%È— X WÏ&þÕi÷¬óÿgý–]dÙŸ'²ÿ"»D²Eò&¨_2á8¾ X3º:ǡ͓Ìùº ù ±z /3Ä,,ƒ·ÞÇӽªW™¶ÈÊSÊW`Ô†|²}©×„õàùo“jóo}1v4­3ª“‡ny†œ9:÷í¾ë‡Ò;Ñ›JÓ¡âÓáï“ëjãŸeS7S’1Eyµù¯%‡ì‘Mß"Çç8º‘Ó;B}ÆuE'×Þu&ÙíË4l‘g/½º$Ñ%÷»ä~w†Ø‰(íjɰLå‰*t¥I„2a•¼™VO}}TЦ¡¯ùÄþœÿ,Ë’ú§nk:UÝ4Å€•„¨š”0*e*§Ù-cæLâݹú4“,èþf2 Ýžd+T™l>Í’¦“J‚™Æå1Ž/óSV‘&©®ã¯ãk,bTåXݬwÄ*ƒÄYl%ôM—¯+öy;äe`véžéÎN`e\«”:šóW+aW<1tÇ…½úB­;OÜol®€iGq,»Ž`RÆ„(ñ†áXëL:±?Háìr9™å—MÄpK„º˜¨m$üÊØ_ ÿ÷>3»KîRÔEF"öDîÎÎû<3ä¥xnd®d"š<‘•ˆÅóÙ&‹%Å?ß½ª~ȤÈô1JJñúÕ÷/ß¼{Uª]\\Œ~Þ§J¨rŸæ…üXceZä"NjuQd ÿ •Ê,Ý>ˆÌe×i¾õ^ŠïÞ¾%Ŧ9ȼÆUìÜ•øNÕUQ>ˆ2ÞÜÅ; Jy"âí6ÍÒ¸³öz4E‘XÆM]Š$.Óùh´8ñu«D’VrS§äéÕ,V»NÔñ±9òTW;f2ĵ84ªk\ ßà6D0,FâU=ºO³L”îmhÑ:+6w¢Ø _p&•曬Ip)÷¡R)WF†ê óJnç+#•j‡UÇïTk¬·h–¤ñ®Š±0ÝŽ@®"Að70ºR86Íùd-˜ßŠ"Ïôµ7;–À?q¤W^Æ)M*°‘XRžSA®eùÁÆÕëT-ãG«ÎF«%Œûªñf#ËZëc[dYqχ—DMÁÜŸ‰X­æy1KsÈ”Öq¾‘VÔùjÅKèaÊJ*ð2erÎra– 6U^°9Õ¾¸Ï…ü sÒ—¥Ò©§z+«ÀÈáHÝ¥å1T9<°[iîxi²Úê¼]¢J¹I·)4X¬…9Á ‰LÔJ™LŸh˜ÌõlO°¸%d|©µ„ =\ðlyLâã ¸jéäÍaü@FOR‡4‚ëguZf–O~X„|f¦}æ1K9z_îYZ1"G«pŽ&ß°äùl í:¯¼YÕô/¶Ã¡D˜†­\v÷pB° ú&{gì¡5¾ÙÇU¼©e¥Äz-r)4ë!S±^fˆµD2œ†LÈK¬Œ=”Ü8–àt²‘u`èLÆøuÝrÏ'ÃÄ[|×ZHˆ—îòÑZq¦ 1!Š˜¶Þì=?† jȽdÄùûKÒ>1l2<ìîxØžò‰r³'ãîÅì—‹©¸ß§›½>Ðê­ÈHLÛ*¡%óö¡Þy ú¹6l¶R8é{CÖ”G¥ ît2åŒ5m5*Æš“F5Øó@G+,‚°ç§Æ\=í"1)Øû6•„½¸®•Ú¤ÖЭQ­)ßäpÓHë¬uدދåöNŠ ãùy|èÔýV_»ˆ´Çà Õ@ð˜½W¦yþߥÊn~E³Û#/ç5¶¤êŠJî*-¦T,“™9kFŒþNè´Õœ3˜Wuekµ>ômkS—ƒôqÚÿĶ*äðªÃ!ž)YÆ:²T;´ÍÌ—1¨¾%ÆÂLue3yKóÄÕµŠ;ˆnÔûfmi™81?»€lª LcƒÎÓŽDÎ&aèŽÒHšŒ“êûÂÆÂd›îšÊDa[æHç],ëbSWR¢Þç£ï.u01.Áb)Ï ¤“6è0ÕC[dÿا»}†¿õ¢£qÙ¢ÚYw‘[Ñ¥x…¶BvÞ•È9.“¾‚N—ƒä¡JÃ]˜[ ºxÇìŸH– dÚ]H!¥NµF»(V@J\älòõŽå„žæ E%˨Õ€Òþgå @Ž_.É)b„%:*LRÕX7iVƒZš×EŠ$^»}-µIÝ sg€ ô ‹B£5ÄûÑG$ gO.üÖ¶œ#ق˵„¤ÒÉPû# i•Ê| ܢ" P ªíÏBÙoØe¾©5±¸k_˜ë[$%x_"Qc…íâ–¬ºAž¹äŸpòÛgñ©¼Û~~æ‹ûD}n/ÑÑèSçMYšËÏÚ¥|ú¶4iêßë_£O›LiðvG·ó¹hà€š›ý3Š»9_¢½TúLj<•îÛ3°erô‰.Ÿwl[[¿ð`tD®¨pú®Cz¡;$ëçú¼´=×?e•~€ûÎÖ1”17×âª`x¦™3õÊ–7§¯¯äG0VÉ>X"Ž«à—ñ?æïÕä}„?ê‰3 «áøæ»ÙãÙoOgß.£Û'aÐÖë¡O`ÏWc¢˜ƒØü;±ù~vûdM¾ 'a0}”Â6‹wjü÷ëŸ_½~õæ%ÅIFø}W¨—¦èÆëâ•Å„b‹N4¶Ù:´áõ”0ÚÒ±–P«¸Ú©¥ÌÇ.ëá|M¯‚é {£Q"·¬^šD4VES!ƒÔÕ”:A®n,¨LÒï ÙvñÍÏI­ØÚÁ{Bms²*ýÿ“Íx«ö¨Ð?RME jº°^¥-zÑjÂÅ(Ô ´™Ié È¿ê]PW?¤¤Sãí¹Ú É…²U®^Q®fi”žd£Þï—g˯Ɉ†L›»ÚŽC®¬ζG‰4àÖtÆì€Í5kÞíwîZª·¿I-!ÿœµþÙªX0:÷zfY†}½Ü°‚¶¹3k'zK¨†øÑð î‚SVšT„_YºÑœ~×}_ù,­9k Æé@°šÛ—Y¸‹‹¹Y1(Ç6Â@ÖÝèþÔµnæ¼è›‰NëQSQˆEÑ…7 ¯U”F†¹h1ò…ƒ‚[?ä§fvpK‰q/ñ¸ZQ·uE~µ ­¡¨ÍÅï òH½pcÀÚ»œX3B¸€=>¾]ÁqwF}+e‘L Eí°TGdO ©„P0 "­ÇñãŒøâ÷2ÂNÖ@ÞíTŸžÖ ê >Š¿‰ëc)Š&xƒÂ'sšÍ[bJŒw¸øééç)7â:¤Ç©„†o‚œs¬;C ¬Wš +<'#ø'}îl¶>Þi0\›d‡§ŽƒŒ DôØq±†NŽ«e^k甋À<ñ ˆY68 *‚YI'fRΘSŸ7þ¦·ÿëûÑ…£¾ðu™ÒN©‰5œÍˆuêv§¹3tsjÍ£Zðƒ-$n6:wÙ„`ðô÷ª}1ÁN|ªŽi$ÞД<1!jñ$F‘MÅw8Ý×…¸“²4¯®$ÝÈ%çy òÖé[Ž-èo·†ìv„ÇÄø-—3 æ¯kái¯Øž{Â#ÕÜß »¶÷9Ý1Œø úévÛ¦Ø/t|Þs–Ó?’>ÌìÂ:߯ñù_ôåí;¯–«¾Pû¦Ó”H?CÑ}ýg d;‚§„Ónèå/r:ç]8=œ×‘¾LO8áOÐQû¨Ekêú¯'r–ë÷ ? zjê1íw–ÏoCÑN©~ê81Boê4<0ê?ˆ÷­q)Tqæ…²½|`7yJÃð©s‡—‰$vù‘uN¯oõ)iIÌÛÓh20ðH½rH–»Níѽu£5à.?£ìŠIGŒué{K Ï&ñŽúw4<, š¸Ñ¦³ÁªÚÀME`®cœà>ˆƒžzo‡è6bÒ´f2yóò?âÅ¿¾ŸLÞç4¼ytI±DØÜÔÛo‚³Ä‚Xe €ôe¹?K–AÖÚÏŒ íókVuKô³4xóhG·ÅÍ­‡¾ž‰½ 8` ÅÑdß$¦Wøœ·ŠãöͦXÏüø­ ܰµû6*ÝiŸ÷Ò:=R›¦ËZ;±à»a˜Yê¶ÿ£‹õ¯”C;7ñžÊwÒ7N˜ï9qk˜‹Éœ%ðOiÌØCBó%Øð,©©Cn;#é;–,ì´'•ïz Xëä:ê´¡ÜÊq»]?QZ½8 ã#ÞM¼cè'%\TKvŒfAª0ŽQÔåå³6à´û!xåÅRÑËa€"T ŦEv0B° Oªì±Ñ‡–xwà¦nWù©têkùŽf}“);®F3Ä2"!vC$d{Æ\Òï4Áádà"ê@Ñ¡ïâíÃŒPqRŒÛÃØùPÇ úQ ïÛ4´ÜPÆÎQÜ‚jUw0eÇÐ2Ž|"q<Âú„¤O ›½,lK9n:÷ýžË–ŒÙÆWÛÎÑ èô†VnqGbÚV™GÇjGwäÉXކö¦(„ﮋ³ä82ð0“Ÿ)N,i+Q§®9ÉÖÓÖÒ¹óÉÍvjÔuÂFsOôb¶¾nêC_|¯%Z¥VÑ™R­* ¶Éîºý.@…™¡@jà(\ NúΆ±üÈæâ~¤aMmñ0œêç1kwÌm4eÿy˜¡èFîúÄå®"Ou[u—JTšK¡Ø÷f¯1ú¸Nv›s³þ*wìÝcµyÛ»)Az;mN/‡d°ªáÐmH?qµ#…6h7˜+¾Æ úŒf[ßl&nižø6d©bÞû~´oi?1¯¹CŽÒLcŽÓ…S9„!;vÈBŠD®Éy’:Š­ÁMzA”/Ì®9’yîmwUêû¸ï£¡‘w:81&ÁÇ’Sj ™dNÏ Cœg7P!Ÿø® Ãñ#0=Jp6er2‰ 3†iBÉíS ]Cŧš4†OÔýf¿¹íHâ, ]ʒȃÈó_5S©:MíPÅHÓéÜ(ît:ÍwÄs„k„”« £ö=#¢ÇÌ—–Ï>2S%=§ó$ùmí)]·˜£p*BÛ1M)¨/™;,EàiLãÿÇæ“xƳuT”3>fU3Ë¡4q|šåé(2îT2Rš6-kÒ™År`Ý?6¶yÆ:ˆ›«Fdò&ØÈ8“©L÷úäqÏã‘›Ft#R>S¾ˆÜnÔïÖ<¡‹ÏaÍ~g:GìÙuJ%»;;š"Å”fœöw`¸zvà ;„Là†?ýAˆú$§q+Ëj9°ü?ƒê:=Ô=XLmxµ”?¤ö¯dñçurØS¼N8ðä$ÑK­ö:§‘?©É¿$ŸéøT{Ý ¥FÄ! ~²»ëd»°wMDk¸wDk)âé/‰ôç6Ö^Óìÿz9¿—þ_e¬; ‰î}èòaÃ\Onš¥Îïlœ¤ÁK(®±ïâp»æ¦ qÿžæÂ„iˆ5_€‰¯ê?Ý}&·ž5ñO~P¨ÕºYÿòÓÆžÛøúnãÛÍçlv»N+" ï~‰Ì·Ÿ5ž°Ûܺ½¹µ©fHѡۗr£Ýzgs·ÞÜÚ¼Ý%œ[øQ|F¥ê¿¢„8(‰±@é+&3B•Åx†Æ¨³«"ýí̸,Ò¤úv2+Æ%q€:¹*&gÄøŒ8þ¬88CøP úõ#LGBŒQž7ÅáœHÿFŒg©Zä`Žjv,¸ôËè‹¢Ù1-›ðfx«*ä×úàê¬xÕ¬ªZ·3â*~Ý~©:™#ØxŽ`ÁóåµIÍn|V¤oi09'¢5šÜ^™æPÛOæ…:'ª“|Åd‰z“ežáÚ²"^ý›Póâ`¡¸] Û1¿Ï@ꂘ\ã ÔP8„ÐÒÒ Åø¢8XoXÂ¥÷K„1Ï[RË›àÿ™‹¸ÈÀ_•@àǘK¸ÌÀÿ,ÏŸºë C/Ø÷§$Íó,ÍY^xµL‚?O‚˜¬’À¼óÂâóíò„G˜£•˼²&…HÇeG¿$ưY&YãKâàBމÿãsâMY”`Z¸d Ëâà"ñBIð²˜\áE+–1|K$!½-–a&!ñ5qÙ[šƒ·9fËoËØL­Š1Lc^x˜XÅDéYEL®ŠÉ51yOŒEºQñ.×ÞÂ|#J“ukëb¼$Ò¿«ŒÏ’Õ¥̓e]fžklÕÞU1¾*ÒvÅ»&"Øá{Â[' ªŠw7€çˆñ:6™!}D÷Ä ÊØ”éy•Ÿëü,®!³¼Nž“þGe|•;ËÊ%Á΋ô Ô»iÕ8Ïj´(çEºX5 ÏÛ…Þc^géÞã÷DúEÕ°VwKŒÁãmãÄøXªX²×Dú×vŕŠ÷yÅSV,ˆôÛ*­ûÖ®[+¬»ÃëêX·É|æë·àg´7–^üZ<…°èìåÇÆ-¨à73êš;B½G¦‘ÎÍ`<¹)¢U¬[L-€›…HòõŒºÁáÍaÊ@ƒ\·ˆˆ÷=ÿaKL6ÄòÛÞ6ËS¿ŒoŠƒ[Âk7(=Á?ÿå‹ßœBvÛ†@ó.Ó\ÏižN†äàˆÇßñþ¸~ÂúUqÉÑÍÓÒÙ²FR P‡  Dº•RÞ‹œfÃÞpúîÙÈò²bÚKÕ¥ò‡ å'”' ºë<*‡‘ª½ ¨›b®XS qþ˜Ê>Kõl?”J^çŽf©ÂÏ»CÙ’I yýtÆgùÝ÷±yF&Kðòt›pôNΡ*°·ç›zÉ4[èÍæô(Fû¼zº¤OõõÔЧ.¿6²~ÍDìpÁ7Õ†1uK°¯Ñ +Ýß=4Müè #âGgün’`—Ž&ÕÄ[t5§ŸæãÎ4 Fj\sPS6 ¥ÿÅRßV®³±k°`"&q¶½ky7 ö”W§Åtm#¯L•e-jÛIâ Ò½ïxªç^Óé)f#+»6 …Uf‡Ü57ýñ¼©’QâRŠxìt¨€ß!»êlZEsí÷®ÒŠ%!Õ¦“L¹“SG¥tQO´AEÊm'ȫꮑ:ãÈG½fŠîÜo¨Öêd:ஂ•zQyÑ©+jH¢àÔõ&sx”Æ Û‰VAV§œ¢W]˜lS!Çãªøˆ‹ÁNξE½3)GºlÏ»$ài³gü¢å«QM9#ÿˆÝáû¼¡b¬›ŸV#¦¤ñB3˜my覇£DŸ–kY£Ü×Zª#+xm6wÍí(úÒ)àÁ%k²Œgã«€~)úFŠú·ò§wÎ增*ô‚ÔY€l›”9È[gœŒŸÚ’WˆÕïè1ÃÛò#<ÂXüˆºQ¶)&zÀ×w'Ûל7é î²èâÓi|%×°öóxDßwx^@Îà†6H;r ³ÜÊɤßTÄ9•NaÜ…u0¼ü¡ªµPù¨3˜5/¸ÃxŒŠ‰Ea«GÆ1Í9Æù“Az™ã`M@kÂU$ÛébSÜ~e@å ëš)›Ê0˜³+§k=ÞQ—¦HÛy˜vÁš-§*3¹È(bgnæ’ae¸¬øÚÖÖß=uîñÙÖV­Æö2R½?”t¦“KŽê·-k…ïâRT÷t‰0¬"\I3ËM.dY™Nö´X¼Ôf"ÇPd²±dÒO˜ 2L½ Í+¥nñÓ$Eµ2Í›ö%qtÆ´ æ…¾ëˆ<Í(œ2á &u@›;xe®âa¨W^¸ëD½¸xª6~š"ƒöSuá9Ò£T«ïÀMAgºE^7%¹“í.6ð@ÒkäÑ|æQPBÀ|{>É5txo#ÆÅäq|Ôá5óxL»P ‹†÷b ¯ñëTf³²›‚¹24 øÌ…¹‚X½6k½&!sm‰ í¦Vê«‘û©V¹¥6òdrfLÅäF¼ ¢pƤ)☊“6©…)ÂUZ¤F4Ž'Úµâ„Y&µØiÑPöÙ4÷ô¯yK,cFgXð7&2p%üRPWj­ŸËµH Eß©«åwý;e·&df¤¹_¯N¡žòÏðØ¡·³ïR5‡n7–¯÷î6ÿ¨ñêÇ?jÿèwü~ÇÕ &HòL{.ëÇ™@™³,Í\Xoh«§ ß_*­”gK³¥ùÒJiÏëå…òly¡´^Z©Ì—æÊk•ÙÒ"ægñ»ŽùKøÌø\*Ÿ¯¬g®|x4š-m`æRåzi‰W_*_ÇúUÞiû¬€ÎBy‰1é_­JÏe|Öù÷0i¶¬|4_¶£õòRy¾²„WËó¥Û¥…ÒrŸj¹Kš%+ ýqëè_·ŽªÔÐUñ*:ÁüGã2ý!Åß qÿù/UÙÜÑ¡žÑ U:‡gDz‹ŠäÙÌA•š?ToU¨€O|ÎX`•0Ó×\Û¿^¼/nÑÿ§º×„×&g©?;:˜5® Ïq¡"Ö±ñÕˆc¦Þ« Jâ‹~h¯“û”Òé¶¡.ûsúž°ð§ nöõ ¥lGŸ[¿˜° ç@¿ò¦™¬%©SöÉqñ*PívSwjÉ[w¬}$-2"ãªô5…ÒcÉ´9€2GÈ™}'Ž¥½‘Á­l­AÊZ”e°µÛä¯ív´Ø"HëOéAËZOìvÆ yÌy" «÷Ú)Þ?àßðàÖcë_?ˆ“µ¶AïÈG^$ò³µ29Ê*þÍ—ÎUÈ4Ù(+E£¼©rÌ1´Ë€QÂÞÞT ècurÂÒCNyØ¢žskƒ^‰XëczP—\yŽ.?p,1wTáb~L'îD©K6BŸª=&)‡;`_ãF÷pÉÊÜð¢÷Šùë(èïM%Í„`baÐÊ÷) MsÜ4Å%8n*9Nu ¥{ëšµ[pÝ¢ö“Ô×(ꂤ}·ÇV…,'‚A·Ö‘ž¶uêÓ~é†#Ÿ5ÁÞÀß`°:~@ñÏX>Ÿ’ÄÉ/bõ2bn}ÕzE»²Ýn='~È·øfKýV‡ÆD®JöÚVƒ;ôhÒã®%Ò‡ Ê&öÞ_üÅÏŸ<øùƒ‡?kQ^Ôºe °u#³G²~R+šÀ#:÷Ç:zü„¬Kn°ËÍ—ø_yùììþÕfqYÌ—¯àÒ™ÿvéÒ\õPKIz)FP:بnKY)astropy_helpers/sphinx/ext/automodsumm.pyí<]oã¶–ïþÄd É©­LÒöa›ÓÛöb€¹Åb3Å›ä*²EÛš‘%]QJâéö¿ïù )R’íL[,ØõÃL,‘‡‡‡çûúL¼ËV²P2m‘ÊZ$â«ù*OZ%Å÷7?Õìs)r#æBI)Þ½ýë?ßüÕª™¼zõjò~›)¡ªmV< ùÜÀȬ,D’¦J4O¥H³Z®šìQ*±.k¡ÚÝ.©³OY±ÍVŠª]øÉNî–²V¢\ »2maY]%«ÉFFXE°¤†Éu†Àò=F¤Ÿ²fKp’¶)PReq‡×l²l±J ±”8!ì»’ðOÑä{X(ŠD¬ç"®‹Éäzü3qFuˆÍt²ãÓ<‡ ÀVWR>¯Sgÿj΄o’%ü‹{ÓdJš¦Î`RSJUr•­3ØÓ,7pB´>‘v9]ZLp*›$Ë\ÓAÀh%•Š\ì’¬”×kYËÐ\×宣®9évšmÒôˆZþ³…1 m’ÃeEÕ6 r|ݾ&4=©*™Ô0ˆV#2ÌÄÓ6Cš –«¤jZ„‡¯áäê 9Ï#i². nq²Áº*©7íf3Ê»V5ÈÿM:þ{ HåªÉj%«€{QV ˜¿­ª²nà–ûòt8Ì'(@‡Æ9HôWDa©ÊpÍ$ŸèÅ?|ÎÅÃÃW)©æe‘ïô?o×p¬ >E3#ôœE5‹3â4±*‹OÝP²p4|ä :ƒ¢(+GIC°U²ƒ3Êv,Šv*`·n‹¡lð‘ƒûàퟎ½]áwâߣ®‡½ú˜U Q.?\ÎÄ-üw5Ã/_ÍDE÷öbdWK .žg ¹¦¿_mË6OC„_ÉÔÂIŠT òÛä‘Ä=¾)WÄÌ îQld!ë€Í`\ ²b•·iJÏ¡»´t7bT>Ét®…`^iÔBT7e "‚[5Ã~ÍŸÃMß8•F¥ë]ÛC¹ÐäµûD· vPÏwÛfŒDSâŽPÍD'YÂæJV m™ÈˆúQ/%ñ‰4³À6 ÅŒùÆPœ•®ºjŒžB}Ñ. ,ë좶®É‚b¨Ôœ] 8&¾LVrì$‰8˲ƌ¯³M[óY²¤ƒ ã©8F'~ª³H¤U¶L5Ío,Û$bY–ùŒØ%[‹÷u‹j¥eE&Þ…êÈJ Å­"XdOQ×y+÷+ÉçjµÊ“ìÓš^BÔª7´cP½¹”жpŠu[D‚ÌNÙ6` "Ÿ96{*$± l™^ K%Û&Z!:VÔ§DH<€Šè Þ>œ¥&øSR0F¡ÏQ TÃËv³g€Ór´9²G)~‚“ÚQ×ä ±mšjqqÁ¯çÀ QYo.ràNÕ\Àè gt´mv¹u;~?ˆ³ÎÌ8¯<‡fžfɦNŽ85®ccFŸvn^äàdÐ5kt$ ä<û(YèX®&®mt&Äz‚ë¾ü¹žÌ­¶´EiL;3°Ÿ\,ˆqÞ!ƒ™!R0AnEˆ¦>À³jû˜}Ñgûôô™‡tºß²åMÒ4B¶!óêäÌb&Dw~’íЙuÑ@5æk©Ì_ 'äŽ3¿ÐÃÞ8<Ø>‚®™ö¶{õ¿áÙ¨Pô‹@É+ˆ0üˆœp@O_çÉF£Ñxûüü'U¯ô€D5uYíÇç7î&“T®èM£}‰AË=JpúêÐ0Ù”Y‰ˆÿ¿q8Së%žCzß>æL Œ-¤Qb°BBƌࡶjP“)ûõj·=ƒ@O‰¼õAá[ö1ùìËÂÚ«Z‚ÿ\ˆÛ{z"A¥ ß©׫Â)nd 5ÀHUyÖ„Á,˜ÞeÈvÓ‰k• ¨©£E" (%®Å%o°b×Ö{õš^Áé9Ïcˆ€‰At%Œ …L£ÀŠÄÆø¸ÏpŒü ÏÓlÕ„b‘ózÚøŽipˆÉ]ÿðÈ0:0|=ÂJÃÑ£>ØÁé4Ùli¨d¾žv§*‹G˜…áXADÆE‰”¤@LE0ćƒÄµÌ{$·¯ï'v½²¶óÚ°~Š2•ä‡ÑÓÎáÓf¿à'/!\£]ÍÄúŸ…"Çayjt¦ÝvžQW‹·$¯?ÖuYûp æ½_ý½¥"hŒìkÛðJ|)«:âá-pdƒg0²áц7A®A°VIÚ߸ÚÞ×Àé*êøÝtp„`&˜ÔËÂçKrñ\ô!à`v-ú bMØi“çÍ[wª§yì=˜äXœŽtHwPJZeõ øDÑP2t'iš&£ÆÊ‹®ÒqØp ’Ù_q|ünQ-wå£ Ð—Y"LoéøhDGa…©øV¼G¨ãåà}qx„ólTó+ŠÐo¸CÍÛ¿Âÿ¿ÃrUþKv™÷âI²n¢WpŠßn °Dÿ8ˆ€Ø»¤ O@C$®ûÛš!J×FΦ“>³XÆ5¯æÈ!%P¸†ü†ä…bGŠið Lš«u¯éAÖÎÀe‘[-#R8ÅîQ”©‹¬!À9Æ gνì (×ÿ 7Fÿ‡¶åzÎÒF«àræ€O°60ZœPyìBzŠ©á€‰„K#qƒybâ¡ º¡˜Ð¾29@Ãûž*tõþ5Áôœ‘oUî0zI€,3!%z…e»ÙBœ¬ ,¸)c®½]ª&kÚ†r93íXûPÓR*´i…ĸ›säàŒ–›"û¤s¨kˆ¦AŽo è—â†F€ xTYãƒ2F)ßs"V%åŽâáuöŒàÐzg_ßú^»ž㯩N1xÑÃÁ'œé?ÏøYe®Œ³j‚÷ ¸ –œI§#ó1EfMpV÷BÒd4NÅSu˜—Ò)D #8Çœr"ásv±;äÕ\kNG °•°þíå¢Óûÿ#>ï§Ïñ~A³Ãný¥IyÂÆŒ‰²ä0Œe>@Ùñ1=¼†5:ŽÏPæ) ®1Ëa¦Ñ'Í ¸X>,Ü[ ‚èC™Ùy÷c‘ ËÆ51<'wA½¯C*À*ªDêäfNé‚o)¥¡s³nÑ3@g}AÂ÷hÙfy*k0‚þÔo8s©²S+X?{žè>— ô«LêÕ©ø ̆‘?žmÁ•lA@@׫Á9˜+1ÔlGdˆ³`ü> Ÿ§Óû;^/ ¯V$;»Æ´ŠJG{šûpÑ”nV6¦!!€™án§þÔίÇoÝKLÄt¤9–À2'B"#¶´Ùsec'“‚’”î±cÅkÞ®™â‡!UÛ®- ‰‰7U¯Ò¬ž!¦p,‹åС¢LY¡ŠD€H<S,Ĭǽ8 ÆÈ{¢ítÐ@£ AÂüp e†wE %_ìLŸŸÖ2Þëw®7¬%Ÿj(ø&ëI²%ϘñŠZ®™˜v?™† ;iþ1¬×%}Å?^ ƒÅëúܽÌ2Q2F~¸îXh{æî½–ÏÀ7µ„…vŠ]ü#¼SçÓ»è.rq±€§áí›ù&óO¯çÿG÷_NáQ09;ŠD 'zwI û›ÿú—)˜hXî{ÿöÝÛŸœNHø@¼4*AøÝâ®À“xkþã®øî^w7Œ ð¸n—×>_Z°ˆ ¼‰ú#Q6pAÕ¿ûúÈàcdÔ¨ÃÈfkDàûwÝ÷+ü~9~ >¹8_}R—Uæç®ÿ¦Ù_i¡¢|yBJÅ”¹aEÃ~¥õj3Û³ÂÂ)eŠÅ7Jf{-.ºÒ|CjjÃuù˜a‰šBÁöê„^ûD"liÙR$¶êËsu}oÚŒ¼Ž .©²n8û?Êf¨%ÖáuŸ†Rââ¼scÚqÆÓ¶ÌYËšz§s£®¯»e]-EåDÕRêÞ)öbár¨éZˆÄÏeÃe1ä´šÇ9BªYc)ÙTšµ ¶ G•>‰KÀG‘`˜ ›ÀYˆÖ, b¡–2ĺ"N¤ÀÌø!Šfw¼§ªBx\‚/y¶"w#zÓýí-¥ µÎkÞbäÿNÆA¼ó`Ã.þMl@Eµ+i›¶Ø½Ü[@>M9B6(a:Û’”ëÿžœ­Û<·ÈŽ‹e­óÚ8»fl|kϺººoe^aÁ¬W®ãÞ8ÊÃâz±­«ö 4‹þK`™`¢{kzõ²ÙG)IKÛÍ£§—,YløÚ¸cAò™.ëf›mÃ-.8¼ö—cG îü:¯p]GµLÒpJJp¦;$P'R˜î”¹¬®‡£ªãY_ëë‚™žÄpÏ^Ã)Z¿¶Ž;ì¸Rj¡ªUãùyÈÒ4;£–ÅKŠvªâÄÅ7ìèâHýðÊ>,+ð/WæùWö9C¹2/¾¶/j‰Í)r.¿ú†^1âêBL³ôp³=!”™ã0·±ÃÃtÕ¡‘+ ÍéÖ"aìúBM ›òɸ覤t–—e%ÊGÉd´#œu EÖYÌf"Ì.Á红ì3eP+…îÆnÊqŒG}¢#iè<³´¢Yê¥Þ•ÿÑç0sè;u¼Rد{ÌÐ ƒ€ââ+SÂå\Dv儽gÀUØTƒ .§R¤ÆŽd¶­‹ž+C]@ÒxÉÍ6#౬àE÷:½R}Ü ÀÅ” R6vuYç@r²µÄò¸ÄJ5awµét:ˆ‚~ç i´¼F.:(çƒ©Ì n³aÙÊo<¸Œ³Óßµ µ„ÎG`–cÝyíf€A€L§Ã ê*ã €qóXáÅ(Xä3qÖ¥"åp½©§ìÔÎ% ~àW ^(3Ñxi!05­mŒ‹Ú/)ä°3êÒvÞ¢BýpQ@[h!#A 2Nfâ\| àrÚKÀ™˜1 nuwÑìT…¸Xzè¦fEë¤Ýϰ„[öÜ*ƒÓ·¢¨8€íòäÙV­îSÅ%·U:ÀtæaП‰Î¡5*™«Iþ”쀳P¶ÑïU“|”¯4—À¡’{Š¿)ŸøàäÏ1½ö0C|¹+Ö…g*Â+f€ƒ'󼫔cx÷–TpE>} èæ€Ý+‹×¨Ûî·p‹Ø}<Œús3ýdµ'|nÚÚ{á'ewÔráÕχm»ARz¨…¹8ÆÊi¼‚Iœ×›åK,WÒ^VU=Ñ*ß!ÀcÕÌQpötV¯³Í_ ,uj7‰"B3VGݧ³Gõ ÅT'plfG9!4ò§| ÊÑ@'y£¿ë”ÔKÀ`ÛcxšÐËPøkÕ2Œa’ ÃHŒ hÄ« ‘!@äQßRêIñ`$Ôv;jÇßÄä£×kt‹¶íŒïEÚÙ' Û)¨¯t°¶Yz¦  ÝÎ ÞÁîûB³Ø NWº¾:ö!nÆYñ!¹Úä(ˆý|Ìô^Óö]™¤º±ëM“ü_¼ÜǨ\gŶ•ü$Km.$iv·Ÿœ÷ùÞk¬j.cÊPÚoȳÓbX©`QøÏàÁe[K8ÈñÁZPÍh•¬e »Ç‹Aݦ¶óÒÍ^3‘!|ÓDsóú3#zaY>7üU¦?Y]&p\´&!6NÒÓkf’b8ž^{ôÒ± ÎíYq[½Á{QÿƒL°Ñ!Å15aØ_!îl°_œÿ§ÂÈ3N–݆Ĝ/R<ÑEÓÚ( Ã(Žu¾ƒ€±!O¹íÝ7èfôŒ¦j¼3¨åøŒM Æ[ºOUßÓa}âœÕN6[ØË“«}(rðr æ ¼DQãe2Ž!R,Áô{ ¬Š„©±3÷ޜ֙xvh3üó3ÛBŠýp»pÖYʾ“…ØÅIfg9ñ%ìmT)8ݽ |™Šj?uí‘‹gúI ؈;Æ·rÞl6ðÄÃ×3ïùAt0hëÉZ8‚Ž}Ä…Â1á àuoËИGÑÂÑÈ-˜÷4eQB6zícÃ9Ñ­-/ÎE†ºÖ’¤)‡.ÁèÕ‚8`è 鯗¿-U*ů¯”áè¦S×Åxº#ˆ¦a®[T{ØGe˜«Ãi|ûúžãdøÅŽæÜóH;O@ä¯{[j±pøÛÅ%€úRÜ‚ûø—~>¿|½0Ok%£ ¬VÂheMãá(öEŠªT*ú@ÚrþVK‹96ê&¹%bpn:²áiôQîUha”²M q#ævÁsî-Á7f7YÄ·›lˆM,+Ë”ÒÆ†.ºÐ©Ç2œ0Tó¼À{ºþTcnY¤=zAÜÐEViÖÝàëIÄ¢)WM-åBÇž'â8¨Ë!'KEÅpüÇÉ`û«ŸwÂ>hŠðœø1ïéè?Oõcc|Õ#ÐHÜ*ÖI–sϪ6Ê_S}¡ñ…ù„ä YÔâ¡|¤Lã ë;eЦÑF—ÑUtEqýù•i¤†ÃÈ÷îù’TŽ‘€¢ª¯ü1†U #Õ:q76ÙÉ$Ÿ\ãëkÌtu!ÖúÇìb¾A¡yŸ |©ƒ7¯È]Ä5¯ñ_ùœ)§™fØŠ lq⤬\š¨jí6ð¬)ùˆe ÝTp„KÁÍ ½æ:È¡C¤a/qOÆÇŒ½]M…\«†eÖƒ=x/i}m`<— G-\|A—™†É¥Á–?;½Ø‚n~-?4ûJóiZnûžóŸ²p€žWÐ;Ž›X×Å0×ÀÇøÍLù2æôÿõíýH´nÂS³=æ¥)A>ÿ=¶Í2æçPoµ¶¨4·A<&Ú­åÍ!³º1“€éw¿Ñ‰ú€ß˜_Xét?£©óA!B›RDY;û3,† þ?¼ݶï D?ºøCMb¶=Œæ¡ Çã<B$QΟñÖSÝ(,=…AL‡G®s9P¦Oà;ÕîÇÕ€G®Cý¿úû?£þ ä£_8VŽƒÛtïËxcOëNjúõ(=:Õê‚û=­;âÝK¸gtY }ä*®¥K‚îÒöÑË_–€X“™·¿c÷éÛ²…ôÝבSeDGʾUÆ”ˆuzZäãsX `HÙ`jþ2Ý1Žp¬ëažÐkºô±>ÿXœ%5ä`6Üà8&]s‘qŸþ1|,¤Ìb·aî"<¤ç ¬PK¢¨™LH¿”ÝcP:aG-Ï!³`eQG­ÖD¡°äíb~5rw•+3ž‡Á¨Á @äÐùÕb¨g:³Ä 8ƒýìÈ’‹ùåýtf°½¼ï«PTc9]!¤Õ+ÓQzw冨áÀÀ1Ø ÙGÐÑÇHÜcŒ£Ä,*Ä Y/q.‚ë w—Oü^~«­\}O[I•…¤ëë­¥ýM¹²lðV”Î/x¿ÙÅÀº~ÊÁ¯+E¸wÉñZÙÚ6–utùÞÁJ&£‚Y*”+kn  Ò ýv öÚŠ¤Êü^ÃY7S¬tö“aÇÃOð\>'XòSºîÑøS‚ë1ÑÓŠz‹p„pïV¦ˆ¢ ˜raGª¨ynÌäa5Н¨9KõÓŒza}u /éçŽt‹§Ðj;º²žxÁ/ü‰QµŸÛ‡’}pM‰{ÑÀüíôµˆš¾ÅNì~X@±*áO×n¡†º¯W«¶ ø~9½½¼ÿ éïï#‰îV—£â@5Ê8m&+?RTû{{}ßoØ8²™q#ÒMG¬mzbnS…ö‡ÇTI}9Þ7í_/¦_ÃpÊhQŸžfÏ óE$€3ö)#Á™xSèÜiò¬Úe“ËfÏÕÒÌùY>’t‹?n{,Dåbg-±Ëd±mñ¬µœßä㾪~ŸR‹~´LšŸ,5u8-:FQ Q(°·ÄrÈ5¡l¹Þ-€ë뮳‹?¨ÆuVØF¬ä¦»òHõ¢ón—M5qŽÇéŸ7up’£æÜB8l]>9]¢çúÔø+°µLìfÄÏÂóó¢çõ™‹hfÒ‰;ëh•—J†æ^¨Á¶rîVž‰BbïI[»#zE—²px×¢mîüª•¦™^cäÇ˸óÚ¿I~xíã?äeò½85IÓØ–¼ÂÁï£Íz—ϧ'&ÒmÄ™{g¾›ö£€áa «æs ?$:¤Çï·ö°e3Ä%oÝÁ]Í@ßÐõÊÉPKu@,Fü®ü欖D*astropy_helpers/sphinx/ext/automodsumm.pyc½[[lÉu­îyñý¦ž½ÚÕr$‘Õv½ëÐÚuv#ÛP¼âæîR¦¥6§{ÈõôŒº{DrwæÇò3pbÃvœØN>‚ØI'¶a$oÄHœþÌ— @û#@ÿ$¹çVUOÅ}À°ÌGO×ëÖ­[·î=·ª&÷ßc¥K?ýÞ+5¡~†èÿ7é?~ÁÂb‹ž†pMbËÐï¦Ø2õ{Nlåø='‚¼hÄVAHçEPÍ!±5$Ó ‹æˆØ¡tQ¸C"(‰æ ±uB¦‡E0*šcbkŒÒ#â“Ôù¸pKÂuj~9„øØÖ„pG…7Ĺciî¤pǹєp'ÄÖ´p'…7-¶f„;Åo.R³Âé§æ„—yáQ¥Y±àÑ¿;GŸôïÎÓ'.ˆ4ÜEá.0õ%á.bÜKâ“E±uJ¸'¹Îidn”OAŽÿ|BˆÒ+{~lÅí=?<°¼ƒÄ c¿ZŽëÆV²ß²\?òj‰ß‹­z+²âN³éDþ~¸k%{žÕîì~­Ôôš;^[­ºåXÍ–Û <‹j·Ú]g׫”¨/ö²ÄœˆG>ˆ‡LºCöýdén;¤E„œ¶¿]íóµRÚé$VÍ ­ \Ë]¯íÑ#L‚Cê¨R±ªª-x]/•ž?þ§”©Õgì-kK9¥õˆÓ  ÐPkžEüœ9)Ãó«qrHHœzblJLN’D>ÀS’ŠÛ^ͯû4 )³ŠµáyrürF*4òJ†rV%v½Äñ"R3b8ªyq\±HàVÓñCb¹^÷"/$6ëQ«Ù—nJ²ÔQHöœäH+òîu¨NLÃŽЄùa»“$ÐJZýq•¸¹Ón{ND•¸7ʵ¿çC&à²æ´“衘f.ò¡˜'ñkè òÀSHlÔ/‘r¢ÝN“ZK–›8Vdô¯Ô׿ÄT·,§VóÚ  ­V;!1’òwÚíV”Ð,ì#ž>«¥Ø{»©ÉLHÅ:Ú#­*}:AIuNúiÑÏ%k{{½8qìÅ«­08\ßÞæüܨӴÒò “f/Ó©R1VF4³j­0Á¬k¡K)EºÁs†­$]GN´c§Isä7åRL›wõNXc–5V%ÃûC¥¿rîÓ~IþHw€ûø®ß^·Z;++ÖÇéãê O¯X•JåÎ[ŒE¯]µbÐyàÇÐ"jJúBzµ×ê.8ý¶ç¦tœÐµÀüžsŸ—»OzÓª±2;£µë…^䱪„Ö‚Žë²ÅKéðˆ³²ÌŠ–QkßsWÕ"X I4ñºÕ¾»ÛŠh‰`¨úÆ«_ôFf ž6éjÔ餬)ñ¦ã F÷ÈìÀÎ÷‡-9²’Fk´b94“-Ájìµ2‹öQue1ãŸd–Û¥®H½Ñ—ƽÖm§`/:;š‘ÍŒ¢¿4:QÄ„ƒQËŒä¤ð=W[¥ŒŸä%gÙ =íFIëþn'’s)W:-tÌJÆéT÷#?!)“í¹Jæ©Ú8ÖN«¬°ºøu땨3ŠÕRsà-³ÔÈüX™¤U'C3-ö§°u=“öÇžœ72«íÀ©Ñ8S׋E«ºÁƒa2šE²›ubù!j{4‹Q'¬XìvZ„œƒä‚ŧ§-^±dl¥¼h-µ¤_¢‚âi…=eAbJˆ*ØcBrø4—JàûNR˜£E•`†w:»»”G<]÷êN'€z´¬íÒŒyÛ (oÉ×­½$i¯¯­ÉâUR†J+Ú] H;ãdj¯ejWö’fÂŽ_žÄã}7“)4«®ïìFÎÛ€š,°Ñµßܼ+€ã‡$W?q$4åÀ¿ëÉE'×U)ë3 ªªA¾üj=<»[åiÖvíršIý¼õuVœ—Áðr†3-¤åkùˆÜ–S†¸é6åµ÷îûoX×ÔÜîïïWt&Ïî rjãÍ«é±=¬|Ljê]hP¦•TBÿÿèçf™¢#‘´/öõHfNÓãF¿ÕuÙ•,ËÓ£8»>R2k Y°«$•*ÙØ¸OåÅ8‰ZíÃL5”™ôŸ£ÿßBx±N®@¼qwXD“bWˆ]Îjp´öÀ×ïL‹ž!º†h˜•^7Å=Klpˆ:q,þ3Š¢ÌªûtàUû!©(² ‘KÛ”fÆaßÂô`<ò,¯ÂÁØ,ÃQ/«&®—`X+7™–ÑM2ôI¼µ?‘oD¨]ÆØ“azh­å¦q¡+?â—é±ÓñwmÇ%>*M§ÖŠV¯ûÌš·»»æHÙV÷¼ MãS ev+íÃd†V©vêªa{ÑmtVD—…Q#o¦º Z¦5ÆôênÓÃD >Sàìå/ãYDHë ‹Æ&‚dBßÌì5õ–£·ü–Oß âÅÎ:G…½QFøÎÊå³0Æ¡\¨1¥¬,LcycJâ9ˆõ8<ÃZ7AÿE­u¦T1Ö2ÒªFŽ5Œ’yŒk©g ©„Õ^z9q¸$’¢èšÛmª½‚èÅf¸&òɸ[Ñ0 #mjÃ>5Z V2 bãÖ?3HHˆ»EÑ‚<úÉaî‘E“fFOII%)‰ÈõJâà9ÑÍÓòX½¢K%®û#¼48‡»Q¸÷#A›´j©Î^awó ¯¸-ŠÆ8v6¨Ôæá “Û=m„4°!}Åè‹Qú—£âà?D26ºEì3\¿óœ¸mŠÞ˜è‹.õBìS£×ŒdR4¦DwR²;ÊLI¦^Ãßfø A¤£ŸiÊŸ7”¿Ï”§5åï¡ü}üm†/2å’‰ГÆ:#\ÖS S9.‚zŸô”Iï06S&±Ct1¯³ LѶv®uy÷%YE?0D¦©lacÓZ•fÅ-Jl”±ÒnJý^€BɅˉå7aj¿õnt߆ñ7èñJäKÌŒ•BÝ7a{À·Šè›ôÙ[±v$L:´ö=‰¼tÄB@èÆ.ÀD¼°@ €Yxî!Žuf9"0JÑõÈ#¶6Ó€XEôÌ« ŠrôL ”a"¯Ùºïñ+6"B—K",²óM'á¬7ü6ñCs sâÇ!M¢,‰Yü®¸âw…‘¹Eâ5ÛUסт<ã׆ p‹ËÚwÄ^P·a´™ 6Œ‡¶\FœL±Úª9›7é•ï…±=®½ f‰#óAáÞG”¡”&SÁTû™,ƒ°ÉÁ~EéœT…Gè¦ì'!Pf±ÓƘ9bÍœ±dŒ#Æ”1lærÆ„Y4&ŒÊ¥ÿYª7aΛcFÑ8mœ2èS½™£Æ¤yÁ)Œåç©NyL˦ZÅX«U–bµ*5’’Ó¬ æÜj_צS99A&ÊËaB²$P¦´º¿GVL>ÈcŤȧª•’uýZ"'ÿDfH»lˆÛF&‹£/îG$sØ“]Pž…s4ôï„Q’¿f2ÞG s> .¥ÀÀ3y;:Ï /<dó®‘›‹/ÂÅcŒïà«1Mí«W)çp«ï®‰ñLy‡ 1•¹k(XAþŠf¥1¡Ü ;˜î*”‹þæ[‹˜]k?ÌÛ‘˜1×Û¹#Æ©VVÃ^Ôvk×KìÓÚnaç± m²çñ6¨Úgñ8‡ÇcxœÒ­-?´Tã1óö²¦ß ¤I ›Ê¶¥9£4óò³%|àÒú{”Hš9ü{P~‚MTΘ3ΚËlžÉ<‘á1'ŒY2[92K‹Æ”É3a?ƒÇ{ðx<Øk¿Þ…þ<üP€¿H\–L^hà`\/´ØÈ€b‡%4–hØÀʆ†Óº!û×(b! w˜µŸ×atï@¼Nç±D°P âàO%Æú¯Œ,‹®\ÅCX”X¯/ 'Úf¼ù Ýã/¬†ƒd*ÓRè2Ȧ¬/\l>(£Ùõ;2°ï„‚º†L¸9 „7±t>zëÞ/Ľmüm´¹E ΂\̯óbfˆžL)É|`uŽä°îŠÚF g-¥ù˜e ­¥HxSàY0îáo“—k‰—+lq%3m¬Úû˜Q’+vHk…ñšâõã‡õ/‹¸S¯ûìäwœØ«¶d¯Ìëï·ñ˜I—ï;rØ·:QÍ«ª–`£ÞêP$OP,fÏߒؤ¸­c¿Nõ«œoÁÌd6,“Vv‹‚ÎЋår?}¤æÑ­Mû%ÍcÕ(—”°;[®-Í›œ%¶?r%{˜ÇÜK›óa,¨Ú˜Ì“R`Ly #ïµøiÅžÕäH™m…ë’Îâ7Â~uizêü eøŽ+ S Ã¿j',š“Æe2EcäÅ‘€†KÑïc&ÞæèÔˆ1…å÷¯ß»O\Œa‚^¿¾¿|;¾tñvåvÅÊŽ®SnùöÆå‹ôÉA Ú]¡º”³Q¹Ä¸ŸÐ·ŸIsËü| Uºt±†ÿ’68dGD¢CpÆ‚¶ f?äþ¬Ž+w†8ÌmòÉuNÊ“¡1°rs0%ØZº"BɨxP€ Gû¥”ܤ…üÑ[4ýðJ§L ]®f*¡¥ü©œXêÉ>”Íæ¬ál›3w$›Uâ¬b6ë„Pí“[X޳É~‘eB|^»]5Sƹ· u{¢7)zS¢ÇAnw‚-E³/€ëL%œÝ)Ý9ÌïÍrWsüœ‡ò½Ñ[ÿˆ¹d†#ëYe³¹Óïêàz —ºK,âï$CjIU)~ž ‡;¦Ëþ‰Ë³eãºL˜Ý9˜¿d9 »|â™ÈýFºÑgŒîü`£‰cÝûŒA›Ý}Ëì.âé’€N" §ñ&‹¨E2Ÿ¥™\à±-‰Þ)v8§ÄRcIÉþ©†½ÞiVª“¸eÑ=)Hgº§E]Šqoš÷=FÁIw.º“børgÄ®t%ª”Åi$ÔÓ<û‰YF¤ÿ‰5ÌÒ¼èŸÄ¼“%$".ó éçñØà]¥³¢wNô,Ñ=+H‚J9wo(h¸×sÉÑ " ŒRZ•‘¶¹ì\Z¶­Ëˆ9¢7’Œ_){“FµIe€´˜ »Ü>ý2§±Å¶N^pøŒFÉ+ Ê4œç3ØC+îøé-&T÷<Ç1¼Ÿ:péA=n°¥Õ§…Që¾CKî[¬'GBB׊¼¤…r¿ÝIÏ%Çò¼õP_<8£—Gˆ¡+蘒XB[I ‘Ÿ‡“Yur춈ܥ°•\Rr‹ý½V Îô Xl­Z œ98òÄ5{r­ÎϰÿÂçg|Ÿ#<´Ö³æUŸcW¬›­D”HB™Ë|ŒyŒdø‡‹úìQݦ`éñð1(®ÔLüŽa{|'WÓ9‘¡µŽ-ðô Gw"ô)‹ÛN<¡Ç°¨G'ÇÔnƒž<Ó DàרƒU^ì¿t¥Žî2ÅjoK2oóÌdçW© ë©jdùY*6±‰+)DzÚ?äÔéñçÎaÿ²À€L¡—}ZŽ-}×Éqå‰0·‹/† zþÊ‘ãEy‰iú)ý‚ªâå¦Ü$ñáW} €)a°1F´vôÖ»ðÁ‹Èû ¾Å­€ø&•]—[{rŸï6õ [º(OpÓ]‰¾>ž™…;1 Z¥¢Û¥@×Ii&e~öütq±ý G•Å;+ %ûÀ×ÞÄã–P;.Õô|1NÞõ”ؾ†Ü‘ç¸ö‹ ø^daã.‹Ì"ïÀTg(î…&¯B‰\!h†Ï‘‡S)Ïe‚PTû‚Žç«i–´ÓdØ9á®Õ¯€&¦>•"”ˆ]—Yyþ=Ip)ë× ªEPÜK°¿ ~šOÎ)J×ïü$@¹@Oؘµ’ßÏ{ÿbô…g¡Yâ“/~7'9$Yä‚Sb3¼$òÉc¼Iú!Ó Àl`>&QCBåyF–D×·0šS<Ü)FÀIIÅË@ÜpYôëLs/s|¿Áàì_è ©&ð±*8¯ànôCSŠPrãq•i$Oàp:Ú<&Þø»Üg 7!aäœÚWš0™#„ܸ€ ùq~¾÷„8<)TQ;/OòX©Æfø„ÈS졼–#}I«°Wu š›ÏП1¹óâÓTpã”åLþ‚ø4qô$N½{˪w‘ESÌw/€k┸î.ã²ö5•uY·eî)Ê¥Óiá™LáYYx.-´2…ÉÂóâZø»ºï3Ü÷óîãÂ}‚NYtŸ|˜™E4ËâAN|R\NËË™Þ.ÊÂKòãIŠÈÊÐbC–锌j…{™gä¢fl£¢ÿÊS>ô‚*¬ 5.©ÄRï²ÈžCáŠè^æÞÏÐ ÏfÊ n,ß–L"‚ª‹\u•8¼Äo‹ô¶Âoz“u‘Z£s…ÄSⴚ׌{EÌ"視F]Žo ôÒ¸„Îݧ!Œîiá>ÃÛ™Ïã«",¢6½(¿<`ź«Ê<ŒF¿(¼UÆJ†ê¨X’-¨Á1eè1]e«G)¹ïÁœ¢ñAù%¶¤Ï2ëI–^žãÃ‰Š˜í­‰î/ÀUsd°Sâk‚"^ˆç½4ôö¸h¬!ý{¤üO‰îc¢Aϧ¸Ñ&i2®°RÜ¢EŽœ26ÒãCÅ­°¥·{| n§À¬¼—uü%¾ŠŽ‘*;‰(åÍKl%nSx3OYrÛ4"ýŠ€ºfšÞî=úo Ð|5ä»qõ­»^‘p932u±1pƒ8T᮳òufdeblÿ¾D¸%ñÃW¼f×Â^n9„Ïä=$Dò”§ºsȧ¢œE ³šÞmä¥&uÈéðè‡r{7ÁÞu5&RWå élŽÄ%;ÇÈ#9É,TŒºW¥Nñɰþih‡‘7%Ëœ©GA¡ò±U-‰à¼iƒ‚Öç~ ¼ïG­°™=y—÷áø¼·Ÿ”'±‘:ãM_ÙѰÃõ\; Xo^é­[¼Qn½ùTo`úuÀ˜¹ßÇ1ß ºãò²†:b»­[â~g߀Tt৤½v!vc¶±Á_Cu° ÎäÄÿ „º¬t! ”„×ï¸ÀP‡§y¿Ïò©NM½ÉZ O6KîÝ`OöaœÞ›aÏÕ5Ôµ¼x—høna†7RóêdÕéos—QÚõ;eµ‘JÞšÌ^üM¼ãÕ–ëHÂ|‚~†Ð¨ž^åðNclý“¶­ç-Ü©³V_@àþp èAõf¹¨A<ŽøìZ鄯…Èø‹#ŠQõäÁ#Nœ(‰úË3ȧ5%ª&ŠÜb©Êoépôà“2I=âµ2ýucßÑj%[°fÛ_Áãk,°à`ëWí?àvÃI61ŽlE¾HQEŽÆŒ!ã”1KŸe£†”²šT0¤&ñ~ztª¯LØF¿&Ö"—ÁjôÌ$×ÏQÕæt&o¤âN€<  K¬”ÅA¥,f”rH)e•ò«¬”¯§JÉûßñ <òJù:°«óvT§¿M}µ«Œ¦;¬•òçxoŒ¨ÃÀÑèÇHC)ŒPØ7/•’ï(u9¥ÔƒÕŠ:*Í_„Ê| Aí²r-Þ=y¸+رj5ZI\­ªK,¸DR­ÚF‰›|„hS+÷ž£ÖѤC6˜s•…e}½ëÆö·„Ú‘°ÿ\¨ û/ š%½ì¿ÄãÛÚPgdÿ•PW¸ØLÚßAÍ¿Æzoÿ èüZ4~êˆÆ³?‹EÒú НÍ9sìíç%*·™ä…+I'½FÏ›î-È{djï¡ÚÏáM™ô˜Úã½&ÔÓiö¸š¥l*fƒÊ™,9Ñ~è'é¬Ã÷S‚yö’½–«xÆk¿Cæm¹Ãþ—ðÒ3Y°¢ÿ ?¨á|ÃL[L¼Ë‰†Âpíç¹ö|8oM^&ýÈS_+Œ+ÉAb7­¨TXˆi1ÜíMy3¨?´x€ý2oÐ`¶–køaùºt<ûK(šïyö—µ"&çÞ²R í?@í¯âñ‡BmÀª&Ä*Ô€>ì?ŒœËÔ%AÖwž$ɤýuPû†P˜KfVb Yì?N×áàþ%‹Yzÿ¯Z…œhúåÁ¿/o2RŸZäFà¡o™ðþäßj6bþê"tvbœÛËû9é¿¥9Ö’IÒ0ð.g^Qá­M;Ò‹ßáiùB¥¼ê.¯7ÒÊŽíŽî=ÂWo#ûcºQ-hÅ^P¶£óâ¨VmX‡þÙ½ý¡vq™3Í™¾ˆ§\Îëàtñ¼ôåÍÂe]˶ŽÙO¦9 ÷ ôá…÷ÙÄÙ¿¯GoÏÚzû<ÊèÙõÀì=®«÷ £V™'ÃݼvÕ]D^g÷A—í$žiÕXt<• ½“´¿‹ª¸˜$¯kƼJpXÀ†'µÙ™º?‹¯k¤šU â~‚VºLŒfªAlrôߎS»Ë#¤,•2ò‚jìíöïçÊI÷\¹:è ~õª[Dð6ŒþÑ݉IcÞ8mNøœ4Gƒþ‡Î‹Æ¨9bÌ›B£ÆD~Ú˜6ŠÆ¹á˹bî´1š+šÓFÉÌQ» rC9”Osæ½Í1s‚Ê&ˆÞ4QÈ'É,˜sS9cî .U͘gè×¢¶£ôn™gŒqcŠ·vgŒgMy³rœ\Ñì‰QãÑ9o\1–òOäO±c3–¨Å”¼ž…¨ß–ÀRQ÷Œú·Ì%¾R Þ°MäÁµJç¡>:ÇölRHÓ|A4‰æ‹}#swpU¼ý©ˆ,ÊXÏøì a=æËJ1ÖÜ‘¯OIÕŸJvêŽÓ*,œçÚ¯A8’Ø#DÓ?À‘¾Øu«iäÍwÝøf«¾„Â"{BÅ•¨,ï@ÉõÈæÍ%“|Lò(ïóô ÞGk‚o} R¬1VÖI³|F3^E Nïœv ¼¸#Ïþ7d YòÎ2çˆìô˜$øÎ9Y€ÓIF°Òß®à›ÇÌ×’—ê§ûZõ¦¢žÐR–òfñòÙ`-ýˆ8‚u«îñ+¨Õ¦×+™÷«jŠšm\+ÃäÕ—_¹ñò›°CÅ9‰tXàvÞxôw%Ùx]“–øœxÆ;“£êrf‰þs#'æ?÷;§ìNd$ 嬕9iÆÙOçYÅ[CìãÃgfìkE¬êtØ93DìîöÓÍýÃM¢ NNN‚ÇRfšRÈF/šBIVó'2Ì–Ä„1-1ÙÖkÒ† é_f%—ªÔ/¬Â ò Ú*øUØßÚugcZÕ,M‹Ö¶šÒ”‰ºQÚ²FÃoefqaô¯5õ¹ÊZ+*“H•ƒJ/~Å” Ò$3è~¼ûòé÷ôëÇÇ›¯÷ì ¢$Su#*ŠÂoËÓäìÛ*\°¢âsÙç/×wwqpûððçͳÓåÅùÏ«³0‚ §LUFƤ£Ó©÷7âM³p4­&ò’×_ §P˜/.^PKf¦)Dd:MwDᔓšÛ¬Œö†³ÖÄŸüª íd§ÎØ¥fø!#CË<ãò•©b–/Mw·ãë4{ßF8MȲážq! …Ëÿ»Îs!7Ü¡ØÉßÿœ„ £3q0†EXª]\úÈ%Vóg”Eðx©, IHc929³…Ïÿ,2™’VÈ–‚ILþ"¶nE•£!$mAÎX ‡áIjj*žQ›V£–¬&춘ÀpïX€8lÁ¶èB·ÂõgáXŠa0Zg%î‡ŵ\M¹ý"Ðz,{Í*w¿Ví¦dëJeŸ£è[‡E9U¢bÎÖ¯ˆU9ͺ%Í-Úýš#Ž„+IŽY!dÞµ®ÌųÈ[^94šžSkJоb£ÈåÈK\’öÚ+qÈîbŸŒyz0$K£A§Èþ9ñ‚(îE DQ¼ŸÆ>^ ÊÎI]¦ý=Ë}®—“‹Vq|ÈWz³‰Þåh½ÚÓ÷Èsÿ‡ø"Ý›;ÿ=Þ,îôîwõÎéú ‡:íÁ—·Ë7=uÇç4í&óçeçï§î T[- é'’’…Ø$aËvvå‘¶ºbg{¸Ë/æ¬Çˆ,ø_MíÆÇÿÛ¸sîªûóF°&©Æïà° J6=Ð;ÅtÀXzt §‡Á`ÝåyÞíÌm©ÐÜ~bÍÄz+Œ“îô5Õ\H7P]“÷ûbV"»òí”n?\¾‹îŽàÞ¬yŸêw·ïŒâ×~û­€Qçî8Ù˜»%¶Ûôc/_L ¶¥Àð«ù«_`×-£7?˜î¦|ÒOþ~ ¬‡Uo°þš´áM.û5íö|ßêGW¹ò“OÄ~†àSäý2žtäk²ç³š’œ³RRRf£°ßªçšŒªž)ÇÇÏ‘ï—øÐØïLÒçH°õ¦oÅcg‡¢H;Öé3¯Z|:Œ`Üc-aqë–þËò¸Û€X†É‡Q!ù€7á¶äÖ P~À¿«þ_PKu@,F[ÛŽ .astropy_helpers/sphinx/ext/changelog_links.pycµUënG>³»Ü0$Nâ&?’ôB)R©ªêÆV/±ˆµ¦Š„CWëÝïïÌ:D…þ¨Û'èóôaú§/ÐhÏXìXýklFgΜëw.èÿTÍ¿Ój×…åÇÀï×À@ü‚„ÐÓ§AÀ Ô §£»=]½æ —ƒ0½<0®Ã¸^¼<]„sÆz%Xò x…ž ^~CeðJЍ€g*¢J›e Aôñ0»#_4ÄdäGÓŸJ ?Ž¡sÂECŽxÃ"å( y"~¤˜îȉ†<ˆ‡Èq#𣔎Ío}ù]z¼Ð-Óÿ?M†nä“¥íA¹}tš=*]t,KH$|À¹\ðöæèQëñ›¾Ì!=œ¡PÜGGÛ[_ô»:ÒuüR*/Ö?ÑÑ´ 3€1Ànÿ.Ìu˜!, fÁ’˜ppjþ¿FôIN#”ÇúRÿÙ4e3dpN6†lnúŸá™‡s „§ˆ†óož‡é:“*Š¡Ý¾Ææ˜!«Dfˆ0‰ÐæE˜—`–ƒq™ì¡ø Ï"Øév÷¬ŽRø‘çKž(ë(žHIÍË#Ow&"I÷ûÃÃ÷VºôèÆÑÀÊH}9JíÅpÙiXj€HjâàÔHYPyNÇåM åÍ«/veÂyF+`t¥0]$+y¨ÂuG~à‘½ÅÌò3û8ˆÝ›‚¤ ÔM–3Ê^dTZÝI®˜©Ò…  ­ž–Šª¢Ã,ìÅZ±(…&d‡8 S)Ñ>ö|![¡ãÆbºõd»õùÖôù3ûÙÓ6ÛŽI@Å™“0 ˹™yätmœÊ¨‡˜E.M@ÙÁ›8F¸º£, ` ù]¤$”ŽeŽY ï‡]1ì×G°ªÙ}<uvî/s®þ´ >E£€Ò¼Ñ! FŽiމ,aõÜÄÏuþo½‚çà7Ì2àY†¿$«1å“}ç’^Ý‚ùÉ`غϗJI©ä‹IÚ€*ô‚IŸw 9á©ù3âÑ¡4’¿/ºhØ ²t1ºˆ7Ö”¾šx¤Ê§Ñ…¬È’¤ Aˆ„æ8v·–»I÷Ïì[ãõböéqù¿ÆäzNÜ¿Ø\ïãǶª@µt‘ †×­jÍ”ÑÍ4&÷‚oBΟÈ@¸v‡LR´uý0cª¼ÕUg>ê7ãCº…P*• fy±è}¿W¶¿ÿŽ¸Ñ )Ùd%^¤!'èç,þ?z)Ä…&ÁÄáð?Z6téhŸôQ¤ eY??” Ò$ÛÏ•JûºÀÝŸ¡@H¯¹äÉ܈‰åäîéœwRñîkFÙ5»Áj‰€‹×û¨ù…¶AäñHB5(^qoúaD÷Â/øuêJ“%°Ù p¼¹8?ûáóT°wqª×qã!'& ö©W‰÷p†÷D00îXiÿZÜ×ñtûi³a§ï´ü)`ôá0w÷±×EÂï˜Æó×LAE8%º«o :)ÙY—ÝËa²ÀJMXâŸIEb÷4“˜3Ÿûžú?wþqi ŒÛpNÊ·t`Âî¾4³O½Šññ'Ñ­"qœ@•/©§•àé;ax/ß{‹Æù•#¸Üïæ¥ %µ—g>¶O¯®Æùêeª1?`KÁDEV†=_./µ$ß¡‡þd¹ù™Ó›ÜðBq4šQ#ÚÝÓ6ç8ëNìÀõˆH˪ƒ·äü(fù¼é†AÁÛ¤oxà+žêÈ×˳§WÉØûËÓ³«õ¯Ñù'ïçØ¥gñBEÆ HÎt¾ËÐÊY viB¬­ìyaž~ïˆh Çi=ÿ¥ÅžqËQ¥Gù›E9i"‡äüÍ•‚®gàÓeŒ ¨‹¥Àz$l¾öÉÊQ!f)V ¦ÍwÿQDZ ·÷äjžî°‹w`8záÐz¢³VûXM`Eë¸A<”½¾Sø”àîYÍ4•©£®Ÿ@¦· 曟E³#¤xœ‚uÜE²G ÓÊÕ‡¶«»˜tç!¼9©i*aИnÜ@—‰Ž+OIت¯½_£î›^µ¤/(„VÉUúEa“átá}ºPïã&¬‰oèaäýŸ‚WHíC5\¨¼%'Ýu¾|£•„6æ8hˆ·‘] 0.5;0NàÝû?ÎßžÁµÆ^©Ä&àvLXFq­bì"MõïTrÜŸëWn±Q­Î9º^6Qxø±`»“Ê·ùuíG7“Njæî¥V앤jUdôæeÓ¿ãJÝ;©NÊ«rÀy±° •ÔHÓ?ƒ,ÛŸ5 3ýŠ4ïåÆ-LÀ%€¡(ã\5åYïÚké˜îÕ8Ñ– È1 …É`2môÚ­š‘5vhôÄØ”'RzG!ÞÆ9Ý)¿oôº»'°YN(„|圾9É­º¸î>.þÈ´„ìIhŸ(úPKu@,Fp‡ûF <,astropy_helpers/sphinx/ext/comment_eater.pyc½Y[sÜHni®_W¼‰ »ìdIìMÙ,µµ…C6@Q™,òÖºv —¥[ãi¢îI&Áyò>Rµ5lnÐÇ 7l̼ÏËîH–1¾2íâD&©na‘IT|ÄØZN4/„?)9èyujxجPÚ¢¸¨]ŽÆñ Ú=Šb¥w†A˜ªÉ½ûïüìÞäáÿÁOwåññn t–Ž^ù'r0’™ÚU£“8™ìÒD»ù.}h™íŒ^1ì¾'±öýk˜“ Û¡ï°F­Zoÿ ,S`³} Û't·Î 47úÀ1sƒ±©ö«ÀíÛ¯ß<êŒ|¹›È—¥Ž1¾ØÃ:m¬Cã­aœ0@æC0™ ÏxîÕx8“®6à|Æs\,°˜-ˆ¢÷JL+[Ö–Z¹ÏÖ Lo f@g`¥k‰$]«¢W›ûmø`G!†>Pí²»®ù½cqØŒá PÊ÷s£&ÁPúþ¢7YH—áW™e¾ÿ>æ¨r´^µÚ¸ãm`Ñ-~f˜Fã-”ÃÛ÷£4¤6žþ*K~&V~>¾‡Þ\¾7·…‹Ú‡t1ŸÂÌu»nÕ-§é4x]4ùÿÓÑ %iroŽ’Ü´G命*³Ô´ùNjša$<9uŽ@öƒ™¾ EˆÝ›z‚c½›_h}Î<ÙžÐe8Ìqà7±1Ï5U‘ˆwñ ¢]¹:uõ‰œ%øE~©å´1ò–J`–KtJzñVpA(zÈsÞú…c¼?e’e{†IJôÞûLÒ«L9¤5Ë!wØë¼«EPÎxÃå0ò§ïfÉÛ,Ló$(é]GߥóÀ ygªN“EMNàX2+¹À.¸àË.ÈY R°@µ`”_Î µœHˡф|#)÷­½GdÃ(¬Èýr<¸éX=$:>§c5¯fTÎ…ÇT Zš†~ÊD~,ò(‹EžÁ™EØyŒÞc—"‘޳ Xñ\œzͬl³8‰ää²\ ¶Ù+ÃľZq*¡‡H¹éC³é>oz‹L%~‹yÇol‘8Ü® =y²ŒD;й%nˆ7†zê ž?žÏŠt4ÀY2çq—M“¥¡TŠN/H7=êËP/pkà;=‹õJ±p|A»%LÚ¬—v'G4¹W§§2‰_K–ÜÇ2‘¡ás¯bóŒÌLç­apJ¢œ S- Ãb‘¼†„¯ƒ_¬PXžY"æÿ-æYfšÛ°–mÇÚ´®X! ŠßR6ýEˆ)ÓeLF”¬vj‹ì“âV•3!YŒ5q^%sý™ïÕŠÌqV-ˆ•ìÍòº0ôÂÉÖ~!ùLí¯H‹’0 o%Vg oCnÐK¦Øyöô鯘è˜iH&û¤ rõRÞ•n×ç¬yJ&¾üTõ#òkŒ½Ê6\¶Ö¬mûûöšµe³h™‹Å»&ϸš äÁÅ¡H¸RÈYyqÅÖ2$¤>´Ò 24 £˜$€Ý^–QM”!éNqïL)Ì»)ò‚!¨<`;Lãbš9 ˜Ù.@h¤¨$±Êšµn”RcÖý‡pÿj¡‹Ü758`®›Ì`hM=”]÷',ldž­³ŠùCÔOdWÏB£n¯"²$µ¿±S§JÅGƒWn°Xºí´J„Ÿ%æµPÜÅ=añ4AQ¢,Åãtƒl˜&Ü3_>£®ìe¬ä]7Ö.áF–2oÎØzQÙ!ëäÆV¼Q†+‡Za}ïcسQšü1Ã2Êd/žx÷/<†v½%ÖW‰·+7àEú.EfŸüjZ•“;¸yË·(¤¶Åï)²,ä3²/îN·PÖ(dá‰O¨yò\ä:^ÔkźF5G§Íß|ÑaªŒガÆÌ̱Éxpù¹¸”òc›†DÚS #”NËYrV†³î4ßf…g°…@ÐO>Ê}6ýøp›IÀÊïúœ=ÎùÇz¾!Ȩ}> C(î¼a/ÎÝ“S/ŽiGîm⃌êbxÍÞEÉ—\´0{b‘§aÚ•ñ(ÅÞV¸¶˜–Y’ªÑ ÖÌ+LÆÆm¸7"—^™#îdñƒÍöÓ81¼ÀOÕrgS¯s4êN^`áU¾ã»Ò¹*ukúa]7¬hÀêCØç¢¨AZ`̺“L”s´áˆÒ6´1èPc>`¥r£ßäÜOì1yé;èz|˜ R* ¼·$úËàì€%‚y©¿‚„O’]k¶¿ÎÓ7„¾Â+¸Ê·ø¤?‚³0uÒà¬!Κ8PøÚz~ èç {ñÙÉS¸Ç7±0@QÊäâFi8BdšÛe¥q"YW验h˜$ê÷ˆ®ã4Æð6d,Þ¤rLá-C¯€9…a?¹ð·)Ëã‚Fd¹“Ÿ~üþ”Ý¥Ï^ÑmöŒ“¤x&iä;1l?léŒüÔ ñ0Òdd›ÝQü¿bqº!‹š`Àº + m d®éÙ,T>жE…ˬ*ÉHoaä€@ßò&Tx,?Gžç­‹lK‹u… _,jºEñ]Œ ,Y–T%]ˆŸä°jQï訦ôŽ `ÇeãK  }n©<ôÉ«øÎ'ßV‰O>TKŸ\DÀZ#œàŽ8ù"N×ÙÕókr>'_Íåp†8«á~(™ÍÛ÷G4aTéQ¿ïô;^×¢: '$vBIœÒfQlþ&€S‘‘y`2å¯~^Ê¥^°Rë'F´DecÁ†– åLƒ´-ÎìQ–/@¼V4¢éŠÂ”¿’±JÊà»ìžãÙW¾ñH8ž}i¾êâ[UDä£÷²ggæhà¼%¿­PËzi@‚È·\áQ;AÎ@ÅXIL¼£ ™ íÈQÔZrñá²Ñ*|@ZsX–UÅŠruGÉæ¢’#W(Zi>ü‘dE¼‰Ó0ÁÛ°,Ò ˜8ŠYA7a±¡QPc'ômô©dËŸ)àz@‹u¸¢Á'ž…ƒCI],Ð0-F“µÏÍØ-`È* +# à>B\sKr²˜´°æ-¤)9='ï²´6ìõóê›:ÐÃñl,¸QACé(Ô3'© 3#¦”7¤™“3eö„‚ÅîÌþŠÚ§ÌêL*AŸê mlMš:GÓŽ.Ž4~;ŠK ·;»œ’Kî6 ‡sqhâî ø!ì¥ÒÔ%1Sy†·b|ã‚zS»ŒÖ|Lµb7o^! °µÃÎTÈÕy ïa‹ß ø”‚´XLUd{úùœŒÑ_ÂjÇœåiVk‚-iøžÆiîžð¬IÒžHc&ûBœPÀr“U ¸Ì 'i/äÀïU†ò ¶pS„ÛmXp&8jG‚֛o± ÓøŠâOÂ$¿ —´ŒÁ§‡–ðx²½\¥Zh9ÌX,Á1)v‹,Ÿ€…ŸŒU]¾HûJÍ$E3Q,cX¡ššV[Z„h$|Ǧ6£Õˆ)vÑ%µü×Ô4m@œžõÉ»ÄhÊÅmÒ1u³§­±‹VêKÃçøo€.‹ˆ¬P8ÀD%‰—W ±„ïÂ¥ê÷"5 0³£5Æ'e€°Q aò_7¹hÂ?Â*ØCF¼ôúÌ3\¢Kôuyày×ǔȑsM  ùºƒø4RúèbJËf'»ŸJ콺Ĕèù k&x<(%¢÷ÔÒ¥–Èyw³èåH˜Ó0i|ú#ÜÁذ‡=ØDø6³.9À]Œ¸à´D6¹UI~® {$•@pï‚8â¦l€„©§ŸèÅÒÀ›G³=ˆó6;æ“6_FÒé 4I¤IȨE„§xŠeš,ȾŠ0\ÍNÏ®%BŽ ŸÔJ/°“zMÐú£9¿ÁœC@‡CPÕ9rÍ춨‘›7¸j}’¦ŽÐ(_mUúdîŸÎýã¹ÿ þ„–«€d9R-¶Ð(nU®ŽìëV“k‚ö'ËOÆ(ß½>Vy4Ýù:/ǶÁ  ‘Ûñfá=¢ö¨-GŠ…ºGX–ÛÝ:‰Úø¨ÍŠüŽxM²¾ÝI«m(òŸI¿ëy&Ép§{hòFM™À½´@#7 ë<¡)až`#2¶*X15³˜µßš ´”€cª{ÜÅâ‰'—ƒ‡BÁÅÀ1úœH:±Œ,h8…˜-·½×õí5ˆk®ž>ß …Œd¹Õ›©…Ì= €?žISø<*Š#öèÄÆ#A–„'k¶nLÖl bá >ùÊG‹båö<à M’ÌÛS‘8+ˆ³3°5YÁ†j¥€Q º ÈŸoB¶¨Ò¸T¥¢€®-Û>΢PuÁxe£šÆ”_€­éäÖ'wSÓžB÷­#¦¹°—3Ïï,æô…´¦bj§5õ»®°lùÍÓéÂVaÑ·¿«“Û÷74­‹B´°¸µI3¬$ÕRDòÖY6 §ƒräòUL‰ßíÄ>ÓÜŒ×Iç,¶‰¤F‘ 4š¼)²í°{¼dó°û¥®ÖÀ²}²„ø?Ä ä/=ëÕe´‹‚œ…;:o9þµŽ¨¢x½¦¢Rø'õÄü=.ƒm‰`ÒºÜçnø>ÁQ~ÈøàŽ/M™¯7úç‡H£Ùª£*Á $PÊÐÑÄ„’Ë}À°÷Dâ®2SZœ½íRSXµ²Pìq­ñêEPåÖŸÛTÐ䙀+ñNpÏP½h «¤Ä’ߢqMŽÉDØ Ø÷×È©´uçéÀ`zQ}gŠ ×…à—8W ú¤…Ö¿ÕAï«ç×]þÂë³ëýù;ž§=: ˜¶³¡‡Ë|Žýn0dñu›¿R²n JHw*E»Èœ˜Ä•Åq ïÎ ³âÔjÂ_´g°iqKÊJ«Å»-.ô³9ÖÃhÒfM"lëcJq/¬`í¦)ä”yT·Î¸Ð…Ë07+fÔºàYŒDáñëQ[U1{ýïš”à¬õîýë®Û ‘ûzr)#ŽlÂ}¬Q™p™tjÀ' Às; ^× úÿàɬ~1뜿pñ•êæHúy4QŽo¦!š×®é€_:ß?yß®ç›Ø k€¯ºqݧ-T½8,ÓÕ›]krÿmUÖD½pB³•K)U3[9ÓÃÊÌU²oÈu¬…\=%› (ƒd¹ØÅGìgª«à’1’i²‚»×¯h'}oó¤tü7¬ƒRsx»ÞïÀ¸VœCŸvGÃðüGÚ/NÂóšDw­12aC‡fÎÏΊ€à*Õ-ýißÁÄ“=±©Gø–ú55’¥Ü['u¥üžçmÉ“|'èîrª³/3мr8í  "î?$¼WÄÊ8k£b‰ô¶º#òz›—;RâàÀ2O]´V=¶á£ÁZ§«À5ya´‰éÛ™¯í_]…*ñMK¶íYJèúË€ØôPˆj`D~ä–“_ùÊó"ƒð/Ä®Êà ”ô¬B"¹óS ‘>Üþ®OÔ¿™pÌ%­j¯“,´Y„·yèS=Î|Aéééù¾Éý Þ†“†B¼|Þ>gcUÌ(r­Á!¯"v*M£Ã¬…>«¥ªÛÁeÏáÞ)?ÝݱîKPÊ奾¾èÅ=à ~Ñx˳£¬¾«_Û¸`$« ®= oÜwÆÈ0ºÃ€.W7ë I>¹×î6K@0K¼Þ–mÅ)%…ÀZð®2¿i(.tsõ×®¦~bj bGñYœv=W%G:ßdáÊx«]5¬S##n§úb«TSšæu\°¦ ݾåÇ΄ۈ%žTC>Îx­Â6Mk¾ogD×§õ5‡Ò±0‘ QCqA—õ– ®¸MÇŠFV:Ö{ÌVåhH}_»z¶g¤‘sô•°Fæ¢ë óhŠºI:@Ó‰Út‘Ÿ~úiòsN§`NCniù>\럠Ÿ&Á_ƒ‚ߺx‰<]ô_f)„u]É~ÆðWøÁ58¬½µ Ľ¦Ã¾`Œºµ2ä½àyмiçÎú–mfýºÒ«J T€ #üú®\èâ/v #+yÙM’-Á$ !Ì&ºP–pLðI¶r@߃ˆN^q‘¤)Œ4­Q¶Ð+:º¢fÒìù¹ÙH—cÒ®9W³÷{^9ˆÆxÝy®OcÁ“ꌒɔdQ†‚þ…sÜÅ!ÚÎ&“нÕ @Ét˜Ó¡ýIœOuüÿÓ$r¡¿ÃNž)Õ²®30ßÄ)'µ³Ð cjÐûû0f.{8.°æt„ñb­_Õ”Asæï?RyDü „Ëap )4º,voðC’‹±"m4Õ©½M¨ž Ù§Z Œ3ºÏœâ7xB[&ÝÛÏ~wdû±¢bñóe©áD~Jž#åWtÝOõ™ÝYáÑ|}šØ¤ÁB¡ÁÍ®c‡Þ6زÞpÚ×e/W]˜•'#q}`üp*#%ð$· F{¦ÛJÎödøD!>Ú΄÷/_\²¯â‰é™9 ·‡ ܇¿éÝu x‰åìO¼Äú5W›¬°„ š­'K{+.bk/Ž‘Fò1Ãä"ºHCü'Ómįî)4üPgSÔ$fNØtÊãÎÀ÷4|)ºÿ7HÓÁêUæ{Wm]Ó lƒtªÄã6xóщíÕ ¶4Q…uzCSa á°… \¶Ï}múî5HýP´}ð°m|ZÄM'Sƒ½¡)Óo%õضÏlyh³ÆŒ<þ|#§A¼vÄÖk—_Ô42‹ëAÞ¹,JÏü{%8ìŽv’Ýéð5öEô«Ò,ÇBôÞ¦w´(½™÷ôfÞe%^ú„¿ýpEÐrÂ?¨–ðùÔûM! ¯ï¾wŠ5ÿŒ3^áucË1]÷ÑlXxí*öèe,×K ®{Ÿ ŽŸÏØ¿n;— ûÊØb¬ÝLÌ-åïaõÿ&Ü.£Ðé¤$¼Ûp°0”'›íS›„çŸPKu@,F^ÉÉãU/astropy_helpers/sphinx/ext/compiler_unparse.pycÕ\[lGv½Ýó ‡âH”(K¢^nÓ–MIÔвdYïX­µÖkZiÊ–¶<é™î!›ê™v÷H¤WнkoçÆ6‚6o#H~’E¯üå7_û“¯ý ‚ì~,$òX`sï­®êÇŒèG ¡ÃGMMOuwÕ­{Ï=÷Võþ­:¶ÿö_/6!þ)àÿ‹¿¨AøOX±–°ÔÀÖÁÓ ­Ã’í, ]„¥"hôY¼,•¸]¼2´G`iÚ£°4 í ,U =KcÐÞKÛ =KãЮÂR4§«ÛéÌ)»wJü _¦ ÞhOÀÒh yhBrv‚=h°´ \¼1þ»ö˜xÙ†/ã`WÅËv8³4 ö°ñ¼ øà}€¯/í¦®/Îì†?ÕŒ›½ c4ýv×õœ f…‘FA¯õ'4VóŽáv"ßpÖf/²žct7¢ŸÎ±Úؘ?7W£×éZAèm?µÈºƒç[Ù+GãV? ¬NØòƒvh¸Qr¾Ø]ËsíÌM ãzd¸Ø´CWóœH\¤Ù §y†ßÁâžÜ ¼(_Åmwý€ÆbEN[…³F«×iF.]Ôò¼ô{Ûi¹—ªxÔ Cw¹Ÿ‚·á«5¬Ðm¢ º(”ÚÅ¿Þ »nàØFc#îñ‰çjÏŸïvææ¶?Ç" æbÙԺⴖ»ÞvηPZvÜê h|£íßu赺e£.†³à4­Š6B1KyªÆ?øY›dd5ü^dœ1"·g¶ð"Ø6Z±RsWjc.éþ )4JŠïÞuipÑ|c5BßëEN]2ڎǺNR]Šmaf„Î,aq%EE¬-X8ÿtèf&Š®=ïÞå××z¿.öüzŶ]zÑd#¼Áòõ×›zl“tÅ«d—G© kð" îÜ×á¾ï@ÃÚªNŸ­¨\ä .ÌÐÉæHÊþ†˜‚«±®`é–ËN„úÖs¢2¾ñPóÝ®(¼è12ì•çÔ=·ã¨Ñ‡Ý%œaRþ<žëÙs Û £ZÛjúáú‰“Ï¢B¬Ÿ=S?szÎY^žÃ‹~w£¾âx]'çÂîŠÛYŸsÖ£99CõD_"’qüv/Ý…ú ZE›ÐBVÚ¼j7ü{Nà’ð‰üg(ýþƒ85®6°9NNÿAœ9sLãæK4?»ð¦â¦Æè©ƒS€Õ"8  €– Lx½F0Ž'èR! £Ê#`"¶Q¬Â•*ÁU¶ÐQ‘mœ+„yTÙI¨G•]„{T™Œ¡`o'W{Wö€=É•½`ïæÊ>°ãÊØ{¸²ì½\9ö>®{Š+‡ÀÞÏ•Ã`àÊã`äŠö!®<öa®Lƒý8WžÛàÊS`?Á•#`Osåi°ŸäÊ3`?Å•°på(ØOsåØÏpå8Ø3\™û(WN€}Œ+5°seìY®< ö ®œ»Æ•çÀžãÊ)°ŸåÊi°Oråy°ŸãʰOqå°Oså,ØÏsåØg¸rì¸rì³\¹ö9®\sqæ<éÖïba¼Æ^ Áaªé!Îú” tï:ßèî:ä@ª®,ÞTÐK?i]DµÐïM‡}Áã!âžÙÄ7:‘µ~ÁðwÙíXµh[Q„¶«®ƒ7FÓ œe+Xvìoc Ñ%ؼ]êX)pEƒH)JS¥Håj‰AHCÂ7¬åò þiìoéaƒ$Q0CØŽN­ëR¸ÖÂÈÆa5N\6üŽô¬òçA/8ŸÜ):Œ£¹$£™õØÂ a#U+DzC£õéf€ØG Y·ýºÛ±Ñí1äÈz…?rî5W$ë÷7ßòzá ¯:^‹+Ô/®PÇÌ!%LÒ8ëuòâõ:9‹ü”*šø­âoDGصèi×rŽf›ç+˜áŠs?ªë°{/Nð^šÔN5þ8žñd^_Ââ:Ë O×upzü–a_‘A4›~`“Cljb.X‹!l1ñ41e!]‘¦qýIþÇÜGÅ!uÝÜ/%N·x䢥™®ãLz•ÿÑ+Ú㺥2œÝJ”))i(%vIÇÉçw»2·œ”ò¢!G[[cÝ%9«]2~óñ!¨ þ*]^ça7iŠ´Øññ 5d[á@q•õç½®A¢$ÔMaÅÏœ†™%ñÙÀ±bb—Ò‡ßî¼á "£gU@“"xä3ÏæŽr‚¯ÐMŠ,ƒªÖ/…I!…¢ÃYq°ÈÒDÍ;ƒG*4¿TÛª1zúž¯¥æY"„B‰u`ŠJhú¾ÁIX?@oçoO'`q_ÀÿÚ¸Ez±ï°™¨"Bg±O}PHÞ£zÜÁ‹­‚pãX£ï2æÃús1ÄÄÿc":k¨£Œ2ì6ºŽq“c ÕoÖØ Ô)ÉÁÜÄ6‚Áü#ñGJkuš¸=°I|“’dt¤puvÝõz ¹$üõ:Ô`Ülœ v;"* ^š-Ïé¤4ë¸Ô,—¥@m‡$îŽÝ¢[Œ³¸«¨UUÔ­Ý4k&­Y« =Ô™:j$h& Dž&Y½‚òñœ8ÿ@¦ŒD˜ÌÎm`N®ßûU§)ªÇ‚¨Å¡. Œj”¦²%¥K‘[G®„ếr… ME÷J`Žñåõã±Üæo}Ð*ô4VèµÝBý$ÀÊ%­X£cBÞ”'þ„¤ý²ÊåWTÆÇ{ÍœcÚ2.'§s$ü&E.œkZá¹ SÉ"ŠlÒù!ÃxÕÙ¸‡Ô/Õ&s1¼”¸Šm„J µßÛHX|HÒÁN°]@6HŽÊ4¨xNζ g!¦‰‚0&VBgDéc,èݤ±…êX¯gPJ…‚«9`P´×Ž£Æ¤])•'ßÜŸŽ‘ü_š=qiöØ¥Ù9,ñÅp¢fÍð»ä& `²>@”DJV ‹ýy)ûˆ†âwS`1d½æÕ޲‰ï*OZ$Ø—@D…YoÇÄ[xÒùÛoeY‹žŠ¼R&­ø Ÿá–(iæ3ò|á9Ö&ÿnÙ%œ‚Îð ö%7bâ¢$_ËJ~Æ|KAs²ŸFågvsRYÀ>5§úÍÀ<-'j8(Âñ|’LÀAÎŽ™ù²MÀ~9~È_‰ß¼F‚ËIÿþ—WúåXú~ðç› _ÎÿÀ&<’Þ =ÆiX?cÎüí9ž (¯CFþ2y´Ø9€œ¢µÂ”!ø>ëÝMÎÒ%íOzT–ÐEoF ø1_äï7¿H1w‘uñ¹@I»Œ:@êÒì×Ò+wµ¬Ä‡ñ¿9vŒµB$?ó8HÊqÍòBç"; MŠÙ`Ô飕­Þæ]g¸mñM}üÁ¾ê*äð·ÒE—®je„Î2à?ò¬J\«j“™z¿]ß Zëçbw6»– mf§–¨Ñ~´Y8›/)#cÉ“Ãá0ÎX€9/[ ‡ZQoÎ?Ðmè üöh à§»È(¡¨¯‘^^1š>§M"ƒWUü€ÉíDβˆfS³„b-®cl7kLc§=:MoØ^º,D„cú4-(ôlGÈ-޹g*¦xçژȀ Y‘õÉð6µèÞôÑý 4fœåšñâŠbWÜ(<𗉢‘¹g8¸M+žõyÕÛ„|,[J[ÖoC>ëæ².ظÞbûzP„>¿ éu$ü¤80+CNRY™â€¬L)ÉÊÐÔŠ´Ö7Òéå4|>HÒ2ì?YÝÈi‡)ÿY‚>ÿÉ'ßáòîp–#æÝfôC¹>¹iåGw0åðuO•°ÈXË‹÷VœŽ8mæM{P–;>mø–ŽaÿtË÷g¬£[fE52(¸%‘ä¼6­Àþ—DiǾX.tNääk[0¢ÈÝŸ(HÚ4›Û]Òf†µZMŒ`ߌ€øËžçvC7ü×Ü02ðñûùa Š35‰ëùV•üš¿ýf¶0o#²½"7‹iÆ¥Â$]w*œ— K„<ìï×ÎþÝJXÙ©¢O·¿m¬o¼#÷\¡9Ì + óhXï¤ì"äUcjξWž V¬‰õO<3ñbæF7nû6ett¢w¡ØyäwœàTŒ›±s³BÎ…¤®á@ÿîAk˜P¬r6lZç×ñ“ÿ¶2ŸSᩘ`q‹,kÖUÚAæ–+°¬‘ˆQëÌ·÷íFtPïöRñQ`ä½¢=¹ñØ]ÝË:ªm¤¨CSRiJ0÷ö‡q»œu^ÔDv·é~Â>ìCy¦ˆÖ>ü»UW‡à„ñ2|};ģߡ0]ˆfB5ßÉŸD»âöØËÅ"öL_ðµ 0á¿È*‰‹xƒ••]'z)ÖÛ8ä •P=(Â`6²¾€mØ•Šô|°,txTÜÄêyQh>Òv½ãv…S¦«›_¹-`Zª7íˆ1Ÿ¤C„äy+XU¦P7ÞÉ MG1…O³ïÙÁáÈ>íYí§…«è­ÉcW1\×(”òNei!@’ˆtŽõ¨U䥨WãÕÓ”•ŒäBfµ3§#r>Ú3›O1^Ç ŸKéʲÃÛ‰>ÃÂL’›0_`½ ‰˜$‘chã\Ǩ rBCÎm‹b¶ð±Ð;¥ÉüDá°F°5¡Oè ®kø)d–m>ÊñÜ÷ù"×»_Ée?«ò}‹iB\R6ž0¸¢âÅ< H"¼_d7FhK"ÁÓÊ›”>íº*-ñKwx“xL©…ó"¡¸-áàj¼›G¬Çy¡#ÀPfMí"´ú05ídÎlÅQ)>«ÎØ1Ы€Øœ‰±¬é CAh„õë­#¤OÑ}´1™N¼{ ©ÜÉëîcy[V4­ Ÿ’ÓJ>Œ§ŸýZ<…n6·”´-¦/TÈLsÁ*hZHnÉÖ™[Á2ÔÚi„œ_Ðbo–Ú¤v‘Œmq°{¹}¸Ÿ3ŒÌbö¯õ#TpµŸÒúcÅHQ]’%ïRzÉÛÏ.SÓºsY®K)…[[Œ×*ET@êÂ5Šív—/±COöÑD"ùƒq@b_Uº´{€- M˜3ñ3ï]þžX—*"jO-^o/¤o¿ãà‡hüõj¥°ç»Q«ùy-‘1*p–¨E*†â²tŽ"úŸ¿½ƒµD§HÿmÖ.Óeb ‘z§FsšYð㸡Ī!x’"ÅkH2¶¡— §"E`³29T’·ê㬊„517AÎ Ìm·g½ã&Ãx*F*“õ-µWÑvi5J Üï§…þÌ%ƒs©V…,Û” ÁÐH5,æ¦8)σùÄ Ûóæ7”gP¾5Ùâ‘Êq­×EYl‰Ú/znÓù^"Ù –í¤(‹ýF@Û«×—s»´~!åsEâ e{6·9‡yú}Χ¢ø‹T§ÇR÷ÒÝ3F ÷g)Ò»IÈ.¶Úäö\±F”‚«@`ëünEI×o¬þ©&7}¢ï¥xýð€­éŸm§CŽbÚ¯p`hƒd¼µ£ïkrÑWÒ¶Ï»è{b‹ãÅ^ã¯6#÷> RÖ¯åHŸÏZ…H|½yšÑ¿O.½{-!Ÿ +l,¯Ù‡b‹ÈúòöÞ^#¿¡LXÀâ0Ä:‹5ln7ú›l^Q˜ÁÎÄ Âü7 kdf<9t^ø¶biï$›SDO—§§âX€–ã”Çҭ–r­‹ÉZb¾ :­üÒ÷Ç›ï—>m|1I¼‹i4•ÏÆšÄ™,_j¹…ÍÑÔ’g_æÄ­($K1bE3kÉþ^jr‡›ZH`̣茡nKr·°û?QÆÃ!1áÔžüâ¤Âª½Jø‘üþ‚‡ePyÈÓz€À¼cÃÿJñ"@Ò_—¤ñŽ DE•‡Þù¯ØEÅ8ø½S†à§àЭҞ -qäS´.rƒ“([w‚–ôÊZZÅFÓꉭ~C¶ÒÓ­F$Œg:V‘+ÁýR¶c?⎕wìGÙŽýl“ŽUTÇŽhùŽ%±L²cCæ”ãaÓ#‰wZ‘ÉßCUÚÍ^ïNÓ±ùÈügCíïD±îmÕ·u{=¨Uñ»š¶îš†Óƒz5Ü'''ë¦ö#¯6¼O»«÷0)+N<°Ÿ—¬©[~vU |ÆH½†¥q*ìWΡÿ¾…m×m=–e:ðf›³M5V“=Ÿª¾Úñ‘÷ƒ~u¦ý °—Õ¯ày+¨¸­Ç"n`ß¾(¼ºgÉe›HÚüUë-ƒCh‡±‚ƒM{ÞÔÃhш?/aQ¶ ô o~|ê|Ø7õ˜" {„w=W\«†‹±n+¨6$–ž|L³‹™×|¬G¾Óül-B{òÕ–íÊ€ \8fAˆ© PúH[zï‘HamoÃVøÖv£ÀÀ»mê1¬;Œ€G—r‘U„K {¶`ç΀ÜÀᱜ”$†Æóe Q¶][òÝ~¼/q#>ÝÛ®g (’C[±rñÃæš9žÑÞß>WÀÎÛÂ`šPd–G“sp {±` oS}Ž™{娕ë®ÝÔ¨·R ôw²ö U¯Np»lÀsÖœÀ‰>¸˜S„‰°ÄÚÄôe§^o'%é(úgç+Ÿ‹ËUÈ.’‹i™ d“”ÛÃÑXˆ±'$¨8ª$(zÎáI*Ì‘ã&²`Æ7 Ÿ|Ý„$ÎÌ:Baj“Ǫvo@âèm#_gl!äÐd_° C‚µ•=°Wk»xîÚ-¬e_{¢%ßV]„Z}™©ÐGWC<¾$™¿ïj›}˜Ê9‚³ßß¿êÖÂõ¸N2æøºµ0ú¤¬Ûúzñé³}zjtU¹õù†#S=–Ù¾Äó%ÌXé² ˆ7 œ"xí’¼è‚}rX•¼­¯Û c”¤äÞàa·«ú{Z&ÉÊ„‰Ã™o˜5ËŸcü{lôGb~|¨ªù¹šù„c=;¾âË8tQWtô{>Þt›èÐ[ÎÙËfèbcoº |?Ë0,¾wX1Æ¿¾«vû&>†ŠvŸ>;ï?ûÂAÇ~4’øÀï§<’%3K˜¶²± –ücÕ¸ú /I©êBWY16Mgo?´Ý-N¦Ð”3vŠX²#z'dȱݯÆRbއC ;ÇœAh¹ â¸$ÿR­ª9×ÞáÈ,jã ãóë¹ Ûë5çsrºi2Ÿ3€¢HâkÿÔì¥/Â¥ÏÍÚOpމ¸D ýø’Ñ\8”œ%OÉUœƒÛÀÈÂ]˜Që(ĺ$6@Ž-2êoïo·Ô¹Š\x iFù©‹A±Ëòr… ÛLï㘖Eqv¾úB|’1^¸]$éì½­-Ž;Ÿ”A!ôöIM…1–0ÞÞÔ 7¹'çÂÇ›Ñ ‰µcz#"gFF ’}Ï?ÖÝaáã-¤0DQ$úXÆÉÉÄàmSÛ%™»¬•¯Ÿ§>s&¶/¢˜=«Ì™ß‚ŠÊ$où|eŸ¥0ÍSÛ„8Iº«÷âóï¾æÍ†€EÖ¼¬õ&ý,#bCš0¤øÎ<ÁÓyµßC`–¦š,EUN0¡j ¸ñž@Êþú‰äóu·Ûé¤ýì—ËáiZ¤ßüðuß5üÅåí³¬x‡_àŲ:ûõåÙ¿žŸý©œŸ­žeïþ= ød=ýŒ)Ћ6ƒ•f9®þÏÌ—:ðÒ%x×Î$ÁžÐÙ…L_i?pš¯`ï -cý‘S´íP‡hêöÁ¬3T,BPY> žtž›Ï9+À©ßïô«wÖðW*¯¤n8¹ž`_âúž’šï«q}Ã’©xGK&è¡ü˜Øëà³ÓæOü|‡r_µv¡ôcú²›_÷Ýa?xr+®—ç+ÈÀØ›®h>R¯—_­ršÌŠkž{°¸”a"ÁþQ5þºï»>H Z™ŠMF£M±a—á‡á†ø ýîyP&”ǧŠDp6À7ÿ@ñÇs­Ò˜l.‘"e¾µhˆÐea‰,ô‘(ÃÂq²'mv­HêXtÛnx¤ÔèäqFU†@Â(nÁ¡ånŽ›Î íg—Àø˜³7,.˜íΡý.ÄÒ…\{•{¤DŽX0OpB8"ÉÙy¢¨Á$ÿ蜞¯¦$[‹ý–b‹÷†#ì¿Ë_L,Ò“œü+R'å‡pÈYŠ3yŒD 1ÂLWaãûûY®Â݈pÉÑ(JoÓrÜ™$ HÜ !g•ÆÚ‹[ÁÏ£ÎD6²AôE¤t‚2œ|ÈêÔñT‡ÆqEϷׇzà 6t豨l…V7'…Üu=;+ªÄãK^­a[ôFRÕiy¢€ $ÃhÙq‡`•6ì܈>iýwòdª!Ò”Œ½`çÁÝÄ2‘ÛN°DàR,Icµ f ˜7ˆ–õ0f °nº¸ $Fbw$“ìÍù*$’. }YÁ+” bå9?A‚#ük_]±AYŠ®šV¤Žλ8‹¦š±Ã6gú„}‡p!iÌrf•°1gcõÓejSáŘ¥}"#À’†Wù´=2cŽ@Ê˺›‰¢oL2åÔÕdža…ÇÉ/éòòvž³Õ³Eö įðír¾zv™ÎŸ^fH2éò¬å#ƈŠÜVI–dÀ@L9‘Gœ‰z´‡¶_zU ai=wJé¹)O µ¤ÊiPC*øçórª jJÊý%•ãô\æä²x%f•ÿ§tVMð—ÓùêÄBS—È6Ç$¨Ð'ª‘Þ‚IÅfH£é%P•ÖR” T×€(íÜ﮺f‘œÙlSÞYfà¢(y*&¯<¬¢Pa®¸r&Þ,þh¡~|÷ŸvPÍ%O2öŒf7½®ƒCr´C‰t+öt"*ñ§ÁØ7ÕÌúSp³—OAÏ€ *iNŸœÂ¦ Ÿ†Ä¸6*ƒ7}ói™ÚGâ“Á¥}žÐ!,b¶3…~I‘„ö˜T)’qÞ**Sº–©´!L±Q4iå\¬¯KeºQ"‚^®n âþVKöéÀ v:$씥b1 6’N×;Jƒ}K}õÂ(mÉcÔ̺ºø‹5S ú=Ô;UCª¿Qå$ÚÜd›óÂÖÉíNíi¦ðÌÌÎ0Æ-o ‚E]º¯Sƒ*mΩä+ËDuR„¢Xë dLè ,ŠÓ¡xw:¼#éé‚§§9óHdz~cL†%žâ(±î†€þ~ˆ9è2lnEó¥@ü1\ï1U|̽ÎÎW3Ëå4ÂÆH›¤$P»¥ŽêH#EŠ£q„˜¸s>ƘIí0µ[6wª›OER*ÀҊˤ±4ók¾uò'Iæ†:ÓͶì"$Õ>"!¶›)Ä!‹¢Éމ5CQVFYSá¬81CO–=ÀFâcé›—E’³’̘X&;2I',“SOŸ9 7nö,!Œû¦ ~Réuȴܽùxlçҙƚ£“¥É7ÆÞ•:±wѼ“Ûý8¹i¿yhÚ+gð£r¥ßÍ¡ÆAMˆ¡Iž{Ù¨NñcŸ{Ñ»ø*ë#& cTé ¯rT¥RƒÒˆhʦ*–ÓÄ¥ÍZBÓ²KH2A´sÿ)tƒú+.‡Êm¯f»ê®ÞUM£ Yri¿ãnvÙÊZÀ¬ïð½\_zu„„Lj¼G׉”…v€ƒ4‰aèrIè~¿ÈfÿWÝ:u{ §› e¥˜¬ ~N( [àÄÛ …€lá G+kâŠþÉ>¤N›¡óaxæTt°ã0z“'c‡ék¾ð"îMÇÔ¯p5ÓIEÈ™ë)E«£ü1zxAªMÍGI¢'»|œ‡-™Y´Då–ݰþy¼Ð/ŽÁ\ KEÂDÓ´KýØß‡y‚¯ÙØQ˯)ŒÆÒŒá~˜Ëdö³í–ÏWØ2þUœEWãwk¾ÙO‘Hâo3båyš%2h%ÜÎôhW¬Vi-%þ,qBƒÛíÈ ºI)îOËDuè”dEÊr®Fœ Å÷z i QÊñÄjk°šÖj[­KÇz2%> â{OkâT2Ù-4×;ûØŽWx˜*C,XCt\Ÿ„-X¢ìT,JÐJâ¤ùõä³[I×f6Äj ,[eiáÈ.þ2,ɨ§€™«¦Þ«-ƒ+šCc\±.»—-¾¿lÑAÉlp Ý Àýh¤>ú@2÷.”ܦåê„@esuæ&\Ží·¥ÛüÿF}&Aqüí^¹?\5õº‡BÍ4F¤vfÇ?¬›Áö§»nsï û‚P^ŠŽÚ» óÂÒÕøJ ë‰Û6ø0ílBßùúÑð „;‚'`½Éf²kÀrÚ£\ ~ÏåãJ päÔìT÷šWØü  ï~Øj’ %Þr0Ž Bz֣à ɑ/ˆ&4'Üßj>UÐ/'ULAû­Ñ„8y‘ð7Ý­´Ð;¾»Ù&÷~ *ÞŸc¨Iqg ‰xäFCE*G[ –_RFTEܹYÛod¥jö…æ²# LÔ2Õù‹t RÃc1¼LˆÀ÷}öa¬!䎗Xu„F¤L´ÊÀIˆ|+h—±7CRŠå´®ÇKÑ¦Žµ™DÃ6Yê!ó„Èu§dTÈ8†‘Kl^»ZG@ÔªÙ1|2¸Ñ '5y ¥Õç  Ôð¡MF@$Eá¬SÁîTI½¡?Ës½×–VÊÉÄ­ƒ°KQ}¥Û¾°Ò›«~#+F•ŠgÎ!ÚŸŒ–|Îc 4é±% ÇNM«õÓcÌX¿Èž ªºÂ–¾ÕÂü²rŠ‘¸ó`~jgŒÈÕ€5jó˜ä… 5Îè@ódk.¸JJ€‡ÿPKu@,FÁŽàV±%O(astropy_helpers/sphinx/ext/docscrape.pyc½\[l×y>gv¹Ë].EŠ”D¯¬D#Û²(Y¢lǶZqbGNÚ8¦Y;thÑ«åîp¹ÔÞ83´–)Õ4–;i ·E.M›EP$(iÐmÑÚAúRô©y*ò´úЧ"ý¿ÿ?gf–¤ÍŠ—³gÎÌœ9ç¿ßf3ÿ=Y<¾ú½J]™Ÿ ýèšVáÿP§¡Ô µZ5ÕÖªã¨Gu2j%£:Yµ’Uç2ª=¦VÆ”éçÔJÎöój%oûãjeœûYÕ.¨NQ­ãû'ÔÊ„½®¤VJª1¦üIµN#9õšR·”úÔÊ!ÕÈÛÑñxtJ5 ªQT¯iµ2­8±rX5hŽIœQCÊŸâÛ¦âÛfUcÚŽŽG`•ùÚ{øjžDA­¹¿î~·î»^}»ãw£ZÔêuÝõ ×q£ ß]Úî<·ã†½í€®‰ß_([€ç<˜­WZ!ÝMÑAm-ìµ·#¿Úêô{A¢±~ÐêFÕõíns/ÍkÜ™¥æF-èF9êx~­á1®ú¸Š¨ãÓ¶5cÌ$… ð†NÛBg ÐG'£“7nòÜ)èz²èL¾€¬fÔ”xpRy•ùIê5O¸íV׿°V ý†F´“& «%@¸ôSwÌ‚cÑa{JíjiuËQÁèï*UuTwýÍ vrËR»™ž4m«Â€ jx~ü¦,›eâÍ¡×ö»Âs·jÓt—RTkÑ7f×ÞŠ×~ÓQƒO1. òu3Ãâ;ƒÍ™3rí©Ê” ¥ãG†.¤ós§*[GÔróÎkœÏƸ†â¬÷ºt¦(O!‰ZYÜõGG ‡ T£^5^Æ"4Í ,èÃD‡ˆ#JúX"b™å¦Å€½-`“ƒ€iàþ+ÃBšî- é#1Á%Á°Zi…BÿIGÐB÷î’HÞ‰‘.g.… f΄1¯àq9^]Qœý˜Àj‡à¯Þþ ÿù4ü{gRì¬pŸ‚µaÖr<,•mº¶H¯Û€¬IAÖv·Õmë7žNaL€¬“#]Ή½ÈJÆÃã¬p‘ÃJ|¿ ù>•²Sæ†ä)M~_¢kpº\ih£D£X4‘¶Œ’=æ79R`w}Ò$Ï&ÄyBO9ûM›9!ÎÍXtjCg¥}{áI7{-Ñ)I0ZÕl¾¢'ÈecuvÉ(¯VÙN®V;½Æv‡y>¤9ªU¯„õá¶›¼ÙXz¶T齋æÔ~92’Ž ‹ú>—ÉéÂT!C¿ã…<µÅB®0Vʱþ!篿s¥WbÈ•f÷ì¿”uÏZl˜Âú;i~QmNÀUC§Š\2ã°b‡˜:SÖ!ž¶nÛa¸ÅäÏx n0ú³Æ † <ãª1Ëcªq„;sªq”;w¨Æ1î”UcŽ;ÇUƒË<Õð !Êê…˜_ÿJ±Ùë¶MÇxx$s£Œ„ŸU­i†@ò}49lðYþÈÉG^>Æå£ Eù˜’|LÊÇ!ù˜âiiïüqX=Į̀Gðì1f²œhdH Ðã’ø|Ìg¨´ÒjvkÑvà3%W¶;Z°ÃZÿ©Aä“ k¸f)?ñMùzϧ[Éed¯¾Ö ýÍ–eòôCžäÙhÃR-OòDD¶¶ù2É3~´Ñk„loV|ß}¢öxš¥.7MÊížbȹ§µN¿mž Ñ;˜Ï[®ˆn'ði/$–=Œ3WˆkKÌq«ä&“×_…Ë—Ë€Ö¢X‹Ùƒ/!Si½Õïb]+˜—g×w8S:£ó¤ùóïø;™ù•ÜàKCz‚-õëþÎèv9&òu?k= ”‰ŸÐr¯çUàÂi0§#®ÒÝÉÄЦ±Ë‰" ïz¡{½Û»ÑuCŸÃOîéP¶‡z«]D+>f·üJm„~–øþ¡õý_Q±’œÒ‡EIb ±ùû1¶Ä¹Ðæ€%À‘Q3Äa¤Í1´ÆÍAü†"ÞJ®k°5a.uA\š—ˆ´:Bÿý·í‰ìð‰ ‡ˆ–Ø5^Xp™ÉÅ{GsÛ̳Ú{dHí1W~¤Ö}ÑxPäÌÅìÚ„T1>lûlº¤ˆk? ŽA É*Y”µ¨j¨fWŞϤƒ(ÀQnïWrL¥\É7›47Yó88g¢¶+«'ÔUçnfÕnÖ:‹eõÜVYÑßòà’¹¸Á •ôzF•Swf†ï¬ÐEË`2º&£î8eƒ*Xwëô#†âw·;>¢€‰ÕÎ(M¸bHlq»9bžå+{ _Àì3 êý–uI;÷r»ß¹ ö°ýàjâ­”‚Ž=Ùsœ5|!.3ÐY!_¢Iº)™#3ctk†álÁ ˆŠ}š‹ÉœÍ¹§,­'ž©ÐE†¬FÏ£€çbù%<¬$ÒÆqõzÚ™–9uöóÔ¼:ðµ°"\‚e¬‘ V¬ϲHæ¼ÇÉuG}RoeÀøB›$LàÅ´à'ò#¾ó|GV¤kìM!‹É˜ÕÄÂKšúóã1ìâ·÷ž°„Íb%êõ3ɼ Ë}Hd:0éG,W)áŸ%reF—Sô9£Ç%t=žÖ_W*$o²ö ]^gÀ ‚¾Ê}FA S9‰‹ë9¼ÄrÃÒ=!Ê…@S7s *”ÍtGŽ1h†<´›çgæ!U€%B$®sPLo%¶@z)Ë:`u]ÆŽ°Gl` Šfcñ EŠ9Æ>²µ~Ÿ N¹=f2±È X*|Ò¹cƒS3léÕ‚&{hñA´Ó—,FÃ룜‰¥Xå…U‘4ùtŒñ\"¡6ÅØ>áL:%]rŽ;!å—¯†çæç?øÜå ×ö¿zã¾³‹×pˆ]<þRí§Ÿ¸°rÿ…÷W.¬ÞwöÚ®kÏ=¸ïäYš*¦ 0Oô Q ±öçµújõ0ËQ|Ž™™"®&SÐà%½ TÑD„{ClžÚZ„œ|“IŽèNJr Žàg†JÄ"9)÷M5$Žú3æù ¨Ž<¾ÖºÑƓDzyÒà¨-Ë”$¯E!’ÿTßҲ䭷4-7Á£¢'†×õÐeƒ &f0GEž¶OÉ‹ª¾‹)>oUí9ž  `‚­sø[¦'Å ¸OÓšÇgÆë,2çåà1×,€ËC«zÂê9ü¾JåÿýeZ&¶ºBÄKZ2j½â»pfÒ¹>¼Ñên“‹6tªÖíÁëªþRóÄ=p>é?xÞ]$VÚX¼]K~_’BŒU þgAv$ëÕ›VHäPÔGÀJ×(V P(„Èëã*x’>&ʬì²Ï\6a¤Ë2›Hæ„#ðªTX‡ï¥æ™ZTßpÏ,‚¯ñšÏ¸½À=ƒîQ!«GBhÌÓ¡Û ]‚–[saœ»¸Ò¤C ùͱÌÏb§ô¶û! —¥^×gsö“µö¶ÿTô‚$|@³àêpÛÜÀúu‹¢)Ž$‰ØÓÀâŒÇ@)g†©}È9*f¬5kRlY‘… ü¦ÅTcK0º+É19«èøAÖÛâW²"øš\¬v—,Hߤ”%Iú±ÛN ½µQAÈìo‡ ˜Sq’/§³$šOhFø3lvð±Ëíù%QH«±ƒClº²ÛÓcÜn;Q`ž‡fÝ*¼úvø¦4ÂCxlïš… ÆEQ1Ì|4kv®Q‹Ñ[¡ïWÉAëýy Ï9S3y2ÈI2ÅsD<§õ¤>¥Oê"Ñõsœ *é9úÇïqco>§RÞÑ_ª8‘h!¼9þ+†ãMбûõ¬ žgùȇe\—Ź[ÌëeÈýœºL’`Pý]Y}Új eä8bFÖMÇY6„X[ÑáÐŒ4Û.k¨òå­—ý-Óˆ‘Çϧåqìñº ½¶Ý‹¿ÞÜn5üE7ìAf¶ºÍó®OþîyÄ ·Ó ü=âÒ2g_àA4™³®¬ÎX/žS1/;j+¯öçÃâLy;éŽ6×ÂnZÕ¯Õ‰}ºÿ«âØ ˜(€×ŠYF›“×´âV„3ûž¹˜EžŽù¤fƲÅèö”ûªŒVTˆ…€¬Ê2b¬ÝÃÉÿ=/©Î¬Jæÿ¢Ré²`ä]|Tüñ˜Œ5ÎV76M6ã½Nbk½§‚2˜Þd5ˆÉ´9nsÐo1ù2Ý^N*-ÞR[³dxÀ"{ŽzËâžÁúø¶qe‰aÀ)É-?æ~ý]e «çpiˆ2µ57´aw¾µî6ÉbèžeR%¼äm(£r_žéê…óîê}8ûA2BéèêÂê}WçÎ]={wÈ䚊ƒâÉópÃÄy~R 9ÔwYZçÐ M×{~«í³äi ß/•Bç]ÈÔ^Éb #vôŒ,•ç‰lB$w™üÙL¨iœoÏ‚£1¸1m,mý\úcƒIþ•Ï0e]Yý!kfv !/¬—†Lrc†ä`Ý:bÝÎpaûs†ö^0XbI¶‹¿Ä•JÖ­{ìCŠL‘ÿÀ”Ä n±7ߘ°×5JÈ?1ÔÏDã|…“šVÜ}Î=OŸiË;‹æšûМ·$´7›à]ÀéezšôQJ(‘§0ÂT #LRá»§0ÂáF˜JaI3!s(ô8{b"Üe… [ŒõZ¿ÕÚ­OûÞ§pÁ-¯3DÓ)騥Lô õO‚f³hŸÔE§L4ûν£^êÞñW¥ÃÀª¨T‰ix¤é «®áЮ„lºïtÖz£Ž¾ÓµU‰<¨cýÕÊÚÍŒ¥å;JŸL°ån‘Ûw²ÙÂEœØY s7$ÏoÒ„B$y½ã(Ž­zµ•¢€Û¡àâ-Ë#Öq-WŽ0[NJ÷ÖÀÕ"1izb¥AÙÄ%µsù¬$:ólˆœcÈ^='a m…rà÷ÛµºÒ÷"‰±õX‰=¦S3ï= &áTjïeÛ“Ðð\õ[I¹"ë2Ùœ²;ñ†Jñ†D±<‘ÞÎA%¿ÂvÔÊ·w{Gíö|³ »ÏîÙ'ö7äY|ɰ©U'eX_©¼à-p¨£/ÙóWVŸUW3&¥¯\ƒU…̺£Ž5å6“dÌ(slf¶ž†¶8šc“+R'†-ÿtè.º§C)[ÀŸFƒìRʆ(d±Àž0Y?H8aLïÅ‘"aÊ"! `>£­ML2£¨gɽËéãä Îéé$z˧ö!㉃ëþò¥8´x©* m¶Gm0¬nÇIÐ~EÇÅ! ‚qC“ ‚‚Žù.<`Tš6Ì…0D’(ü‘½þÊêß3efMxÕk ,„Ý…,oæU—µQ°Ã'túDBšŽq@ô¾  ¾ÃΦ)8CûŸC)Z¹ÁÁýc—2—éæà?íŠxÔqœ·¹gõ["f!彪pdiÈþâƒÅÓáâµÓá5¶°Ð©2ª9µÆ5rçÁ.±evyÒòŒØORé ‡v80‰€’°œÖ6¡»ºQkTý÷Ú¸Lä5” ¶´[Ýë£õ› Ile TtNä™Ê%Í‚¡Ìç¬SäzóiçÔ:ž5=–¦±ßId;î1} A€ÄlÀÜŠ±ÁÇ“ªô+«§RÊŽ·þ¢‰ë =`<Üïr”$%MðZœÅ%±¯±ËÄæ궬‚d#áÂ8`Ãà¼+¡Q4M?’×]JíME·1“`ý²(Œß[a¨£¨RVÓà·tœ©+NÞÃpNߣywûËþ#‘€Nâs©ŽácÇNÁùº²ZfÍ1^ž8ÿ øHÖ@’عaYº9–Öu§PÆ3eU|‹`’gzC-ãš©w{Ú·ã§åì ÉsC6Ñ*âiÆì¡ì—Ån›sÚ»ˆ•=Þƒh¯‹Ñýïæšè…ä¯ÉËTqéX8\-¦«ÅXÓ¼›+Ç"æ3hÀvÞgѼ†æu4H˜{oí'`ïsVC¥t84êh8S† ò­¾®Mt kš3DÄs$jf54¸hñy„'¼»Ñ܃&)^Ń—Á"%ÅÎN,»©¨ÞòðΛü/J8n«8°ìò> ïÝ_ŠoAg$>î½4vÀ^N—Ê…L!W8T˜ ßRa¦€ØÌ¥Âláha¶”)å ò;Y/” EqÓ†çXñ²€Ô¦ù¼ÈfÅé¬ãH˜T„ïM¨›å4±ýŠ“±¤^þeªó9›$¡5抡Pñûð°²âG¬N!ló¦ƒsÕD*ùÂÐã1ÇSî÷`a‹+z0ކýšAB_nú]ÐÿšuµsÆ‚ã ÝxÌ3±. É½ßRÆþår€”ÿñ‡# <ì+:ÎAùfõÔ~1Þ:ßg.%)v+õJ§X¬!6tÅèº5 ïöÖ͘ڠթµÛ;FÜqx/Îy[`0XdÃ_)¾Êu³FËÿiJãÿ.ÏŸIiü<§Tm%oW}-¯Œ›‚H¼—E¾B䦖7æH ¾VcMrÉ&ëXÒÔÔo¢æmyEêóåU9ü)G" jPW¤®wÇ%ü‚ºYT;™ÕDÓ6å´Èâ"çÂwn;ø‚Sœ¼Êh%†!ÄDÁ'»o 00 œ´?ôN¬!X ÄÈ4PvÔ¯Ü#ÞÑH}˜j”uxþX%˜óR#—=Þ€‚©T{ïCÇåƪô\þðà‘ÍqíF°Cö¹„OômË2ižg´Õ²× C@9¢à¥ì&¬ï51¹ª˜øËÈÞ…ïÃÔz,eòLã®ç ÜÃo¸´‹™:i’2T_±x®!´3¨^F‹jhU>ûµS[Ý{ïînÃïîÈ–l8/‘"ÌâÚB'Øí× Vp,,;œ®ª;ÒÎ ®@·-¢Zþ¿&Cò[[š p6•/æëÒl"Ý ‚OÂþÇâÎ!\ëöÿrZ]Ôô/úþP7¬¦xb‘?M‹è}Nx"D7{qZps6°•‚ðÞ˜§EöÓTãw¬¢“„QÆBƬ×ëþþÏ´¢M"(Iˆâ#È'{®¤LÏ Ð:ˆäXPòt¦ %5ã<‡ŸCÌ%U&MÅD´rŠü7vÜŨðú“¡nè)¿>t^#¿"¹‡ôÁjÄ€)yìèë±¼_7<’,ŸŒ´›Æ&IÝ8‚ÛÏ¿ |Hz@%ÔÊ"{EÞžiú#Ú:@¨œ`Dª&y=ÆiRAà}ÆQï›ljÁ ¹ebôOœá³°³ãЙØIü4) Œ ¿³i{·5Vd h<0àzL¥ä2«Z”E9]9èUð’`!;pWÓÒ!¯&ö Dó¾\ña›_†íL9¨3Ò^‘÷øhÅÀ'_o˜kø½á¾–Ó N="],j¸ŒÔ(©kh}&8;s´.6ª™·£:â(â:ýÝK©+sÜo;J´Qê¡«ÕŠXV(ómIer)hßC8À­ÿu(¿öðÌ¿ÀŠ;™|ÁœU‡ÀÍsÖ;.ºýõnÜõ˜¯õC¨Aÿ)¾º·@N¥è@¼Íf“qõ |xŽ{.Mu!jb;èJ-šó ^’¦3 Œˆ>±ÓU¥Á92vúb傺¡+2$®ý ÃuÐOƒt1^БVã¤øæƒÇrÜ‹ÚW®6}þ ½«Þ ¸½oMY%pí¼ëw¬"Xøa¯´þX­Õø Ò³ºÈÕK§÷%¾¡qRp¦ƒ[mqÊ›<ä} ”|ÌÓ•]бÙ„áOö®BÉDc Ù–9ºŒ)RB ³»Ž¹´ƒßÿfk´½³þxJš 4|Á"ûŸšÃµÊÖzkÐê=¿Awä¼X r†í“B“†|—QXZ' »¹w¶Á½`C}i¦„ï›CQ{o _Ò ¡ñï6éÄ ‡öˆcµBÎ\Ð’û“y[ú\² v=°]®0-òª¥£²×7ùAêc›gÔ`ÎnÐ =´_òáªD´&µË=Ï› Þö^-ÏŽû@þ’­¡Žçêî.r&K0£]´ñCÜYu´`6%*k?µ&RÛkQ·UáW䯰޺tÐð…ƒ‚A È)ÎQ°,;Â:+gP«ÏÏájÜ,´(ôÀ>€î·E” ¹°ÂWÂ(Ž»£ƒ Ö÷Ñ·ëåŽU. Ô3éEñü’QØì2ÙÜ«¤nCøZÔà…Ë¢†Fe"ҳߠÔ{Ÿ¼ùéþÍï¢øÍáuðñÙƒ˜òÑ_œ«G+ÛëØõÇeôذ¶ö¿ fîq‹|=©î×û ?ÄØ° ’´MÞ`½AèC0®Í³ÙF/IYv®uÏ‘[¤ñ|î}¯_cŒšéèOÎ>pIãéÓ(ð$>,ò£‡zš,I>¤†–ëž Càœ®ÌE]ê÷Êϸ†Z‹~égºÅ =A3†¥wüÜÖþ ²ëMC†Q•$݉—>)¹7z¡Ýֆ륲jÙ8yóDj¾¦G6˜>CX€²ÎhÝ\ïïxO#o£;xHúE‹ÄÁXó½p¥B Dˆ…÷IΩ¼ÃNÆÚ—[Òm¸]Ьo×h–L±Ž”wLÐ+NégÝÅÑÕbÙwß hŒ­P¾úg–]÷–¹Í8ç.GæÁãPÝZM¥÷±Ò=ã£gã,Ünè—óGÑr)cé·vÜÇѳÇÉ!hzXÝÃË#ÏÉyõÈ”î$ß¶£{s³2¨¾Ð¦Nè²AnINû~8~rX÷åŸ ž€øvÓ&*8þ_`[‚ ÂÊmÕ®œ/|:'Bk8¯+L©H©Ü@ ;“ÒYˆ:I1É KùÞ3¦˜wɲ¶  ìŠ`Ê?ôÈÒãï(Ñ[½;;ƒ×ýÆDœNz­ò˜7rÆ®7É:‚ž$„Ô¬4+ñ‡pœÝ"R—ãß"Ò jl°äõ6AÁ+eÁsüw®<‹In{ϵXjG^øbGFÛÇ£mñ‘:¥:ñ–èPKu@,FìEñ‘-ó./astropy_helpers/sphinx/ext/docscrape_sphinx.pycÍZKoÙu¾·úÝìæ›ÔP#Å=™¡‡£‘(Ù±56­gfèÇØ ­TB S*v[ÕêîjUU[M»™ ǰ‘lxi/‚À³0da†¯²ËÂ@ ù1‚ˆ½HÎwî½UÕ”ŒÈŒDï«îãœï«‡R+¯ðvßcªx©ƒ×ÍïÛ` 89´9´ìmñîPLðˆUøÏèq8úÞÍC/ˆ“íÛ ãÉÜÚþøÉ'n;·?vÓïvoºq…£cç¡ßùQ|3= †“›þ$¹é…¸¹#ßQÛ£cÞá¾;8ôÜ7jXFäwY0»lbG¼QBÚ)hia»Lƒñ0脞ïøq‡æV›¯díÜ`—Í9Îñ06V3‡`޶¹/eP*?8Ø[8Ø/¨à ˆMÀ‚ôž„ðÐ!Ó©ÀE`$;%Æ´dÙQ€®Ð(T5 !2u.Ô5’÷ç€x2`*!2 È$5b4ˆ!‹\ ‰XâIÀ2ñ+\ ÓÏšðÖÅ{$ðkÂno]ï úx%û—ïzì›Jnj¥¤zÏâŠdMa¸ fuÂáQÐe¤Û©´8N0 Ça ÷C×srÃ@9öûG €þ0Íí¹‹`}ƒfÃYž„\—ÅÊcx[ðñ{Œá„aLp,Óh‰¤`YY¶ùX{|œqì;£~˜ÄɈ™vþà¶æ$$é‘ïoâ ^éúI‚ÊgÝ~ìÛ‹†6}:ˆÉlCv.†8Þ•Œ8k’•˃*–!¶xHq‰Èѵ bw{»£ ³³ÓJÒ-+„Ì›3ÝÏø‰‡aÿÜõèçÐ+4Þõüè9¬dñ)S¤§[ÈŽ~»2<ȱ£öš±æÒ°†•ïÿ(ðûžÓ§™ŸÏÎDNEs[À˜'1yÇÙ=x^œÅ´ e{uZäã½F#7Å=êÈŸ´¥NUJWPòÊ| †ž?L¸)'ÌÓ~0ô/Ž‘j€•ªL„²lÊ ù´Mú¨b'Ø8eñ݈^†¶Ö•õ®ÔÝ—ÚzË4N´g¯ãÜìvкÉ8òcœþÁƒÍøÁƒÌ 3}Îýìóæì±ÙÌKÙñ+².×­ôø3hVöx²Šcj}3ØntÌç¼èã4Òã¨M¼šÊÿý1bèÍÏLŸðàµþ?ϳfÎãëݘƒmŸ9$ªlöK-¤Ò/ú'È*l®ò¢ Ÿ¬Ô¹Q™üÀ Þ=ø¶x· N,H¹’íèØ¼/æŒ79¼ÔE^1à®§^ɦ£²nRÑOg×͆³›CFç³£JÜSmmV i¶O€ÆÌ™R|íÚf|íZk§µÕÔB@«Ù/@êð*\ƒQ¦ì™Ž‘¹ƒ¤nJNr<òY yä^^r#u¨`©+Z Õå i¢ËTZ“«Ö­—V•¡)çYÿ+ÍzK{\Ñ/ÁÅú©f;^J1¡2ù3x÷à»ÌzæûI‰ùulÞg~Ç5ë‹3¬·Ä°•XÈæ†L)(ûùìÚé+ÔgØo1ûó£ û-Ãþg²œÕ¨ª?‹û6Ø·Uy#ËÜ·_Áã¯^„P§†Wá †÷­ßÏíVÆí§ì¬q>6ŠÖ55ÛºÕâÖëB¹Ûíœg `;~œBÎÛ&ª‡nì&IdCÃØ7…v®ö¡zwöÚX")¬2GøeÌcUC…Ð:‹ùG–‚UÖ•7 išphuÊ(‡j{¸£Â:Õ‡j¢"?Kbò™`üˆ£,N*â¤*¦eP™ÐM-jZD3eÄL˜¹¢MkÀýèÇÐ.T&‡xjEôªº7þ^¡ñ@wMDÿ Ï W7½¿ÓªhP+”c »¤5´Ø½FÛ|ürÓ›Có´‚ÁGލ¨ã„·-Aˆr*m´Ï†ˆ>Í­Óª¥•-Ü7ÓFÒzßJšˆ/éÙå–݃uqRGbZG¼¹A«ý% h O'sˆ~)þ¤êtN¬¢2‡Ê¥´™âÐÕK' ×Ô㎈Q'M½iÃpl©5{3ÄÇ‹óx±·¨ÃV:øî)«Í•*È]³(˜Õt!¢Q«:ê´™1P÷Eó+yoªvð4m²z{kÀÑ£ÞÒÿ>çýÈMü–ÛRÑY ‚MQèõ–;NBm·À¸‡}¿õä¡ù­QÇU¯§Ó¸CfȆÉv=íç@)m*ûÇ&ÌA Ä¡Ö_mÆÛ1Ä™^ÙŒI7.ª×f¶Â± ØÑaä'Š8MÅÞúëìa´Z$onnz1͸Iúªc<*üÆÆç•Wu°$”uïqjìËòqA¶*Ù$S…ŒY mßâE'ç­\bøÞwºÄ®É(zãÆ‘* ¦×Öfü Ql3v¬)¤f…ˆ-ÙðümØfNJtÜ~œb¯!ˆƒaœ¸ÃŽÏ}#Ú’%Ç<õŒüN’,ó8š1ö¸äŠ$a¤ÜcQ·)º£¹}¹s\4p'ü·Oq ç<‚ɘ ½0nÍ?mÛx–QäÞˆæ?7‡ á+>cý82Q†‰ô¯}Û•V¦E[¼üC/â¿GƒäÜMÁ¢±–JªØ\ÞÇrŸÇ¢e˜ËU¹l‘‘¤ß2™ÍFaM6ÈT,ÈšuźLÿa@kr‘ŒiY~Tn‘y]”ër“F¯È¨¼¨ŒJQä]$òfJø?:R„ß+‹^Á¼¥µR‘mŽd›ÃNÔSïÅÂÖY¹7†ºòT7 "Ó¢3âÂý¶ÿxÔ¶ägQÖwÂ!Åçϰ,ó9ý-,.f¾Í&ý}Ñí<Ñ9pÙƒyM8F8åxB‘þÄäGÉPd^$t²æ:¥)»ŒÓ¶}¿õf?MV)ö}—ª;;LñRž“sLǵ!ÚI3;“ïà ö(3R³Ô SïDaßW4Çzfø¹çÙ@¹ï-­ýIÁe™*è”È;âltx;GL™EŠºÛ„v:übowφdßbCÌ'ª®‰©Tü FÅgÁÖ¹0e–ÞPü}a¼H&LJ–™ ù'"=1V¡01¢NôyDŽô‡OS&Ö” ³Ó̃˜Œ¹‡CŸÝƒ®x7FÓ`Ì2ïâ-enù®PyZqK¦.É]î¬ñðzÖŸ÷ZîŠ{ ô9æMI¨\Ú„-9_ w¸…ýÖžäŽû‰òÀM²Ýq@F ãáhåú>ÇUàßõÛMv'x𺒀7ñX6b$þ f¥t&Ïx“LiåÀ–“–&G‡ çù_:ÕE.×7ù[,ô£NÐX–Eë*…Z *7äUë%@¤b`ò²<+=/ÊgäV’´?Q1ØL½kzî(‰R¶B šœÉzeï•€5Üfþ5gDØtu’d‘›J¹&ÛÉ;Y.çuÀ¬E¯°MU¹ÊQJ‘ãû÷9QSC™¡2Yòñû‚~îa¾Y¢(£Ëút÷`Áa‘|óu8ÿÿÅ~ncZU(8‚ävÊaeÚ‡[Û·9GØ ‡}xÆ}rŸ'ÆÁåŠêˆ×TÓ»÷·î»7¾zëÆ'·¯¾òî߉òl@¬Æ)Pw3>p¶ÆvÚŸ4 $Þ³íT 5u_ÀèPi`ç+"Â¥ã°Où é›t2âß±?mpÞÂñHáî‰ÝÚ‹°ƒ©¸¸ÌB&QÕþ0Õ}+ôU.ÉfaA®X‹Ô¶D†¢,¯Êר ySñÁ0ê™d zbvÑ×µ|Tær‘Ë”µ ·t`¬|ãòð¦ð2ÃÎo†•s)"dÙSJe1 {ÊEbõõ™‰;õý8æ›v¾DoÛpqÖ95„2©¦À¤jÊT±ž'ùÆL!†SFwÅÌ5Sƒ£/Øž™¥ÿk­2OW¬5VWpi/‘gU´TøÆ—(‡½§/pnHs3-h­E–구ÎQ±¾½È5[g†ÎÔ‹)—Ó¦’2yÚb÷`CÛA5^™1¾(zÂEh.Ÿ™¶¢ïˆsMU`c¶©væ­z~å¹3+ÏåWþ ­ÌI‘)Cù”­5´]-@+}kUv±‘Ÿߨ©ý‚¨VÖÈÅvƒØYKÀIR¥½0¡6Lñ&…“ÁáUÀøOýäaèÅÚßg%õ¬™ãlf;Æ­Âu¨=F•õÏ‹x8xlâñaŠTŸ§ä¾zú„ê/ýFŧ)¶ºÒí˜Ø-uŽ@(;¨<¤Šˆó¨;„SË’Y2Ú¾*Ì÷…”/ìY‚M¹€6Ä#|Þ´Åê¿éÇ M¹§ö2ÁãXèLÚä…0û«4ë¿ “°’|{«i>õšùL¹x9ÏÅŒ‘…<#!ïø­FþQÆÈâïg¤ÇÙtŒ° 2wÃ}ÕHGÄtÅ®bÊÛ’!0§n2O/”ËÿñAâò×hÖÏq¹‘rùK‡½ÿ›¤¦_fáæH…-Ž07pZdÓô•ºB)ð÷ZÙ'Z9^ÞLZÿ`ëï0}™ÙXû0ò„fýmÆÈ” éÍÕ¯ˆ¸ª"z R)#FD/ü¸ûVíÓ~¢§Û‹h$ï¢Ç—KÑ=È£ê"w<»G—œeø&"o8Ú%H'¢AN:0ß í) _þ‡èƸ™ç=ÔNa®©xG*ÓFñ“MEƒF9ꀆÊIð§kì)3œªNpFú°çw%û)rÔì#1ãükq®3U(ö§„Î2±Z´Êeµ¬Š1s'ì÷UBx[§óYYÙÚ¯ãñ')ºlŽéžÞ³9KÇw0ìxǶo(hÿIJ¨ûëB':ÓÍñç™ÊRóˆà€  ƒáQh¿•*¦æ× !›¾yQ’¨¾5VìƒSHú\±îòе"V­°þ/¥Òzù¿PK*xbEÐ÷dûy%astropy_helpers/sphinx/ext/doctest.pyTMk1¼ï¯x$Û`‹’”½4I¡z¨sKƒ‘wµ^ÕZIÕGœý÷iåÚÅ`[š7oÞŒ´çt'k¡½h(êF8ât¹ª^Зõ ù0(AjÄЊ¼t÷íúöûú–9ª³³³ê¾“žðáØ dZ ¬‘NÔA> ˆ+eñÏ› Ô‹ÀxÅ·&jL„ ÓÀ„NPêA­TàðãJH½£Öñ^ŒÛÓ^›ƒ¯¬;ËQì÷Ò²j’ö;ʵ­pBƒÒ™>Ó•–$ž&”F£7­m'õ3Éà…j—…š×!b„%Y ´µcD_ lóÁ;,Ó”£/R¥¯`_p¹ºçšïàvV`–»sÝLM=i`S€ØE­ARåÉXö[öÖÀ<'ªL‚bÊ3m(+» £ãf«L½>w` ÌjÓ[dRÀ7ǨªªBøÞÓÍèË6N›óé×âª"<÷›ÚèýL÷.¢>­7¢MºçɾMÏ9]w¢Þ“Ìö8‘ÏŒè‰+Ùw»Øƒi™ÝHù!F×Ñ¥ÄàœÑj8ᚤ¾¼˜%mŽ!¼’ ³CúÞXw8slª‡'XÏCÝÍ Ó’’^Vzøðx"==§»÷øâêqÂÖˆû³ŸzÆ~9ÚpD.&˜!:M¯‚š§âe¦X<¾ ã‡À1vŸò—”Šês:ž}/qî–´Å;´ÍǰX¯qïqùp÷Ò±ßâ`ÚÂ`lÀàjÊÆçãòfZƸŸ>Bn ï€hçÜÚ"¿ošÍô:˜ÏÊ¥[¹2¬oÄÅ¿8ÒAy©íÄÿÔ®`Ç»õPKu@,F T¸À]@&astropy_helpers/sphinx/ext/doctest.pycµT_ÛDÛIîj®¥´U¡ˆ•xÉÃCi©¨T!ñtÎ ‰¼X{ö&Þ‹½ëîŽÉTžŽoÌ(3k'-/¼“íÌÎÎßßlòÏýôùëß/J¿„Ö´ü–H°"ACÁ* ûšÚV DÌO ™@;…Õ”ø)¨)¬I:ƒ¿nþXÍ :5 Òãƒôª{̬ŽÙúrž²Ó6H/jíý¥ð …] ¬R¢ÒN•¨ÿTž…l»=qVhã•CÑ*”•D™ÊKÛ£¨l‰Ê#3¤ƒµ™ó(Öº!~°‚6±v²U;ë¶bkìΧ»Z—µ®Óe¿Õ]–B{ÛkäˆÖkå”!“ζÁÜèR¨kTÆkkÈ·Xvµ6×B£WÍút4-Kì)…º¢¡ØIk“ ñ«uBzt¶»9å,‡|Uû´$§.Ün¥‘U t7Yð.Mupê…±Heb2ìzcÈH2ËRýž¾ó9•ð>‘†ò"ÃÅecËí ¾Gä—}íñ sC’KªÉáà ¾ó÷òs" 4*f¬˜¸ÝÈ—ÁpÉ$¦5¡õ3ß8gwWfïh34žÝÆàN÷|_Ñ®ˆÁ#ï*n#ø+œÀ»ˆÿtgª¦dò™î´yñ­æ5;õì= çȼSA«•XÖxÄáYC-Dä讬69_³jq+æ´•š‡3&þ7"—½nªÅe¥=f­,­¿>{þMöÝÙõ÷¯ŠW/j³YŒý-jÕtÊù…ÝZl#„²îy©a\s¦óYô8z a³¤( á¶(0 Lk«¾a–#»p½ÂOhSK_Œéäé>Ò;Š9ç }ÆV9„Y4‹ñ‹ÉMŽSþ`óà~}â=Z4?Js.HÎ)å'\GDl‡4fYé6}K)ú;MïS2ö%[åéQ7>34J>ÌYèìà 㳬´m'1ö¹ Y=¾c0‡{3 Õ »Ð‰YtÂ)%OOžÎþPK1`!E4‚-R},astropy_helpers/sphinx/ext/edit_on_github.py­XÛ’Û¸}çW tMHÍRœTí›SzI<ÙL•k˱'›×‘Ș$[ŸÓx]<Þ„s »O7ºOƒ|ÃÞW¹hµ(XßB1Î~^ç5ïµ`ùôŽis¬«Ý¶fZöþá¯÷¿~ºO•6A†ÁcYi&¾,©dËþEhV&¸>2#™(ð¥y߈ÖpCkð{¨LÙïÒ x0Œ…†‘ö‹f\k™WÜÐW¬€’¼$amTÕ˜)¹aIjM)‚\*%t'Û‚&Ÿ+ñ•iÙ«\°Ž™ùÅ™aìoJ6$£DB *–ó6èz]Ú‘ð@C¶ë‘mâ`Óøh=a¼-˜îw f8ëúºfJü§Ú8?J®­Ä^ÖµüJrÙî«C¯¼Û}hþN ˜†U­•è”ü·ÈM¤ƒí–dÒî¸Ý®ÞÁ-Ûn I&ÛÌ…,ók·Û€áz„tË8»·šÜ¢Aa2ØKÕØõ!9Nw~ ݇éYK;ÅÛ¼¼`ÈMŒ?Ð8R¿q©±ÿØÅg¡(-«ÃÎëRöuAà„–~Àò½Pn‡¥Ûd/G;'‘–V¼Ï£>Ê0¹GÒù„Ó6Cá&M¸ø† ×F¨°« áGÆk-'ãØ²ò¼ó.‘2%å<ÔµÌÝ^RvúØú”3JŒÁ!)oE?M ¡Žç_˜ôNìy_MPúÚ]ØäÞÿ Á²ÀKX&TCŠ…ÖGÖH«Ææ¬Vß9=!«öó4¦â¢$ТãHýŸÃQ)¬êxÑaWlY#´F¬fžw¥BJAƒîj~Dnyïs Lç‚ùçÒ¨?ÛE#=]<ñÇÿáã§GKA—ØRXê:–RÔÝk°pй‘²6UGZ ˜µeÑ-7ÛqÁ‡ûˆú<ó ’-(Ý Ï—Ç—ªË”8ˆoÒ¿JṌ›Ò4£&ÁözHÃM^ íü†\_s…®Ñ¿'~hžKÑ ­Èz°.•oQˆâŒOÛm˜¥·áv›ÚæT5TD³ºCÚ _¥î”îôQÁžº•Š©j0™›ie!†9Ý¡æ¾ 3á'ƒBìýh&wTq# âËIJ&¸ÜFèóÁÉSˆÜj8ùŒøíŽìÖËÝÚns;Ý*azÕ¢úR§b`®DãNx”y\{ø‰—ÐìWÙŠtaߨ£DW–yàÙ€y5Îa€m(6)îúZèÏ~ÉÓ¸` †ÇbaT¾ín´6E†V&ŽÒh5YD¬dTŒo‰•›Ì{Ÿ1c‡Ä·\tæíËiòÏote½ª³J#æ]ç ú…,*éÞÞÝùÓG.›»}G¼IŸ»añ¨Ò©ëßéùœ¼b©ë’+™E¶P7¼ tÉ0âa¾a¿—˃Ñh#ÐË‹€m¿ Žm6,úxÿ>|¼ÍBÆ+Æo¼îŽRRÅ‹ =gœQ¸„ôÌUÅwTØ=JœºíR¤ž«bbHª  ÛG¦îŠ ¸ìÍl•ÃÞºŒYîr0ô¸eó¸ªúduà÷àï¨68¶8û­I˜Î'–Kƒ!Ë‘˜Dä¤ßÉÔ(Ngàòäâ/Ÿ%>vÏ‹¥ð#Ž ÙðªVìرî-KØa·ã ”¦š„ìjQrº: `¼¥ªÊ1F¥Á†i)b/‘°ÖŒ†9 F¼(׳xèòœ@¨œF癣Œhu…y¥=ÎÚç, ã§6F ÏAúÔÒ4—úˆ®³Oޱ;{x}4«ukÁíó N tú@£Ý M‘"éÊÌ. ^È¿dÞùÕá¡íT Ög°-¼‹Þ¼¿)ˆs¢—Žºu§:@žu6eÜÌ —oÖ4Ëh>ËNÄíñÆo4ý€’nô’÷çH&™sU²°ž*£ê-aÑ]´J<êÓRªÙêÜLÅFc16èKM]‘úiãŽ!©}RT¼gcÚT¦›Ë¼7?N&—”ôªÚP¤.Cúü§§ UÕÒž‡Qlðçñó¯±ùc»ÓÝŸqG¦Ü !8ÈÉ>âHŸÐö‘¼FZ ½ù‘ÿkÙ®ÿd›ÞäP¹¦ºžN¨þúN(ÝÓ±²}œF\IÑ )Œÿæ½lôHïx¾ÐvkûÀ`£@罉ð%SS{€Ž¯tÊñ@>¡YÑ+„AÏð,ù½¦85[t¤e±YLÃp*ÚBÓÃhL°¬×QÄì‹/D‰Ä»¦Ïx裖ß]éÙºä]_Õ…P©V9#§]»z( kþ4wÕýùÂIÜo¢Ë¤iuô]dû§™Ÿ£kß“^زª–åó:Ãɧ¾›xI<“9 Ù3÷âþ­S2;)&ìQõ¾½J‰;á’÷ºåÇ5Ìø•ÔÔÕîÇu @ pÿ»,i%:O+öŠ^¾Eøq{‹Ý¿fÊ>šÛw¬ï4Üäœø¯š|Õkß±Ï#C]µŽÇ÷Q÷¨Š[:9EžÖô%‹'ªÕéjbÓ5¡]û*„È ƒ¯‚ÿPKu@,FÓüE‡, -astropy_helpers/sphinx/ext/edit_on_github.pyc½XmoY¾3vìØu^»m7mÁK‹)I\ÐÒ®v+Dµí®«Ð„M¨ì±gl3ž™Î½“Æ’ó….BûøÀà3ŸABBâ—ðøËsÎqì&A+AI<×÷õÜsÏ=çyθð¯¥ê×÷»"û3ñü ü= WˆC”†pMâÐÈë¦84ózAòzQ¹^Á‚•ÄaIÔ.Š ,F‹âpíñ%W„[âJU¸e®\î"Wj­pe‰¤î5ª¤ÐKBT÷¾´¼å…ÒBkäyÒò•å9rl©Èò\4ܨ›Ž¼P9ŠæàÓ÷Õ ílW«;Êr\WZIË‘2êúŽò\ëf@Hw@‹¥Jü°o©£¬~DbÕÀ«v£$ñd…. ûÞ+KFiÒõ¬Øé{´Í§zËú$‰F´&ñ6éËJ¥—X]'¬Æ©pOý)­[T©(ÜÔjSÿt÷MË ]K¦F+NƒÀJ¼—©'•>ÇÀ‘¼¢AôŠTêFaÏï§Iv옾¤Õ€úÏ’ž²üWÄI4ôºêû²ÚnÓšíxÜnÿàÃjõžÕn“&­(li“µ²¹ívÕÂß>V‡Î‡í±$=)¸™oЋ’ϯÓÁiA3›Bõúö…;u'ì.ÙHæ ïP?\v pÿ¸Åc/!·Ød<.Q¸d‡´µ”ÓÇôž—èŽô%gëèæ¢Ärx¹ëO呇E=8]æpîÇǤmßúÈ‘ÊKꤛb#gl9ŒÎ6Ç• .>¼v¤VE³¦¢®¾KòÎ̶™Ë©Ä›‡Veu^úl¬X;Ý#8&zâõœ4P’T­~ç’€ïý4˜@½àM=0§¾I@6$[‘i3˪ˆÅ°Ïª|vSË©[~oÖ)¸È ¤;pý\?­‡Ÿ`F”Œ/=°¶ÖÈ“¶š9y%qTÉ?ó %1\¢~„eZL Äy•’òSlÉ•£ŠHã ¡VÅp:±à7˜V§Kâ ,¼|lµ¤ð¡–.(h‹˜­q›lµBÅjŽÇ_8Aê=M ØÍóØ0“¡ÚWi‰u~ι|ŠÏ£‡òhÏf\¡£2À`†Æ~|“ ¾ôC©BžZÎæµ¤ß‰vð¨MCöbŽÿXž-kyZOœRÑ]3×ÓjÑå€qÊl[ä2]ÍQŒm¶rE[ïn¤Æ­ó§œÍøü¶cõç‹ÛÜ5¸ìõ\O‡`Z‘?Ì“—þÔšžó†ËšÄ(wÐiù÷’]Ðk“¾ö»TÔrð'Ç-Ò|mˆRVk×øxNКåMÊ¢Ø>d’ú€ýÌHë—‚U²ùÍu­P3jf­°a\iV@ëø^ÁCeÍ,¡‡Z5ÌÝÀS4‰\iåwPb-èvÕ¸…9+F—¬P™¥Ú¿¡˜˜9yü…â*#\“8¬È«a ë* Í `"ƒCfˆ…Œ!jºÆCÌ ù†Ì(@1ÂxÆ2’TÃ+Œà œZÎIå|“%¦ˆ2ɺð¿s<šŽR»$…ü›Ì^£Ìù@…¯‰?a‡ýmòÜ´‹© Îì‘KϾ€4h £[¢]Ž“iÆ µq.LSsuãBDÐ^NÎå…®¤÷HIûqx'´ïæìo^¢’tñǘcB^Y™†Õbv~öcö~o„Vºƒ11 4³äÓç¢oü ×2iSC¼ÝXË0_?Sôw´Û;´'œxì·áêߣ`0×ÍiÖ8}wø«È“ýûxåuAYW¼o¾k¼h¾«L´?ßż?ßÅŒ?ßµD4?ßµÂÌ~Öe»áàöy{(€ÚìÇt«»LA6Ú^ËÝWÿšb×E–Š~ÇþyÞÀ½ÙïÑùiá›ïØì$’‘ß3ùÃgs?ÐÙ?¦wP|£WR{‡¦Ó¾xד3еEÐ%ó{Ü¢¹[Ù=êדUMX-l´Ž‰`5=$éÔ?C—M·iAþfäÞý–Ý_¯ð’ÿ*·Ùå®fÿàçÌc®ÊÌ 5-û‡¤çgT|JEq&ÀR…W@M¦À¬³¿¦nåé‰ís‡}{'&íé\à§÷iÊKLD7«æj¡²Z)UÞ¯¬ýPKYHáDq¾oŽy &astropy_helpers/sphinx/ext/numpydoc.py­ÛrÛ¸õ_‘ë!iKtÒö¥jÕLkg§;ÓMvâ´}.DB6$À -í6ÿÞsIÙÞÉ„3ºç~?šL&ÁÂ?¨Ëê˜Ë¬; î«=† Í¥ fO ÙS‘L€ÕFq±Ó„ã#ïѨÊÉVª’š„,_¯ƒà{CyQ̃`Fn¥x`Ê©¢%3LiÂL–Í2l41’l9+rRpmtr‚rÏù[¡e‹ ÔžRr,‘Šö¾à„ùoÍË'qàTMÐæ™¢K«Fã3)Ü¥ró3È3%ŽäÌî­‡¶—®6¼@«Wžý¸€ÌiqÔI£[¹|µ&]?8 4?ÔdA ZnrJôœè€š=qY žÉœE`ÚÐO™Î@ƒ” r¶%%»‚¥]†D´ª¦äÒgJÄü”€ZðVYCO!ÎÓSËoü´!œÊíV3³écH$¼Ë¶;.癉jÍÒªF/€XClù.i²:moG\ô^>¦YAµNK†9sžÀlD©w›™ÅØYbg!‡ôb§"¸ G –2¯ æŸ ‚áPA€7ko쯲{´ÁÁ px3 ?­VújyqµXÿúÇé—ÕJ,éì—W³?‘Ùúu7ú*ŒŸòKçŸäûÿÁÛ}ÜZ.çk`ÞÈ‘èzãÙIVÑd%&qò³ä"²qœèªà&ênÍ.ñ á~‚D6 \„§=%Î ˆ™NÒ“£Ïâ9‚o~_²°É’ð‰YàüŒ®ÃÏŠ˹IÂgýº¦„±j‡iŠY•¦al/W§DÒÜÏOõ’pÁ…Dú =4¶­‹ÂZ8™/ur©'1¹$‘cÒP˜ö˜ÆÏYë ñnßväzA–ƒ ¡ íMYHQçóî8Œ×O"ãÙ¥QôöixçâL˜GÏ;â’<4k¸v¼€”¨ š±®t׎5&m§l¢Ð´á%$Ék ‘Qôë(mÏã,($j³†ÕfÞS+4|$Xo«¨³ZéÒælß$?ØkµZF>çÓd¶ŽW«5ILm>÷¤ì»ìd¤ó0‘Ge²S²®¢×M_à]À(L »nÄ7í˜6¤™3p~yÆ HÁGÅ BW€;4E¢¡­EŸÙqá[ÑaNfÑÁÇÚAw£áø´µÎEL©}U諆À ÁÎQ:±ÈФ«U~ý;´ ŠÇðøÀ*¬6q>\æ.m†­ KÏ5ð7‘:ÉšægÏyò—º¥?uOlž#®0ñµ#üšøö*./õ:µ £^êýgˆnEý pÖ*_/Ã)/E?ÆNb@lua÷&›vv~i°@t¬ÂGƹ“óPÔ£ßÏŸnx€Œ·Õ!—8wCŒÚŸRhKPrÒŸš8|ywøq|ã Z­ C`¶í ™G0¯ Ü…ÀV€“É:¹¥EA7CQFbRµCíR®ãˆ–ƒÌñÜó:å1ÄÄêŒí«µ°®Æçh¨^WDà`Þ7ײàLWNÛQfòiù)Z_MÚ¿ ÄCkÙ hš”‹+;¨Ÿ6˜úsMºèÿö¶À"†4ÏS׬R0[ͱ£.`]’0ýv;ðGN6G ¤!p7ÌÀ‚F6”DÖÆo«-2¹›ÞÑhK¾ïŸ'´ÖFÄ D€ŒÒ³v?€è­ ñËømvøíQ‡>´JŽ;9x'±÷}kôoÃmНÀï@䣪™{ÿM4ή2¾àØ­ßY»k.K ©ÙcâÎ"ûÆG³—âΞÄOBÝ6ÁÅì›>VH³‘Ðßš™Û£Á ¸CÃa`4(i¶·ã‚[¥ÿÍÙã?¹6½•ÛË“d ”·ÇY ÊZ´<µoX?’¼žîôïTÛ¢Ùå{Þ¬óicøRAÖýúÅW9("M…Ž4+¶SrEáuõùñ¤ èºb*3ƒr(q[㣷C€äQѪ“ JGq'Å“0–E0k[¦9V~´ÕÆ&ç5N8¸Ø Ƭ>†^"]%ž%Mg ´’Å›FùqÖ–½r‚"='Uø‚?»ÎÜü¥ÎO¾wƒOhEÂK÷åä†2V5¨£Û’xù³TŸÁ$áÙó0Ø–ø¦6 ºâ‹ëa¿fÇ95ðí3¶½}¬³ìÛÖÕs‚»kš)ù.†ËY«?PKÑeuk‡à™Œ‰6 q÷³‹F§»3ØSÐ' ‚,T-†ù‡¸Ûà·•ÿ„ýH˜\Åt AÇÛ{^ïÿIAB0¾Yg6§Þ6ªÂOQrµÒ×ñø|G+øˆß„Ó™³ ‹¢Y<·›ïP&“z,§1âÖ'áþ:XœT&hÈ@ûBÿòÃ%v.ónk7,¸w·ƒŽK™gl›æãÖÕiï:=Ù 2XÏí¤×‡¤ €fç±@í}ðPKu@,F_½ø% ô'astropy_helpers/sphinx/ext/numpydoc.pycµÙrDZwqð@A‡µ’£’MPJÉ‘åK¢â8±)gi[1Hj½Ü€ .v¡‡tªB'vUŽªT%¯yÉCŽ—T¥*UyÉs’ª<§ÊÉOäÒݳ @GÞB’Ìôôt÷ôô5Ãܦʧ7þ¸êAú“ÃÏë løMl ðM èšÐ4¡›ƒfºyhæÁ ¹„h í¡YÌúcÐËúãÐÏú%h–²~šå¬?Í %èL‚Ÿ‡m€ä ¦À/À‘?0 Biø„ÓЭ€[î 4g´ãÎBwšs`ˆ"tæ‰jÍ/Áv’‚_†Oq?' BÖi1Ú¸t>5 yü)†WAUÀŸfàËVðtkЬi^3ž†îhžÑãYÏB÷4ÏáxÄ3ÐB蕞ÛQ§á`’/ŒƒI蜢~§˜2´ªŒ‡_Ðß}šké-nWY}²¿É“ó8É.{a ì\¦^¹/Õ$~cåCu€D­XO¨Ä.=±ÌèÊ ƒh›¹o¹ÒUˆ7CJš%ä‚^ô¸‡¥™·Åæçöz"òØNâ~O LEñ BJ$®Ìeê‰è…®'ìtäs™ÀH‰ïbȲQžÁ¢‚×Å=®ð˜Š*¤šaji‘æÄ­–Š—x­6;‚ ~¢éà>Y;6™4ûưÂc–D•QºÜÜ&Ì+ '9¶âc–•µQØai|‰ø¼MÜrsƤQÉMšcÞ¸i>‡mÅœ4ªæ£dTŒº9g\2ŠÆ\јBÌg°.7m ǧŒ æic/š\j YQð7í§NlèªÉË€–Hùö¤¼AEj«Êmñ·‹„‡¹yÍ¡x@”ULè}˜­ÎÓP~Dw·ÕT`Ô Ò¦N9Topj¬%¥ãÁ@ey:Œ—bPþâÌ9˜Àì°ÊѹÄÑY‡Á B³vä<[_ 7 >ÆëÇÞËx–ME‡hÇq“¶ì Ï $.ÚA<ßa£s¸®Õ¡s5«ú9<>X{P߸Âåâ¦Îõáó#zÚâÉo9s%>xv ¬œ±k¿‘Y$VíÝ‚<¡&8„az³á-ÝqÃÐÝ …MæjS"²)DÙg‰7!ØKÔ\¥æ5_¡æ«ƒ¨´™+z„EöKp|µ(;gjÓƒëÒ:±9EÌДgÐ4óæÈÈ›'2±Gê¤O>3Ï_ã7&3ÖŠ®.cÍÔ { T¢C¢ê(Lð€ÍnœÍŽ6íú¾£Ó²ƒ†Ô’nÌn_Ũ˜Å^c´‘‹C7Úì@a6{R›MÈuŠëlK:Üë|Eh'öë]¡æ^–¹Vb jdtßÀk®Î(ï%}ÁÖF¢úq×ÅÐL!ˆ/áïî«­8ZÖÐÉ zG´¹“ñ%ïÑ{Ÿsl¶ÄéG¨~o›:Uâ€q/Ÿ+š3hFóú77e节Žâƒ@쾌‡·°l  }=²QÊCïµâ‘hÐmWŠÁk-ºMæhaG4 Àš«i’ÑÛGKêäÁÖWB/»6Òç-}N[²b³¥«I7ž~Ú rT´kkÒÅR>‹²Ú±É{t¤ [ØMÜžÓMEvüìV-õ#ça¶8…¹\Zlï[•EB}Nd󬬚1ØýÀßÄÎÞë©+ë»çèËÃe¾<``?¦é&sý©ýÕËœYÄ»[Í8…ß3X ŸÅžÎ9CGúdà>\u}Ÿšão©ýŽÈšìMšmî¶Œó4yþÏ¢ kÁoaPLœŸ«“÷Úw ½"9N«Oµ±ãØ„`ó³:'5±´é\Ñ›™ihVö]~‹€L({q8MØýH]q7Iâ„+y*Ò=,ð£×³B8Î ˆ6ú*éÿ6=WÙls,.ÝÈFÊñïBzÕ$oÀ²Á‚šBBÛð̦.Êeó›ÙÂÇfz\½ÚkDœuuHÉ„##kñX°þ‰~[|•ìU¾À¦sÖ¼jLÒ/ZuŬ¢uÏc¿”¯\/U&«T¯Ï˜ÕÉÚT­ü_PKYHáD¤†<žÞ,astropy_helpers/sphinx/ext/phantom_import.py½X]Û6}ׯà:$§¥Á¾yá>´Ù lÓ: 8®BIô˜S‰DjƳEÿûžKRßšd[5Œ‡¼÷ð~žKÎf³ “OP_¸2U™È²®3ß ~ª/R]™¸¡´¬3+ù/‚å²™‘B³sS•ìÓ'mEcˆÆ¼5U^eŸ>1®r¦e) Þ=ˆ&”V¤Ê´i¤º×¬¨x.r‡ÅûÏÿfgYˆ8î.R A=aV]»}Ü“HÙ¹jJnØñ݉޲Fp39ËÛ²|fe•·Ð2Èd•2\’AеÈäYŠÁ®˜ÑñA†óRA6çdû½0V#k›F(3öÃ90pÃU&‚'i.Uk˜"‡$Á4"me‘[(ˆ·%°p€3žÇ±uâbL½û6«rßWÕ=ö²ª|[¿­ý!A°AbíÉIrnMÛˆ$a.£HÔ£¤ÀíOuU´Fø\ïX “ Y© ðø±cúYïž²F„›3ϵÀB…ð‚z#‚ g¦…iëˆ×õv0|ð *¡(´ŠæF* ßBR—FòBþWl{ižç 4Îò>yäE+¢pZ– åº*%vì®i¡kÀFçŸ;tF2^Á²ròÌ"ÈR‰V:®¹¹ÄRÓ.V·‹>6LÑæ¨ÚÒFüÄn¢1eÓåÌ¥³ƒ ;¶‰ãx³íQüé1NN ‚W7ê'xž£š'»º@† »öÉ…ÎYÛìÿÙFØô¬ú|- ›bª]úù/¥ª³3ñËí3ÚEõÍZQAÆÞ‡K9u"öù˜)å½40«k[ªp}íûóýÝûØ*Ñ©Áù$‹¢ãÏUú,ÿt‘Ù…Ý·¼cBØ>WEQ=!æ{gÈ {?°o@UC”ûÝï ®5 ø"iýTpJ…¾Èz¢Â"”jÝM\#mê¶Ì÷¾{!O}I>¿ùðãÝ›AY< Å^B°q7‚ç;çE§å½âÄ$ÍZ¨ÜEq"Ö3ßÔ-n°˜¶–v11è–»Ÿ­À$¾>“·ˆn)Œh´ƒJ‹~튈í è»ìTXužÌË´<·2“Šó|W+¦A"9 †¾8 œ=IÆ3¸|`¿þæ–­äÁ ‚6=*i+ÐT•€ÝǨ _£­Ó}Å~²kD©™®ìò7ì[T5Ë(€ˆ¸W`æ `‡5_-ÝœDøÊ^ùßßc=ÈÆ1òîÂÈ‹"Q˜$æ }ŒTìÒu ežvLmi„2E…B¶Ÿ¶C訫ø”Pêˆh`jqøžZŒˆÓÊàœãµ?¡çðdá¯OúñYªfaV@>ÜžÊi2*իܼ›ë¤ >ÓTæ%bÓ9ÑÇu¨Å=&ŒCø’¾´åyª£êâ° –ã®m‡íXƒÊ¢®xz‚³wÁêîŽDTçîeD*PìÔ)Šhûàè`lX/€9ƒ}Ë7±A1`…á6Î]‹£Ð ¡Ügx a_±ÍGµ—šE8Øå½‡Ãè%^±ÌÛÍéJ¿#•Rj Ôá"h·ÈN˜Û¯¾Ä=½4Â?TREn%Öu!]°û›w§E))L'ºÆ94È2Â8žPkÂØ‡˜s±OÝýË©oç‚=ÐÑ œ ‰å‰Øè6“ZÒAŽSà²ç{Û3ÕþËöR´ÖÆI‚$â™s d¾h$éÎÅÜ–5žé‡×$4©^–ñgspIÞßé¹ûٽƅÙë&R#'x ËœbNŒ3w‹Jÿ7f\Í!z®Ž_ŸØ7ö÷¥Ÿ³v†NäD1¿yuš$žø\­ª®ÔÇïè`yîþÊ€¹mÎh ¶/¹…ÿ­–_ÓçÜE«ÈÞÓƒ¤kÆ=W땤9©/vÆ_è9QR2*§ MLÆÌ8&i?y^¶Ê³òï2ËéXËœèBN C» »[ã—A÷—ŽÛªn š:ë× ºÆìÇq˜Õ…e‹éL„§0toŸTRúkì¤fozðlÑüâôñrО>bmxc4ý1qi/n=õÈ(À» .ÅϾõé5Dl«…a³ñ:uüaþ¯óÿPKu@,F»ˆo) s-astropy_helpers/sphinx/ext/phantom_import.pyc½XÍo$Õ¯×={Æžµ×Þ/{ 4„ ³„‡$,d!(ƒ‚”˜Õx¥%F¦Ýžî™éqO÷¸ûÍ®fNF|ä )R¢ä)÷Hœ8p’Dù?rINIýêu=h‘¸,Þuû}VÕ«ú½ª_·ýïZum÷¯Û-Ê,þý鞢ì·Üð‰vø©È·(RÔ·hÇ¢¾M;6õK´S"…9›¢Ú™¡¼]¦rÑž¥Ù¢=G;sE»B;•¢]¥jÑž§yòKô+^ F5òËÒ8‡5ÛõY¶,û§"ªþdê§:èz±NúnØ$©þêlu{Ð ã#'8ÒAœ…IìèÄé{ã‡iÐÒá½ sÚiÒwöö2YÚॠo¨?iíí9^ì;YØ#/­N„d2ÌXHÒÊtÆÌ‰Ï|#Ë‹·~ù §FA£Z½Ó ³3`avv‰²UÝÀ¹}ÌâîûN;IûžvÞ~vê«­4ð4›é9þ°ß?vú‰?ä]ºËkZI¬½±€l´ÂvÈVœÚÕp ¾Úb}ûlöa{'в£5LÓ ÖgÏapj ×^Ü ª÷CÝM†Ú‰ƒÀç•“ûÃ0òE/öY+0òÉ 9DWëÁ­VâN’tx®•ô7ƒ\Iµ†u›z ï…p–^䎷Ÿ%ÑPyˆõ9°±Úmcaoµ„ßÿ¾ $?ÅQO¬X¤Ð·k†¸.щÍP&ÆÔne+Ç ÒaòAô 4MáËEÀê3°ˆd÷ÇŒ"]å6ö„^¾è%Xíû.O·ÃŽ{Ï‹††i[IlwÒaP‡ÁʽÁ .À#{³0dcß3Ýè{­$;ºñì÷ÏÝ8zá¦{óGA§³áqÄ’Á±Û ¢Af¾ ´i›ƒc ‹³@Ñ€¤–”¸Í:ë¶×&në)+)J_!mQϦ^ Ý3"7$I~Ôå|NÅ’A §^ççÛñ°/‘ÞunÃcPd°b`—aO£ÑËÎÅ¿ìÀ¦àv&™xoàé®Ì‡â!§Dh/TᣡŽíÍJ!¨?\‡7aÒ*„ω¯Ô•Âßøƒ6üýÇÒ$Õ.ç«0¶àMÆ*‡‚}:¶id#'õþ]WiTEëÀ¢ô¿˜æÆÉ¨Bãy:j“ž§´£üõh4O=Nþ5Ù|Žœ£YCÝÆ&îXtP¦ôeés:è-b yû¦¹û·ø"öÎKçÐRwaß23þ¤ò•bc{Ý:ÝW¡—â¨|[Y¶½h±ë?$œ•·mî®Ó¸F£ZaÒg Êk´Š|¦ÆçhÄZ.ã¾óQÒÆ‹¢lÊô%¨Ñ—±ŽW„–xj‰nò´žnòÝ‚m•)Ÿ¬ÂÐ+?[Ø6+¶­Ú§á˜Z>^ÊÕ[%YÎ˧;Oé_,½F½«ä¯ (<uçÉ¿@£%tÙ–¶M—L´ü‹bü¢ÖÅM¾«þ%:˜¡ô_öã*”·…ùfpâcýõœfNOIâdÇY#OéÏ8ûèÏ{gé¤ÜaÂpJÀŽ˜ºhÃMó™¡9!!›w6² ZEB®ò~E ÊéQ²ßcY¬þ~7luÎÐK99°”vEÉ}.<·Œ!7œÍSêã¥Ìˆ’¼°‘ϾyYƨ¤¡Ð æ<‘ΑuÃÁÔ§¶Ad T¡Ð»ë…˜×s¢Âë;`i8óÓ[oÞyútsp/ˆ¯“ ~×ç?cNQˆËÂNìéa*Näƒ ö§–MèÝô±<̓ûCá–,bÊ …øeÁ”óHÞfïöÍõЈžüH÷¨ crn9l@~ÇÙâ-NÒž"ÁB'=_ÖÈC(á–TëÐoá*>êê *ç¸Ñ9Ãñä­Hé´PI»’…—¤|òUù.—Ï£=P€ô:>‡²Ê÷v•‹èÝx™JLƪ”î‘R\[½ÅõC%™ý)Á%ä~áq¹+†ï°®­Ï³ìÃXaé¶Ä-¡+¸ÂóÒ -§ ÁNYd;Œ}/Š„Ñ˜˜4A„U¾Á=z-M™V`Z^#ü:š":fN-28fÔÕ@ò‘"hͤߓç¾P ê2ÿwÍ<ëv!({xtè1–ù „_:t]•ù_EÙêœªÑ Ó£5u^É ÍÅ–´€Ryh±‰Þ>c…  b&箂‹O©%<~Ãõ9@yWå]~0aÈØ”>ööäÍI÷Ë|õ¤û¡ÀŒÑÃAyßÁÈ–<›8»y¹+ÉkWÔ~Èow8îK‘×ß÷½—ß…*Âẜû]WV¸.^Q¹#q2…(Ã…zçíwê»O˛ʵìZV­^Ë&Ÿ†¦ªø Ö_õ<JöøË|¯8WhPÜD=š²ôg°çˆv5·a’øŒ b.=ìÉ‚ù«¡ë~g¸É2ᦒ}ƒ„¤oÉÁŸn^(  gÕ¯7âjÞt˜ì|Úx¨<°•ëJš$Z6ûaKŸ¦×½ˆ×Ì›5­.›Or?ðM ͶI‚÷|*2ù½„_íå Æ µ¤$6]lŠƒûye˜é§Ø‘SÐ&<Öü!å_¼øQóÉB.2‘ÈÕÃA4Ÿ§<ß±…B;Ò\èp_¾+¸n~iÜ0ã«tÏ‹BßÕ …ëx)Þ€?í§ˆsÿ¢pB¼ˆô=€“¬ni-lÝŽÑl£à§SàMׯ`q\ìs\kýBuÔöVà¡”ÅÁ R§Ê¨Ðƈ‚ø—;Öjx@Ž2_C‘MUâdm3¥K*¦¦ÕÆa@ãu:ù‹¢eÀùHFRäœ'E™2ýô~ZBaSXR®>F $B´>»‰—sÇV„UB½²;“žÆYèQ…VÜrçL‚¥”Å>Ñ9¹ÌCâ7†‚±l.ûÿ3ÊM“ËÒç‚k Îò¼ÑeW‹’¥åü¼Ði|`÷»¾HjÆSKD⬒eI]Ù7GtSâ^£óέìu͘Z€z!e .ž:G ¥¦…=WŽ*þŠ~·`BI×Êâ‚F!ÙLÄœªOò›¬¢-pt%«;KuÔ×gèz2aÃçóbIL˜¦êó‹RSõù]ß¿ÎP''°‡º_† eÛP…“b¢R§dx2Ã#Ú„¾{&Y,œÎÒýàb¬ãq¨m˜f.LU¬¬F'³ðb¬@°ÌJIj¤SSi²Yab5ã±¶A, D!ÂÜd'‰š sÆÊ8çEᲉ@ #%\aàd6")/<)t"÷[ aiY§ [;‘ÆpD‹S#&Àbhïø+ªŽÃD[‡bDéƒÀ¨àEŽj ÖΆ±H³TÇ"Y’PœHéÈ]@oîõþ —V#tyv¡gбÎèôô8T/À¯û m"òV‘É&ebWˆ$HÅü—Ñúœhpô|‚~QÜ÷ øÅì×^=žhkAÖÁšã ÒS¤à·,y^\l–1N²ìV‹¼”¤ŽÑa t© âÌ£ÿõ(Ì3Ð1ú_øécb:LªD‘¸6Ìb¨Uøšð}©÷žglÞ`ÎcWœ™Øœ±3Î.}ælîc^úýi†dÔd)MΚì²ÅæœÍ[È~¶‚é¿3Ÿm?L©,žö ÿ‰» #E1B¯E•‹A#c*À ÁW–ÒÄ!>7Ë•C~•¾ “ÆÂ çÌ× Q4Éd‘¨(r«D’ô¨q‚u1FœàÚÉNÎHf–£k­[!—¥ÊýÚƒÊ>Ö; ö[(¿O$äë`"âÌNî}0øè`úñƒèÁýCuzzX•m4VI®Œ=´ùX§ÓC5u‡v"Œ‹ªÐ›A>s7@f•ŽÑ"·P[uz^¾Œ1ЭHÁû‹—Áóê íQ<y$y첉A‚Øô.WhÖ€™Ïæ¯vî3ó'_®ÊU *l7Ùy‹™Ë6’xîwŠ:m3 ºŸ!Kè|êã2¶ØYƒÉ5vå1ówMvì Ì]փ̹‚Ü@=’üŠ-µ¼bóUÒ^ÏUEmƒ‚ç¯È0àÜ¥×ñ…üMÜ«´þ؃ɛ¸nûšÜ2¥‰ð—flÄ{\óÈ>ȳ+$ü)%Ö{rõpy—¿¾‡zrD­‘6Y¯c^zòRP/(ø¥Y'o¢ª+æ]6¤µ,ÿ¶Tò÷.;„¥Ãä;ìá|f·`Öag–!@ö€xúüòʬfç&’=2ó ȈW@Ö–@К5&oCð:H ï6H‚VÑÅmNâP‹!ÄVÿy›™?ø.ÊhukØÃÖ0\4,hRTñUÃrœ*7Ä|§â¤öQ¶ƒiLµ •òÛª³Ø`[¶5`jЋs‹Uİäêo Uè”Ò=¤Æ\Gmz¤qöBƒùˆO*•ÇÐoÜ^¼l8Ô e¤S¼q23+=+.Ê»~Hž#§!Š#S”BÓS©¤ˆÈ ï6ë:d%µ¬hŠÞhÕ}^Èü$KU#5Dxe¥n›IEã,uH 7qoƒáVm˜-F#=¥Õ›ºáN½“ƒ.ØAØ©º(‚t…ÒÞrgîapÊ ¯¹Îw`î{›øŸw¼¯ '¶`mƒo{=o xoz·ˆ·Ë»pbÝÛ…•®w›¤t½„_£îùïÀeGÎòÎö*š3ÈK¤—7¯E#þ÷Õco,M\¾Qˆ“ü aƒ'¤â±á}t¶Wù-û³Á*Wä?â¤I~ÞäOÊ·B‹Ê¬€{ò4.œNì“Â.{‰{øà5Èo7&ûÃòQòÅzÝ~|~»Ñn·?ÿPKYHáD{™jn¥)astropy_helpers/sphinx/ext/tocdepthfix.pyeR±NÃ0ÝóGÒJ%ê bb@L,•ªœø…˜:¶e_ ü=çÆ­ x²ïÞ½w÷|}ô#¥0÷Ef >2)­×HUUiôÔ›¯ûnÇÑ -UkÒ¾ã¬n+’sM`â9îÔˆ;z’««™öÎÒçð-Y“Ȥû˜SP)A“qÄ>—¢NYÛªn_žÛ\•€1‘¢Ö0M.ÂÕZ>®“„Du¥?è5µÏaç™!šƒb, Œ(ŹéÒ*Ý“LÔ´“±±;4Œ1ì´bõZPýv,1ý?ìVGhA¾5ïàe-†iê5mVtuO›Ytnãä ÃËä!úIæsß´}~ £÷G_f?³Ï’Ô4ª=(MQ^Öþb˸ÞX)²&ñìi!V‹Ðç‚ÞGÊœY'C‹DÃQ–§ÿoøÏ'ŸÎ¥™}W ËâÂú¬°*[”ÀSÈ»SØ2KçC'n•n"”Ç.6nUýPKu@,F#@òÅ*astropy_helpers/sphinx/ext/tocdepthfix.pycµRÍnÓ@žõ&ýŠà’Š+È—Ä BÕC…àÖ*ç€T©²¶Þ!qˆ×Æ;©\)=•'âÕxØ™Æmy€®vFãÙùù¾ë?»OöÏOrXŸ(Èç þmP6\ €RÁ™e#øpÕbh°=˜ÄýZü 'VÁ¢­ Œµ®²ès®×[ˮ۵˜‡«`qƒÁuôÀ¥aÁ`Þ+}nDÿÐÐ8h`"ú@0ß„_Ï_õ~½ÅÙ+IS?Oà›“˜ûi“IU¹3% Lªr‹5Í ¦o³‡C.–ÅÂbC:Øè.I°¬3kÈHbÈ7òÁ!S¤Ûj¹ÄÆc ]¡PŸDÚ ¶«³µCàH®©ë?¤wä/a,ÐXùÓZra O£Òä•o‡ïß>Û£ÃìðC‚Óib<5U}•ÍpQ8‰¯g…kl)éø~/ÚQ}EÏCÁ`2ª 5zæ¹?ô_ª7z rFÄ¢» ¾ºÛ`Ø)µÌ˜w=ö;÷l† +ná˜WÎaNé3fÄ%Ó§·G"ȦGZÖ/Ø`  Æ·Ãß`$ʺTº÷žGÅÓ=.+»\à'ž‚Ì|OoïþPKYHáD×g ¨¦±'astropy_helpers/sphinx/ext/traitsdoc.py•MoÛ6ô®_A8(,£ŠÜõÀ‡¡M»Ö M±1x² P’Ù#·ìÈeQ‚aˆl¬ò`˜ °ÏMU?3cë‚í•®¸MØö§]„GÌ4u­´e_,¶}»K£èëQ˜„œKv¬1P0ngê’çP´ÄÝÞJ’‚ÂooÙãdÇ6"hËYjø» ‘¦¤;Z[_­×µV÷[“š\Ôϩ҇µã¸~býNhÑ}.ác# (…sL½ìŒsLߦ¹* Eª9mš«*ÈY{×®£hßkU±,Û7¶ÑeLTÎ%…ø&Èþ„ñ;£ÊÆBæ! «Q®E™[Dˆ¢–BHS#ûn«L·r¾é6¹*Kp„&ò²Ó mÊ5¯á¥ó̸ð·àéq‡îsä]Éy¯ò¤ÝhÕáòÆùpªHÏé9:‘¢ž· £('-/fäů®"†_{ô±ÂfYl Ü',/MÂ*U4%H^Áf¹Lù4CÁ›[>ô‰=“*¸;Æé#¿}¨’ö/¸ÖZéxñ ¼¤ãÆ á˜ÍŽ8e‘ã+½`¯H¯U`Cª¦± ¢¡½îŒj‰tê0õ ó(ì1^¦Ë‰^Â׆ð‰8„£¸kv„N4s›,›`tnD¬nÙk*¡.Êé,þâ‘áC¬°NM] /ÿ’ËUÏð‚½‡K! ê5×ü€9y P«ŸÇÖ·˜h 1›»dn‘–$§ŽW+×X\ ÂGLFÆ{GKÐà)‡ÚÂÿ‚ozKH¨L¨ÁdÀ2©& ç[¹ú ·[ÏÿjMbãÃj7ý¼=1ÁGbçÍ n9Ò}É_ÞˆƒäÔ·–W ëglªŠëç9Ð{@颦ÚBðv7_Só/°ß÷,Np~ÇHW€}ÀÌA¿j%çAT•³?ù $¿áU¦Ùy‰¾ÍA~¼ŠYÐ û¹4jöYÙy5¿À4ÈÜAO\{ýÄ«ºœ H š%£tyBÀ÷£óÓôqé·Õçº*¦Mf|œ\gä¨vQp”Û;öšm—ËÝ„´1ÿO¼†ùCüüéIÚ̈r²º+À×ÈæMÛøµ*a³ åb X5T¥ÛÝèû¦÷‡³¾«‚xõ2’sp¼ê4z™YkþV'®êq©ƒP¬2¼dèŽbñ°R’§IŸ—ãL˜|¡’’®p&=èD»^|Ü/ÏXc2Ž5/ÔÝýâ,¢»Œã¶2Î`êP!çÜøu%ó?p§â§‘–6ÆãÄ/WÓ$¦ ,½Wxÿ Öef©ÔƒA_=àœgLsç‡ tIâGºh[×ãÔÈ|Xpºm€îšµµÄaÜtc£K¬©Aûó ¾á”ìC70ø"ùtJã(¯Ê'[œy=˜´íþd1Êsk&¶ÙôúžT/©uyúà”¢‡RWZeÙhÆràã;Ç»ÝÀ¤ï[0èÞ˼‡¼Sñá²ù¬$ •Ü‹ƒÛ´Fñ§WŽôšÎ}ÈmRŽ+ï‡+|9 ©ý|u†Ü#Léql¤Gmnôã|úŽ—%¿+á~݃aÈÑÀ<®÷ÔräŒM0©§ñÓÄtwšŸ§ƒ×ýo5ôð™RXþÂMÛÁ&VºÙ s#aîu•tJ°Ñ»ÆÍ̱Ìü;l&ô]°ë§¼l  ÷Ö7¤ôŒÛB~íƒÀUÆFÛvðΦ:¼¶íñ.åuí<Žç´÷¯{râlyÒHh°©á3–:~ˆ4:¬r]~yz“ž„¤ÛLhÆ©2bžqñhœ'¯ž°råhºŽÑìV© F³þÕGgÝ& ÈɤŒ‘Ù?PKu@,FÈ9_” (astropy_helpers/sphinx/ext/traitsdoc.pyc½X_oÇŸ½ãñD‰úcK‘ãÚ—Ú-Ø &£‘ƒÔ5šZŽ“UŠ£µtÔÓ‰·¢Ž:Þn—1H/uÞŠ~|€¾÷ô“(úÐ~ÎÌÞQ´S OŠ(îŸÙÝٙݙßÎÐþï’scÿo½6~s @ý!@K¡±€±} Æ6ômW _Ac6ÄUèW¡h× _+Ûuè×Ëöô ¬@X…¸cú®Ç~û‹Ð_4ý:Ä‹0nB¿ ã%è/ÁxúËflç¶ ß2ý÷W ¿‚}dŽp·EøàÀû«6©Ó_#è ¾E5®A¸ÌôëDìµ[¨­J€óëòÏÑyi¦ƒ9šÓËŽ£dêÊ©–‰ŠÒÄÕÇvƒ$Œ¥rq²Òy” •Ñtw'ãìÌU'yè¥ù8Ðï¹/ÞßwäªI–¥¹vŸó^î‹ûÇy~©¹AâJw¢dèÊ Ü\fq0c™hbè$´ n~pà¾<–IÉÖ¡Ñ‚5²Ìåé$Êeˆ[t:$‚{¬uöQ·›åéH´ê¨A”uÒ|ØeŽÝ—ÑIÔ}’†¨QOŸÅòÙ$ e%RÝ™©z¯TŽ™>˜1¤¡ì ˆÇédx¬;ƒt<Û§k޶ë8Ù\›ŒN/ÁEßD¤³¦ûUO´ô£1)£—‘–áŽÚ?š$Óv#A˩РZŽ2 ò “†´2OòߜًX™›|Jí¤½:#}Rp'jkFÅ^õ5¼IÚòÔ e T’nÅ—–ùÜbsÈâ5?û-ùÙ‡Øhˆ‚¼MZä-d 6ùh… ”ÕÂyÐ_hB ¼^»N»A ’©Šß'Ä÷¯‚‡FμBÂOA3wìn`ÿÏ Î9€oùù.•£ 팚¦‡ϵxn•jܮùͺ€‘SìuQó ŒItÓ=»ºI  &8´óÊÌ«Â^² ìÄüï „@ ‘œøÃô=:Tœ3wöoÁ×\Ôà¢N¤ólWá¶i>:ýì᥎ZÅti¢U:,Ä“mª`{„\9¦Z4UÓTK¦Z6UËT+¦Z5Õš©Ö Ïk¦ºnª ØF{7a›ö_%)Fk„C¯¶×~ ¯fW¹X~–D: âH‘W£I¡OÈ;î³T»?Ë5TGQé ¨´ðK7¬èfbYï߃ ¾Íc]nƒ.ïÚ4FѱûÖWâÔ–˜í K!Î4uc4ÛÕLjÓ†šŠÎ}FµÙQ©PŸcq8‰â°{FJwÆÁ UÓ{ïßï|poúá¶¿ýË®»rJ³3ÿXÆ™ÌU×ø_q­;CÖNv¦Èq e"§Yþø>m@šÖÀ Þbéݽh˜z’KMfß›ŒÇA~¦ixG¢£"è´Šœþ)agˆpYNrøû ÆýRñzO"«D±Ò^€W¡øDö$2“/¾swnÍ4ŽÌ ~'ÚB¥ÈëzRºÇ*e»©Ffïq$s™ ¤YñtŒ³X2vm³i„ÂNÛë¤h»*C˜4mÅ–Áì¾ â‰|šç†tDþ/‹x¡®êe¤ uœ†Lõý%÷}ÞÛ|Š ž>ž=Ó¿X³¡Ô%Qeq¤Ù*ƈ¶ Þa2–9‚šÇ¦Ãg&ƒP‚ÐÂ&5² ÇWÊð$Ch“8‡½‚\¥‡¬ $~Ô^'Õߨ©FÞ÷V93öx%·H1|G ¢àŒ^{‰oîÉ£ó󶨸AÅtùìÎéáÈ{›(?¡â(?^m†“×ÑW]⨚ÇÑ9PV— Ü¦Å¯“œ½NIbðô~E+ÑÜV9Ñ–>¾²šc3³^J?  ¾4rÉÁÞå²ü´ç÷@ð!Ë¥QÂj±½zô3Z1tå)Â;ÈD³„—2\eתHLÿKb‹m¹&VÄ&~W‘l­ãg…Ë5Áq£÷sÑ70ìûüGTÌÔûü5¿¼ <’â6ñ%Ø­‰V·a7ìAõÌÀfÇ€ †£¨rôz‚që<½é]¦ZÆØÜ/§Üá)§w0L´‹0HM±pÅa’4‘ntÄ)3ÚætªŒË\L£0¥’¹éÑ[Ë3‡Ñ7˜l1ÑqñÞ1L®¨ùÙ0IsÌÓ8Ä S'3Mª36š¨°;Ldqã<-ÞìOÐP¥™ø¸´2fÂÏ%ç<ï„hW œqšž(4ãLÆ”š²G´y&ÔðÊDÍ«%Ãf½øòµuß ' ÐUŒ8—@ŒÉï^b {jèvIDIA¯uEìB”Ê÷(¯0C˜Q\”‰Lh®ú?DÑ[Ä©>䈛h¯, ‘†˜Ï¿aú%y&*fÓýák›°SÌ5(‰iª¾#‹BèÜqR‚Ùf£eÜ#†KqúàÿIƒFF5á¤ùª@) ‰ YDÔÑj±u1 Dãt^¾]þ‘_'ÅIŒZ5¾h¯¥?€"<¤ÉQ4d›ù4PEØJ6ã3ˆ†Œ¼ë«y®jnp­4ÑÝ4‘žK{¼Eþ©B$‡;¶êq“asƱAV£> â88Œ%»ºzx=uŒ?}ÖÕ7ÖÇL‘a®MlKK‚,çیPŒÊ¿Dx f¿ â]òúÌaHì—ÇööÊwŠBK¢²Ñéò^ìyEê~u~´\(‰]ß\eîê.£u]§Áß5Œ*)¶|{·1¾|«)Ö­ï‡^X>'khÒâ$ÏãÈ›aḶ́ÇüZa›ã¼:HGì…¿@ZYm  ˆ£ð‹—çhB¯9¾<4Ëã8°¥qš*s·‚"æÄcX¬Îl©^*ËeŒŒíë¤6 tµÏú#ãùÅ›Žâ¦Õü±è9¾i­àgãYc¹µù?PKYHáD–ï0‘ #astropy_helpers/sphinx/ext/utils.pyVËŽÛ8¼û+:³[‰VÈy€9ä`O¹†LI”͘’òÀûõ[MROb ˆ†$²««‹Õ-«n0Ö“êÝ k¿QñÑÝÜf³idK­ê›²3Miªïn‡›^t2'Óë›6µÐîå3~dö¼!\OOOôUúÑöŽ„ÖäÏ’†±Òª&á½UÕè¥#Ó’ @Z’•­´²¯eCռب¢ Þxùùúvæí ŽÍZ9Oï±ã=¸×zl$¹±D}'NaSÎ6#ÿcÞcCc°ªü?Xu^®™îüÙ8‰2„ŸA*yRý«ògÚ–[N$¬dªÀ¡cY¢ì²-bt9 Ǥ8.G³ÇÖÞfËD.'åA@ûÝ%gÌ¢,U#ÛþrÈøDèÂúÄ•pá¬èŸ5*ðɘßeÿñ@ï^x%Òa^kL2°ÃÔ³|dئq42¿ g„}±Z—zæeúÓ«· Š—È'§+SšÉƒR˜ƒ)pwÍ‹výý°©оýÔ†“‡y®vÁŸ­5]4CpÚvXwm‘³ÀÆœtß1“ÿÔ°cŽùªÌÕ)¯œ¢à„ˆÎfR¾]f„{§¬xbdßðæbA¢´-¶ø¯#B6ÇßÛåhÓ§d‚AiÙläå[±`\¡iDRá¼°ÞñWmî’ ÖX¡”ì0GßûA†½*'þìщ_ÒÝJN¦SîÕaÁYÍ#´åÂd®Gá¼þ66Ç¿«Jò‰M@7ÿPKu@,F5Ç­Tü $astropy_helpers/sphinx/ext/utils.pycµV]oãD½¶û•´Ýò‚VAU5ðÀ¦»©³ X¡ªB ªJ Pv%¤]gl“IÛõŒÛÅO‹ÄoØ—ýüŠÝßÃÃ>½cÇIE¼à6ŽgæÌ½çœ¹ã‰óÇnûƒóߟP_6~¾Âêâ-Ä b€çͳÏ-6„6üŠÏu>í:–âõ}@ÞÃÏ:~¾¡@‡Ø£æ/-°´›ÒíÀܦ/mÈ0jNÖàô¼%Ž™áÉ:=t"^ØpùÊ5HN«7hƒžžÖpdÕ ¸p ÷þqºGÓõ&L¶ \7 )ÛülS„#"|ƒ‚ª×4漆róß¡oé o¡Ü"hÙ‚›t æ[0ß$y§ççffÊm£» ášÑýU7×ëæ¼“6õL¶!Ü€ûô´÷ɽKg1 ÕÐvÓÿÓÜ‚|ß&ž-Ìö>”;0ßÉní<Ñ»´Ê]ãÜ=ÊœÛ7¬îA¹s„ÞƒNþÊšïø+«NðÖð7 ø e×ð­;áïðwz•1™£"+i“Jæ·56ºÈÅx3=,+üXŒkK¿ÐB±4bœMÓ°ˆËE$r‘"dþŒ%|*Üv›áåº,Iµ8>6-ºž NÁK¥ÙCD¢y€²5†ØG)†½aŠ£R7ó³\^q-V™võ8UepÝñÅH&×RÙï%â¹ ª‡ =e{Þð°Vñ#Ï1Ÿ¹2Í£æ2Íš;fJç·tšnô‰ ¬Ò)S‚çÁØ5È4‰gqðXát?Mãfþ·{–¢g «jH†a+½@‡ÄÔGf”§q†ý0ÀybÕ5©ÕÒÌü–Í×Ù ÃZu]«’ͳáKiˆ³YAL½*ýë¦W×&¨EcE')bV˜¬Çž&LíØRTeYtùßsG*»,x,#‰ î¢ÒîÈí- lÈ1dšÍÜBËX¹S©7’Iè!/õ'jˆ¥ÁΨjþ¾.M%§ò¿â¹ä>ÚÞCˆÄZUÌç Ù¤Fne§¡Öc‰EéRMT$–ib–,ˆ¹RU±<¡ edöVm´4“dz&J(<&±×X2IB6)Ч•K…¿°º.NTºb36E ÕVWYo"¦JÄWdpµ´L™ ‘‡X¶|ˆFRSË<SÔ£«ÔôBªw£¤0ìÐmÓ]ˆçé-Ó$æØ „ÛÝ#pÃeHs#tNª™2Aë­`žÇ\íIPÅ e°˜ÊÜ d¢2ÔoRUó à™áaÀ³L$ဎà³H¯4ϵ¢ žG"A}9¾ŸºtJ/˜sƒ^¾Ld2r.LÒìb$5Z:ØYqe&-÷£^£¸j&p½QL$ì4ßq25ß8f8_áÖ• &Í]Ð/07u†7¿qØ÷C\iwʃTÝ}òØýüèæ‹'Þ“Ïúb4êכŋ8ÃQ_ec™ÜôÅîWû'›é]ʹºƒèŠú˜Ò|ضví=«gŸ8-ë‘õÈÙ°ö­ëÀîØÖGVÿ>µ»¤l°M7¢­iúÚ$lA÷ÿ!NÆŸT‹ý%ù£ˆÈ޵ãüPK*xbE#¢ƒi_ &astropy_helpers/sphinx/ext/viewcode.pyµYkoã¸ýž_ÁMHÞ±åñ Ði<@vvŠ)¶û@³ý” Z¢cndIKRIÜÅô·÷\’zËI€¢Æ.Ææã¾ï¹÷2glñí‚%E*ó» V™íâ/´rrzzzÂðÑåNæO‘x2у8(ìúÆŸ»q•¦,“ù½f¦`û"­2Aä“9ûå`vEΊÍo"1,:Q²4²Èuä._$EyPòng.ØÇú+{÷öíŸïÞ®Vls`f'صŠÁ÷s¦…`WÿúõóÏÿ¼Ž‘L&"×â‚}wý½ÛÿÇß?~úéúÛ l —YÍñn’HY¥aVÒ/’tgL©/–Ë4›*¹&*Ô~©{‘oE–.]–RëJ,ÿôîýSè²¨í´ØŸÅ£4»Å¶ÊR”á¿w+vUÝA«Õ{Rè‡,ô™}ÇÕ†«ƒ5üÉV{–Ie@É}Y(ÃrÐÔ~ϱ¯wxšºÍÎ^” e$îí•ç·÷£õÒUγÿ…ê$"K»>¼ç÷"VbK‹''~QtýÕ(žˆ Oî±¹¥èA(² »dÁûàÂZÝÀZ±9”‚­Y•KU"ƒËF»Ú(¯rE=sH#þßÃ$'©Ø’¹Œ$OC^–óze樊üô°m*™¥BEX±;3/ ÛqÍQ!–ç,ˆk7Æ.ˆuàéxZÑè¨ÿñÕEÉs'L¼­²Œ¶s¾¡ÿwΈ‹ÜTFt(uhÐ'Žžq\_œµìŸQöÉþC¦åš ¥ Õ'áõ"•¯¤0ý]úЖ̷EØx-BŠì¹‰Á"œE æ—e8› o=r•‡Am–ðüK`jלë9£àG^Qô;ÙØé¹> ØùHˆÖ0öÜ€™¦R9û©ÈE³îaemÃË[ÿÆS¹=nÒ3v•eÅ#ãyëB©l_eF– Zre4ΤÀD¦"7’gÙqº; §D)¸š‘&Ô lj(G}›a™Â¯ÙÕe&MDA_ÝžU¤™Óª·EàeÉÈ|’ÎØ½:8ÞèrBœÚ°·¿]pŽ"íªf÷iem4|/S[ ã[‹œkxœ…¸s¯XÇä¬8~…·[`œHÄ>ã8˜[³“6‘ݱáwm°QnºoÀ ÷…`­›èˆ"i2á#ÐÒs ;¦ww¥¶;}F¡i éìúˆL9éyޱ ã¥Æ´'åoRÿÆaåÑ5gè¾»¡àe²¨gS¨#QPµáy"Âæ 1Ÿ·ð>±LÖ¬w#JýÓ’¹ëWF…É1‚ýkÞÃN¶æ)6ž7A1¸ô‚9-ÕNwÃÁšz* ›¥F²ü+-Ò9‹GA®_‹;8Ü'Hoê#$ñ©4úUUÂ' A º³Ü÷k¾€F¨TÄáßhDÔ»uÜyü5›AZì¹ÌƒûfÍ‚òô…K `j^µÂdT>5î¶N%a´¼«…ñ &K\'Øü9ëÉÓ2‡ºÓA7‡>Þ™$•£è4s¾€vã‹Ááz=‚ÜÖŸöL†*QxA¨­¼kšnß Œ…oå<ÞpÔrL&ª?õJ³´½Ò14%áŸAÔ—¨wãÚÆÅøêºhd ª4X ÌtìP¿ùŒMò²Ä#DI8mž’ß oÙ NñeÀÞÔ‹Pü3tMT{Q|–'“ˆ¹Ÿ:i-O¥Z;³ÏŽÝxÓ¹RŠœ .~‚%ÑbA`ML`ºnš1·æRph“ºðÅ`$ÍÚâÏ|ë·†+ѺÖÜ^“éºñíÔ¸zÝqù´J7ooI+§’Ìá5˜ bÅap£‹J%â6˜Éû$×ZèõM£ó‚!¸ís¯ÁœkAü¬°ÇÜFV%³(ak ¶ówèA!Cß|äR«§‹ }"¤e§5ÛSÖPpʱłºÀ˺B]ŠÍ#Ê=ºÄ= ¼7`“À{.>#Æ÷µïº;r…fÞÒõƒÛÎoçI,=kÓæ¸Lév£³·RRdõ˜âAãÿÃ$Õ©|; û ü¶ê’ïìØ“¿bp†ÐO‰Œù bpÍçj]\&ëöÌí³3QÀÂó´÷„a 1›šaì'ùä™<[¯fm™m‡×äí@{„H¯Ü’™íÍJ«o¹:ÝD[}ú=Å]ƼW%­ª"­°4Ø´N@`Ûœm®þPyÖÒµ\eÿC Þ%fÃ(èÇL æmÌÄ›¬HîCg4#ô)ƒòB;4ìÊc*ËÚ?[!Ôè°nÎØ_=v©ÃìF8&Vl·ìQñ™¬î«’Ù÷ â°•˜°-=œqãcb* F¯MÝø€:š­K ËZÏ~—¥:6õû+jünÜm8ßótn;R"˜vÖÞZ¾ÆáY'Û_šùA3tY4Û±þrIÑ3°Õ#÷ܰGáfkkHgµÐ fØÇ!žØ éöMÐCVžì ¥I„=ç ‹Ep3Å2 ?_}üá;è§m3ðX¨{M‰A‡q„mŠ*O¹’àÉ•èP+U†!#ˆÖ ÷Mk·=r­m*[glÁV½–´73öó–lÐêÀÏÕ(Õ)JI›þS…õ2Oîm;³vø¶e¸®­äÄ3Ê«:‡ñ;¢ß£&Ò…€eKA0Ñ9\¦òÁÒuSÎ6UNj>=Ö|¸äãœcz;ÈänëË%ÿ`ç~'~­™«÷PF£ÚÏF$Þô¤žMè³—°)¹dÞxkf[‹àr …>ݰ¬"¢íkD‰È·¡*ªMýõñúæv°8ѧ?î$jÙþw§únonº/‘jžiæˆwäî°íõ@®.Yã¾×Ë¡RÁ á“U(°ÐÅ(†zÀüŠN«|ˆÜGÚ´Àþлø{_G–m¤~Y@ëÖçúÁ†âéǶ>³ ¶J¸Ñµ‹Êee,YXC{V yØuª UQñDîëÛ8ðD5u_ÆF®º¸÷w7EzpB_îV®]¥³ØHQIiƒe ÍçÍP÷†}™¶ö—<ˆ~+d RÍ¡¯Í·ƒYÊ:öõJQ ÄZänÛ6Ž<ßë†smS‘Œ·¾y¶•ÝXVÜÉ„^A¨A𓿮Ø;8F¦k£Y?M-wŸ{².ŠòFc<i=‘Ú¥ºq勪WhéÝ,V·Ķëu´¶Ž½Ô’žõ±à²Êºxü娖E9x-sHÒ±þkD|ŽàX´e_¶×êØ'’IªC¿\b~&¬ï¿?Ùä¦ôüµíá ÷ëGÏ6ÀÚ±oYH%ÛêeK¶?;•É]ôøà@µí¢Ûçw¡g´W€‹úÏ=p_²ó".3¾ÉDÉÃü |Ö’ ž‰ÿ‹‘OױŎ¤­Ð0ÒTeg0£åi»·£Ø¾‹·¤ñOH I/~sÖé|é".åè°èñξú-èiÁ¼÷wµ‰Ó$ÐÂwg ; Y¡;“ãÄ%?/šéwF3¹»wö’Ry’UÙrŽca„ ^G@<=Cà¿PKu@,FËÂó +'astropy_helpers/sphinx/ext/viewcode.pycµXKsÇî]€ ¾"J¶Vr)fl‘¥˜²š±l)±c[v-eÑ¡­‚—Ø%¹äbî ( \IÑåG©ÊÅ!ù©\|ó!À•ŸJ嘤*‡T%_÷ìòa9·ˆägfgzzº¿éùzs--¿ôà~ÒÏ+xÔ×(|¢M”ù6E5lÚ´ÉâvŽ¢5ò´™7íQò)c´9Nq‚ ®øEòKMRcŠ6§ e˜>zÓäHe†üQ©œ#L*³,z}aœwsh•ü¨Önw–‚Ž^: ƒGõ¦HÿÇÿ”äÅmßw¢0ÞWŽn:¦ßއg9aì¼ÛÕ»ÍØiníuíøª'aK‡ÍX-™É·êÍV7 wvõ-絬ê\¿víæâõkËËÎV×Ñ»³.J9:ðWÎí÷î¿þŽ»¾d„Da=ˆUpËyuýŽyÿ֯ݽ·~×Ùn&XV{a”­ø®§ë»ï´Uï8-n±¦»Z·Ô­ju+Ô[íú~ —šÉZÉ~o‘_5v©†JµƒêÊõUX‹b/‹™·yÅG¡Þ]ÜnÇuÞ¨ƒ¿ëËÎíövµ|ƒ7ôfzÝyÕK¶¼¤[ ÿƒŸ˜ŸôŠ‚”i¡ð|ÿT5SCñ¶XûvìEÝŸ‰éAÑðöƒZlóÌ{2éF˜CiFQ„:Hð4TñÌs&ñðõ }N´‡?‹¾°HÛô¹Å8<²I=K!q³–£˜è3¢mÁþ§D}›>³¤™“fŽ:_X=‹öò¼¯½YtçaÛêç©—§½A>Grös”téà}–ˆ=aòu^·0ìÎÃW¬~UîDLI´ø|Á£ÑÉ‚Dv0kJsˆzƒÔ/²²{87#”ü•z6wö†XƳ„ARÿ̤åÒ·Â^è&pÇ]ÁKŽ4ü:Àþco›I±ÁÒ ãrà€m›fÅ`Ðè}8.Å‹ ðÒ}“zâ,Š=˜g0ªgúï<|š ˆ’/îpêìÑ:ø’ÿ66â«PuTTý Y–•êcA ·UC¤håh]¬Å–¸§®¡ÌŒåÔ½øYí„V3ÑÎuÕáXÂ'Þ ’ÁæòuYNÜ’šAy'ôyÊvû˜ÀæŠÒ%ö@jùZMâoÚgD×jrFïvêK‰ í0а0În¼Ý”:ñêÁ–Wß—Ùu OׂN]³#¥9Öò„G^Kå^3´ò®Òƒ(Œ÷eÕŠB-½;˜Z'bn£nµup—·'!©V‹½+ÎËdb¸K”ò² "TŒ"ú˜¥D Îo½¨˜ ÄZy­Ö_±ê [íQwË•^jxõ¦ê,._[za±óâJmåÕ`g§êa‹¸3j»AÔ •…hæjæ²¥VWO˜-Õ¶ÛQTKU½ÂË|³rÖ˜5n­ xƬkÔÊ寭‚5‹g­ykÀ®³Ú¥ÓÇã_t*Jö„ 0—¨ïQòGêNóÆÍ@7â‹@æ€ ó=F&lcÄ`Ȫ€‘ÃÊ ŸKKÈÙ+2:8ìý:mâ(peDd(.¦ý¨óÉà J<ÛΧ*¬Op˲Šb]×Ñþ0ÏA“#©ÅˆƒÝ?$h¹g€0Gƒ=vOpëf΃…Ý)îÉep S»ÃÙíöc/R'|$jÚÛ1Ç!Äm¬´× BØuâpfMw[`Èäƒ0ˆQÅ .ÃE Wî'ÀËs+ÙÊ^p²¦~³~\çû‘ëÓX']sߦ—©Ëàp9*ºÏ±(–ÞV‚Ö >|heÕv=ŦY;é9k@GÑ’5eÍÙEôN ?ÖúŒ‰š /Œ5+ÞêºXÿ«,†™ûª;”‘‰ªl,è´©ìêF¤);Ö°˜~èT ¯àEºŽíëaÓ Aàb#é(í%À…˜­Ð7‘‰g×C±‹þ@5ÛI=x(kÖ#O©@©ÑSk.2½\˜ÍÔ[ÃC׳˜‹CŠÁâ Œ‡0qàZ™ë˜zº—2ׂ.G‰püª¦ÂØÓíÄà¬ÞŒ·Ã=~J‡44»‹ÇÁÊ÷S#µ"/…m3ŽºBÀZAÌà¬u°W÷v‚µ Ñ» Y <Ô½˜mFÑI¸÷ÞÈzÁ™Æn¼šÀÍú¢W`.v—²Í·¼@€=”jÄ© v¶žØîÿ Ü‘“-€{z>oC½*èA€±Ç+ãå 0[@ f èå@;"õ‚5Çu»€w³è)¢=‚úE”~ùa¾Ær_"!`°‚}›’RªÂáØæ«¾Âÿòæßþåèh _,æž{‹ ñC.nsñ#.^96/çòZ ù3VGÇYRô‰}Ÿ@8`¶Ö@ÒÁhâ–#yÞÙVÙª3Ìù¨ó©ãDUý-gl!æè ‡ïsø‹&è›×9&îi=Ϭ@c¶UÈ(˜y5Èä‹ï£ìÕ,,, Þ²:×m]R¿¥ƒnÊÖÏ\3%öKOH=(<Óv&ÍÃì>¾á9Ó›°Àjû h#†‘€œ2Ë®€È\cQ^pŒúãÔ“žroœvìtÔ|žU¦œ§¹þu~#IEÑ(üK™?Iý)¡ù“Tùv™¦þ õÏI^}¦X?ðø2z —1®ÜŸeŽZo–/Àè!p;G³X­7C•²ù¿Šà!½s²~o‚E1“ý]?xÎÚØÁ¶ÊlþuB6HoÎd6*œ/ÄÞ¶ìƒÐ‹{›G|eõÊ´7E¡ªÊf;kVž7A+èF®±ÂÄ÷à+þÛøöT³K åÝL‹ÅÒ %3žÎmü/ÙO³Ù`³ï2teiÆÁŸíc© Æógø5ìÏ6¼˜Ù›Ž4æÅ˜ó§‰õNSÚ% hr1”Q8 Wü3ŸbøNPßOC. ë»)»’ÝR-ùp#W _WqS™ûšo¡ÕV¬ {xF½Ím?Ú ë»é§5åx‡È=½­(õæ²ëJ.)÷›‰Í±îìFüQ-HŽ¡$ˆ<µvº?¡”Å»£µ‰‚ØeÛ»oqÏøi)5ñ«Páí’42B”ËZ#2 ‡& •´’«Hï@‹RÒ$üL̽×L‡*ð«À7bAµâ´Z„µš­… gnaw‹ÒŒ{ÐM¹‹ÓÔNRTåBH<óww9ãHîýÇMã‹$Ù†h²ÀÞ†ryÛl9ïuÄñæa!Ã%ÿ`–<éf¾Ìb”3pÝŽ–Ò]1t_Ì6ƒùõý'Æ%FeÉ( êº&á¼Æ'¼’P´ÌÚB]Nµ%ÉåöÉ×÷§,öQ]d¢ª8måc¾˜gQŒ£NQ¯Åcêµ IŸ$$5“(Ôä;†û<£KNFêÛ²ÜÜû1?£ô ¬Àø‰yYpèvëJ,‚í'ð»PΔ«Õ`€ZMŠZ[‡‘:IQŒ`“<·—pò½Èd.§»[]^Ù¤ý“'Ý,sI>]*Í_MܱL>þazÁ´ãP$<›Å•~2jI$zИòWg ø$¬È–Y5Ñw£žFQ°'ì 1å„-GÐF_®x¿8XÜü/PKYHáDÚ¨;Khª>astropy_helpers/sphinx/ext/templates/autosummary_core/base.rst]ŒA€ ï¼¢®<€ß(”ƒÅz0 Dãm»Ñ X†˜tSÆ@$—Ø£µ òZS¢É÷i‡UòºÑ²Ï—“Ç’"Ý÷9.}^÷ì9=Ê™_`áš§¦žÇh'ôÑ^PKYHáDavì'J‰?astropy_helpers/sphinx/ext/templates/autosummary_core/class.rstµ’MNÄ0 …÷=…7£Åô•X ±eŪ4ui ?Râ BU9;I“N;ˆáo—ÄÏOï³3ì@t`±C‹šc'$Ân,Ê„æÒ·XU0 Á8ÃP·¡5ˆ‹ 0Í“f*•ðºE+…žîÑŒ{ÚI™ÖËl™Î³€y2\2çRqe•ëÍËAè­ RTE|¦ìûºZP]ïCdPH½i]Œ4 8ó=Õ—7³¬´¨Ì¯ëÜyÆ—î4ü‘'tµóJ1ûºtùRž;œõ<Ý.Õ‡ÔƒßóúOr‚ø>’,p¸[Ç6Ã=N2ƒì`©*\^à/¢J=:œ…Æ-7u^Ȧa¢wlýÝm#c¤nÖ.lÃMƒ¸A>`TMX `ѬlœØÿsÜÚ ×‘àžâ’yL‰ð2ô"vt­¦iÂ2Ï¿ð&œSÁrÉÙU¨¦ %•ìkEµJ9FÚÍ.&ª‰„Ë/=W®ÓÉ “P¹n?»–m¤s¤¾Aj.ÇH²r|̲0J•½û]›ÝY?v¸ÊE"™šòB†¥c6ºôØïˆµ`(Ó^RZƒ½9×ü¢$¹)ñ*#gž™·ÖÃ8K…b]¬qègžšöÃDr¡ìƒ=ö×ÁWâf÷Vd,Ò˜¥…X…1KÃdY@[TiÉÚqöØh®x"Ãôž¼'•H³kwÊ£Œ Ù×ÒUA> ¥âÂõÓ8ö’àŽãÇ/~±!ëéôjöë‘sòóËc¼9è?©¹Îè×Ñ‹’×ɪù~ø‘'e€7ÿ±e“‰½ q¯¹“í³½T“Ä‹ùP+.±/1(LÁ°[º¬¼Öî,ßó¹rã4È#.‡oëtÚEèý¢ÕzË*ÿ³ÞRÝJÅÞëݶio÷l÷¬†Ø-ú‰æ˜ZÃí<£ÀE?$Qûûa’EžÏ}£t4eN¨íh›ÒˆÁ21á§3n ¸Þ4cðqß¼ëBC™pÑñ Ã@úüÞŽŠàãZ@=jÚ¶÷Ø!S²S=¼2r›Œ+À^Æ™PæJ¿×_øõHì%š•ÔÁzH §—¼PRÂ&\GOÐRªhSôz“/« Îì‘~ìù©œï?9è»?vè>ðÉdp¯¥2›†É|€iè12¸3%´%?â^’gßWañÀ°Œ £k¬šöçäM™ø"…v Ÿã£§P¨úöJ„Š;ºR›¸ÝóA«á@‹=¥(ÊT:+UœˆJqê4¹.åÆu5¤?%ƒ:Ù™6æ{QäÐAÑlãsîçÊ;¸F/‡C¡î×F3¼ ‡‰…rQKoqFVVt5Þå˜]g‹6]õ*ÿŸ®Ûœžþ.]–¿¤|DF[›ÆŽñE³mvÌí¯Í¶õÈ|htÌÎZ×´)`g»JŠÌÏ3‘ú\Jg‡.t¶ŠŒ¹º^V”ˆ"G»hKG>ç8¹óåR¨Ÿ.^rè‡ây<§lëߪŽæ–Ù±þPKIz)FíÍÓ`Ü3astropy_helpers/sphinx/ext/tests/test_automodapi.pyíYßoÛ6~×_qp€JluíÞä!K @×—ömëTV¢mÖIT£ØÿÞãÙ’b7±c/Ã0Ilñøñx¼ï;Š9ƒ÷¬ \Ó^R~i4…ß>¾mV…ÊÛÀ4¥ðþÝÕÛߦJ›(bµÊ€Ðí'½Òë§re¨5š)QC áéyøŽ­1¬Òísf¨ÂŸÇû©ïJ/™Lb-ŒßÅc€3°O4˜E¯¬)‚ÌÀ8³ÂŽSG¸­áš,é•à36OÄ×o´0ã,l£ÑÈýý]K Äõ”ÂY7Š&8®ÛÆçö©6ª) Ì«1¢%‘Ì;у,é òœqfò<Ñ´šMàü|yKÔ\‡Ém³0Ë Üã›$÷ÌlCˆ1*`ÙAãÞú.¥|pq_üêR"%nª[[z¹ùü<ÀÏWç>œÁGQS»JÒT&„ nHÕPo™‡. ð}½xƒšQEiɯ㠻$‹'[-om\•JTc²¢õ5©4uÆG»ãíÝêF28zÖ$];™B®’ñÀ,mdI MZ˜u·¼†êdW;åÀ”ñ™@Ã?>÷ã6sL+í»Ö˰Öa µžO Egk@»‹”—I²6o0,ôíì[q"RçñŠTå˜óè¢ÝûO ¦185Õð•b–Ð(JÓNªd´Æ`æ ZIªtRŽÞ™Ôå‘ûo†Dß…´É§q#;ðd†[¹|ëºò•hVäôNbš¢jíôj_/%eSÑhzXë†a CtÝðÂ"ú«m]XÝÔõ!¸v¿³Y‹=¼ZùDÈS²—Qte¥„®g?ÚÜ…Ç}hfxÇV /(¼ad®H½‰Ä°u½›–Þú`¥b7Èó)&ÕÁEI”Ѽrß¾ÓZšÕŽM1ãjbgsÇã4dk¿Œ'XSMå8:³õ ‚1 §V͈Z9¹E´¥°WÑZÜPpˆÓŠq · ”@-¹i î2dF2ÐþO®8z[À‡Ñ€°#¸efáœëЋ©§¥ƒÁª„†ö°Cï •¼£ÜÁ;¯K3ÔIÔš ˜¶^y™ÄbmkÈÅ–É@†ÚXɰў´¸Aýl²)³EÔòÑ—._ü/-ÿ-iy cwÍåÉáDCf±ÒµÚå@:Œ;:É„tÇŒ×gÛ}Èb>¾ÞÇrwK¿á‚‘qúÉlµÀûñµÏÉ>_ 3%¼\”JŸ¶/kÇ¥íyÛž…¶Çžû)'‚ó]í™N'˜nb¤3øê‹§ _Ö-Ö´}EPXP‚oú¬XE5*(Nÿíqep‰çŸ[ïž{lݲo#¼8ÿ÷éÐV­‰†ç‡š0~´—¥aJ¢f[üi) ”=æe)xô$m|Ú9CôôÃÇ!Òu’ºo£yxáõwGp"Â=–›”ݳ*÷òjx[°dòd,°àh„3h3µõéëÇùù¬ÔØã€pÔÃü|ÚûI7à' œ»÷ÝJ·F[ªÙWÖQðÊK»½FÝJÀgæYK‰½XÖKÐÇ¿!+Åéˆf·;ËÍö[»·}ûÜÇúª=ÜCÚ+© ÒÑ &±ûé€Âöžhؼ^¬‡;ØîOÞ½ËMâkÑàQ‹”%³~“ª=`A?¬6_ãÞ-¿u.ÁSäËÁéøs/u‚7«ä‹û> ’§X™…Øó ’Ó’§ gæ—×ûÝØ†ÙVÚî?ÔûºÙóí‘òØóèSÅñ5ÎG' A²Ý’K2§‡3Ü¿màÊaφ2Ï£|›\Ûvu÷“Ô÷m¹äYôPKu@,Fnª¨6' §$4astropy_helpers/sphinx/ext/tests/test_automodapi.pycíZÝrÛÆ^ü1iɲ%Y¶$ÛÔÔeÕ²ÝDí°©§Š\OÓ6šrÛ '-aW$(@°K[šÈ7Q/zÓWè+ô¦Ñû¾@gú½é]rÎÁ?A´þʤ3ÅGvqöìîù¾sv!ãßÓŵýõ…˺‡çOà”ÑãðÓX‹±ZïZc5-¹ÖYMg~kìÏ0že­ kgY-Ë4¡³fŽñ;Ö˜ÆóLäÙ¼{ý‘±cÆ>®]c¼<-öž¿ÎjEƧXó:ãӌ߀­9Åø Œ5§Ù1´|ƒñ›øNm†ñ[ckÞd|–jÞb|nlÍYÆç©æã·Ymžñ…±õo3~‡ê/0~—Õî0¾8¶þ]Æ—¨þ"ãˬ¶Äø=º]fü>«ÝcüÁØ×ï3þՀÿS2až¼/áØö`²X …B±æez÷¬¤Dg[ªNmØðüU„ËçÎ¾Ø ü=¯Þs|é¬u´O7N´FmÌÚ)éXáW Š&î¾4;¡é˜±nÓ%ÈQ^à›R(åùu|*UÔq•¹D¦ÓQA;àNè™JH%I•‹Í£ñY8­<q°ÆcGzÒ³ßßcŸèì5ü ìíèìÈ`ÇÓ>›f¿kw¨ëÛd¦E£GUB9JE%T¯2ô µG#²ÿʉꒆnŸäË ù[»¯Å×w¹'U¥í¸<(?~Ty¯|ðà {ãÝuQ¯¯;е <´¢ŠH®Ç#±.Ô:u¤Ýït%Y‹(–&5_äEè<ïô{TB‡²pþ¬ë(¦p¨³„ÿ–Ö-|VH&ÆZž,3MƒjD²¼3“ahy­hòC~†üñ¢áICm!Í]¬ ŠÅJe€ªUs¤ÝJ—b Ý µ[i·øy"ÙÈ×ÅAõÎDQÂô¦¶zÞV€õø‹å‹ƒÝ5éfñyÇw©£Å?$Ç ZÙi·/¢i¸º—è.~ë°?ì’0è ½õbq«åÝöZ¿²¶ÝXï›Z6?ô˜E9¾+ÌgžSœv$FAëÊ<®}a ÃÈ{ $_ÞuÀή‰¡)Y5ÓÝ碪Ã4$hR©BðQr³î&ñ9“°ÒÏëeHöÛ{ HW:Å.ʰ€D› Ö¨!1Å8¦wô°¯3ùYø øN‰²Ì“€ý{fBÄl9.¦Žo®Ž nÕ|婆©b0NûA9ÆV«¡-ºñâwv8<ÇíŠp]dZú¡´8TÛ2‘¥6Ô ´“×#fŠâ ൠiãÒH1Ì…çÚâ „üBp…„³ naƒ?¢ ŠYÛL‚í¤G¢He$$òÉP8F‘øñ¨ñŸ`ËÈæ,{S/h˺ü‡ö²úŸ'«“@pÏÂ]Œƒ{Œò:áÐܤdXnÑ©™ÅìW\=&Ȱ£ 2ƒL&@ÿ’¿9?ô½>ß& JJ(¡Ï1çS¦júûU™ML±Vˆ(›Yí) &Àajžo} ½FÑïCq£‡~ë!š‘íiùN’~aœ­0×Vibi[*æÉäclyª‡ù)H¿÷¯¯8Iyx±ãjq¿–_ íË$)k§_S’r†j¼™¡€›ê‘Tî’ÊŸNR”ê*rÄó  –ù‡õœV’V™Ãý''ìÏN¼£~)ù7õÆ®Š öUÍvà‹x#?Å7n–'Îk÷>ÒLÄY—ÒœµgÿŠ–dWä±Óà]~tF¯µÅKÇ®t|O=z2~wüï§hÔ0†åO’ùPÓgäì¡wΜ „WòåúôMU­/Ò親N$là¢åÔMÕ­seEôÝÓÜ:T ðèxÒ׸:Ø%}Sfä’Fôòxq1šuˇ‰™>iãfm·Ý/tÜ}§.¾9YSlÛ/µä%­.fÁûKoau¶@ÒÞŽ<Œÿ›4<Úlï(¯%ã:@yí0ˆTa  úñ'iú`/Ôúk4údûšš¡õm,Å/ŠÖ÷PTP¬£x„ÿ9Âz‚âû(ÞEñ ¤:ë(ª(~„â}OÙ$¿ÈÑçç÷cÏ{J]Bc§´)}J/j7õic¡°`æVV2…·WŒBÎ…ÜÈùÜ<ȹÞÏ®_PKIz)FBþ)ïr 4astropy_helpers/sphinx/ext/tests/test_automodsumm.pyÍUÁnÛ0 ½û+ˆö`§Ha»È!Ý:`@·Kw[WµéD- ’œÖ?*’c; –`À°âˆäããÓ“r w¼@a°„V”¨Á‡ë¢f­A¸¹ÿÆv5Bísà "Ü}ùxûíþ6ÕÆFo”ÔLgö荒èB•– ¤V¯ÂozZËkÓ¯s‹š> ÕûÂÔ¤6®’ب5¯ñ àÜŠ»FââR ¤ŸBRgMA­#ÁøÌ6x+¶‰|zÆÂβ蹸¸Ø}•ÅÆ@«häbKZËÅ )ŒÕma¡’¤Jke#K¦¸ï;*±‚<ç‚ÛÉÖ×sRÖ#¦Ï’ òèPçþGâYÈK_ÜŘš!­¢sHæ 'ÒÝ&á4Æ€ÎI[Û]gJ:E.!ä¤â³yÚÐu…4[ü bOw;ƒ3OðpÑÙµç88Ç-ËÓ–.¨wï½MªVn‹Ìµu—ýÖ¼¡ÏÖô9aPÅkiøÂw ®˜ChÂé”AòÿÐ'ûýPKu@,FKX椧5astropy_helpers/sphinx/ext/tests/test_automodsumm.pyc½WënUžÝµ7¶k'iC-–»‰§EP! !RÚ b©Âm7»ÇÎÆ{cÏqšHéÊ_ž¥Å€€™9^_Ò¤- ÙöNΞë\¾ùÎÄú«ÕØøãénã…Ï—øÈ§(Büô&mz„&„Ä&솫[T WCpP…І'áú8¿¿<ø±·a½ìmLzk^({›“Þ:„-è5 \†ÞWh ×„pz-/BoÂKܹBºÝo¯¡ÎÑßøÙ‰ l¶I(Qeò^§IJø$RÙdk¾¥Gj ›÷ü¡¸›NÜA+nÓ”WQ`ãQštl{¿mÒ„{(~¾Ë‚¡tF¹ã;zcG¤‡ŽJEéÀ ²Tªb(§ŸŽ?RY’…~9JH%yƒ€%}«ø|K{ßDq´ àÄ ÏÞùùüdÂcüYdà ˜pbÁ Œ_Zðu¼ÏÖî°r.Nö¡¾RE›¶Wîˆûì„á#¿HöÖåa›ÀB>@±7Šâpk/Œ¤ê$~ɣ͛7:Ÿn}vË»õÉ– ¶|4-˽}ç¢[Úþ-q¤¶Ø<–ÞØh9J’N~¬j¸·çEi¤<ï"VaÇ_1´’z8õáyªÁ/¸xÓ뿆Yàyn½Tv1j»”(­R]Û² uaŒŸÛt¢(þ†¾9C{zÓ#sü0Ž(?4ˆ~ÇšÌ!…ÌR$´º‡PèÚ‹s,ò*b²ó.Þ%»M‹6z}.Ø%Ylçù$Ðfèë§-,޵A‰ÜIA¯ƒRæès&þpFôjõ:~žÇQà«(K;ÛÓöC'Û;Ï5&uz¾*A¦˜Ì‰LÀÐ8h@˜eÃ*¢–âµ*Lî&“{ ;´ïަÑ"£B¾ÍSN@'w¦Z¶i»–½9F8³R”ö3Î|$¥á.9¹<\/Rôi-:E¤!k QºJ{‡LÉ !EªˆÝwè&c÷’Qç¯m<‚8ù ôr_{ötJ^"q™ôŸXÊšÈÿ³`Aæ‘&ÓÔü?F­=k”Küè¾¶°¬f¤À6gØféY¶áy»ÅHpxu8®,˜€Vpï7éÚ˜€šµº%w‰1n L~Ñht:ÎÌ¢n×yqÒDf‰nÞm4¶ÓÐÙîceÔâÆ¸_0* L}ß¾üŽ¥*ôâÇÝîô jlë©aä ?™íšè3³›§2of3/ŽR¡©m RQøJÌúŠŠ=šY ¤œ¯@á)x—Žr¾%«³ ΀Ùy+ßĀǓ佈e,»×ƒ ­¹ F2Åz aìt°§’ ‹´ Uĸþ„ Û MCªm~ßÀ»ˆ0¨‹TgJbç:A®ÌOêRi d8Ò>6A–Ésf¢ûz‰êƒ,JÿˆÊaE‹ýDòi2Ás0Þ =æ|Q—OÏG9Þ?"TË8²-%8º÷nQdE›™ŠˆZ%9Þ úX²±1ã÷ñþDgõ¦G±b»”ýtOèþ{¾ž’÷ª¹b´ð¹lÊgž8ô½Î Øk¤÷Gi@n›YwÏL±;g§ØÜf/H¤<Š3Cíçâ×<…_‹py~ùº'üòT,â·Zâ·ú’øåPŸ‹O÷Ú<>Ý7Ê%.qœûEfyŒ´àXígé‰îÛ4¸6?X‚Ð}—à²â=šFT=žB‘Îý`è„>‰Ê÷.îÆY™ÅœÖlpâÚ«“¤;Öµ.Æuì9NØ‘Šb©ÿ¯£ÅQ’g…Ê 9Œrž¯ëB.ç¹ÄÒÎ#Zq©@qÉV÷#t¡»×{Ÿqm÷¹ýl&UM³i6Ð -k½¾^[¿j·l«þŠ]³­PKYHáDœ´ìW¹F2astropy_helpers/sphinx/ext/tests/test_docscrape.pyí[ëŽã¶þï§ &$O5ê\²Iãf‚nw7i€ftƒöÇŒaÓmkGG—;Eߦ}…¾@_¬ç’©‹í¹(Šh,ñ\yxøñþ„ž1‘Y¥«IU.Ï~ƒFËe__³«ÉˆÁUDÛŠ]³˜'‹³bŠ‘ˆ 1ð²J#pœpÁBGÝÏD€bÎx4š³r[‰ã8·À"E#ý¤ŠËèžçï¥YžðØMŸٽNJ5Ð_¿ÏR÷žÐ-°cìmÎØ=+Q0òg&/&yA`þ¢B÷±‡¨\DËH„À%1ž†( éÒ@øÈüǵèå–åì[^´´9GÈ_‰Tä<Ž NÎX¶d%p•ÏÂ()ú¸ô©Vfl­Ö"guË‚Tùç<%t|9«/­ü„¹ï½1KCžç|G=ÃØ÷øF o‰6e{¼|Ÿ%¼\O&ú\îů.u5þõ>ïHAì}[Ô›ÚqÈ#¶Z®-‰Éž.eµ‰6‚R(&ßF÷úAµÉ–[‚§Å–'ÐÖcnâ¥ÞÝØcÉizzÇ z Ï…¢—Ž/EèQgnxp'BßXr¶Ø¥øqÇPñt%À¥ÏØïE}©y¬kìMËmžìƪÜT¥RšHµ¼÷cräŸ$‡Ôè$ìh>i9 C+„ØMµžV+d<²s†ÃœÍAÑïÈ£Š^Š_‘Ç´¾ïIÇ”ÕndsP`Ž­"íiÝ\k×w+%FÞuÈà¢|ÇæÈá&ò>Íd:'nàUË=Š FeȾ0€ÑQ¢jð´v)£¢„ÈDiN¾” Ñþbè tK)ŠRQò4KwIV6"‹OÝA˜R ‡6ЙæúZ}-!HAhÙ” ²(–=Í£B4 ñI•–àŽw@¦­ú%‚ zOþÊÐhð1ô¶Iò )"¸5U‡Û7´ÐV ¡76›xGнÏJaJù.-JÁCr7%½…ôʲŠc#ç©¡ ÓV¶©bŽ6×<ÛF ¥2èŸ4ˆ«P¨ q†s‰È£€[\Ü9|‘"³§é(1 !¢¢r§DŸ·_Qbê²YsŒ‰ô,+Pâ¼ÓÈ- ŸÆ;–¥*¾$ƒ±LÛ {%À¥TlØ€¿v,€˜]ÀÈ8j€ò!3ò,[ìØ&ÎÊRöEMXÈK~¶É0S‘å_ýµÌº×ìæÜ;ŸªG˜áÉÍ<òàÅÅùùtÊ>©u3ŒC#;8/°-N)»3á­l½pœqZ|u~~>öT›¸ôQ}(=gëŒK§ëˆŸ*ëGÅ:{pÇ:TÀ¼$'v"ÄÃ0E‡íéLJ¬fw“P,£4*…ÊK‘vy ¦—›‹){íÃpÜddüg ¾ˆb FTB¾ø *±)¤}(³‚ Œ‚fZ2ÃÏ;aWyÈDè{ìûà[H:gˆ ¨ßdɆ§ò¸øòË %þrÊþìÿÉgo«{ìÿÏþÀ§¡œ·þ·> ËïP/^BºH%ʘÐðN.S%ö¯Q,@ùËóó òÀ!Øë¸ÈìñZ@4z2Á´@ýC_ñ $Ÿ\Är­£ ²y'§½Ö°7BϽð.ǽ¡‡Ÿ:(·‡‚Ƚò®ÆšáU¶õiê€gð’Á—c†–Yg˜?`ˆm¨ó`–yÆÉɈ¢éÜÿäYµZãû‡(jò*JŽ3!Œ*q‘Åõ˜’Òqjp™»Å¡s dÔu̾"®¨éÍ$?§#ÙµQŠí¼H!${i’‹åª‚Œ£ÿÖœ… 2ÔÓB9äˆñ)xÌFÞ®­„_Å’æžY­RŽ w,‘0ŠÀÕ@Ü8ôKgêƒÁyY æta°ëŒ÷2i¨X4ðñt£N•$<ßõ*#_9S€õ–6vî_“]˜ ÙÒ–3ÐH„ûTy§Ú°A ·%iSOç-±H]’ÓLøÎtÌ®a)c6»I X¦ÞÌ›á4Ð!™"Ƀqçxh0|Òp¦ræãù ñÚjVî6‰!,p j:| ß™r5rwlíX®vm¿tvOY¢Ï©ßnÎ.ÉÇÄòŽáKJAGx´ ¤”_/úµK¨¼‹ìL¹³K~s>ìT Ù:s¶³"MÊA§(°¯|qyÈ–ºy×Ò@¶3hÚ±ÒYX´Iìmasg|0Â3:áMšØ~Øœ#ìh¯2´°º4EtÜ—›6w’BÏ=ÃM´¼©ÑMQÇŒ¢’£ç +Ö4rêÓ®ÁU]}¿G;‹ÀV‘ J+wËXéÏÙ*Ž:raÎîl´·ÅÒ|m‰¥Y»O&½èM³#“˜œ°^¿*s$ö·¸q4.¨[“F<³EÌÓ»Y¥b¶ØÉ¿"I˜å¹·ÐŠÂ@ÐÅ;&3XŒ¸\úaÑój1®©nb?DZ¶qÇ”)c*NøÅð¯ëܦΘEKûªÍ´æÙK¸8@(s1­`ZÏ€®“ÆFK`Ô\±¸I§ÍK¼r\å²×äJÈ´¶uOþí öiÜz^À2g 7a'}ïur›"Þû´¸M¿úê+ú{Â>=LçJs¯¼øüââóJ‹º°¨{¢[T|^Iñ9Ån9ñeЉG”ۅħ–‡‹ˆb§€Ø-(ªÒ¡"ï” Í¢¡,Z Ír¡],¬K…µjƒeºJQ7c‰b>ó wÑbº£BÅ|6ÍëR|£yÁ*WÈ’£äóôrãžbãË”_¶ÐøeÆ¡"c§Äø’ÆG–ŸV\|Ò¢QX4ÊŠÆÀ{¹’⣠Š/[N(&Ö5ÀÚâNýo¨ú÷˜Ú_·ògÔý^¢ê×[ó;¾âg×ûz«}ªõô³Ky´#n¢HõD[;èM5ðH¼Ù0“°³ß‚XÇG–*ÿ߱礙mF<=E…OOÛØ³^3ëÚ¥õâ~¥]Û\…PÿÓú„ÓìˆCx{F!6SW+œ(ü¶‘ɦÜqþà³¾´=%Ý_ ë.9ùˆÀéðB[¡Çûc”¾ŽWï¶Ø¨#ÀuÐJc¡Ûp½‡S¾;úh`slOûl ±H…éØr§·i³f`·úÕ#•µvîSˆMoæ5Û»F³Ö.56¥@hY×ÙÉ•Ûû½¶âù‰Z[ÄkÃÊ’CêªZ ©jxpXMéOK5€-3ÄZ;öùàøp$“’«È0ŽY'¸þšqy l¶PƒæUi¯  üS3¸¤¤jS/ó©•Эä:…N‘e÷"¯#…®bU¢hd,•Ø_ i‰|gë¹zþÑkÚÞhxÁöáfö“DÓçòÉœþÌ>Î'@±à ­þ*CµÛÕŸß8ÚUº·/ëíK”/x0[ÆB*±h¬ÍLr4réeÇcònQßõÝÒñz÷åÛUÝn]ß}¬ïîð®ö†3¶wM¥‰..ÛPùq³®®8Ñj*›uLÁ V:ô‘I§Pv†Nt 1&ƒFÍý< Í ÕÁP+ç ±ª+ šÁ÷Øö‹koß(QGŠº&4#ç(¶­a…Ým¦AA{}ÕH¡‘BñDƒ¤7ÿÌ÷é,DŒh'ÉÎ…¾Ai„ÎCxY¹/+ÿàeç ûq 3‹µÎeík•  ›:ìÕhà UåÅ!“J#ä¸(1~Þ„æÉM¡àŒÍs&®3Á‡*gq\¼ßs3@aS ¶Q} MVaÍ áÁý­¶3y<—›…ÀR¨u¥^䲌r¸Ç–]Ìòžó›µ@Ǫg§Y¡{ÛelÝ=ƒ¨uµøêŸv5“bOu\³ý÷¿þýÖÿÿ”ÿF}ïñÓx»)![B˜ü«½K|þeâK‹¼E+×´’U3Wý€Á¥Y ÜΉZ»ïôì¹<»4ìó8&:§±‚å O”nUjS\ã"OMû;Â8HÞJ¸°T¿Lx‰lãháovxÆ`-£nWW?`Ù|é]Áòù3ï•÷ùtlµP•åC.ãSÙÜÎ6õ=JÂò®[ˆÐäþE ´@ëÐà6½Mñ/µöMäLä&ÏuÍ‘Z—囵…@¦ï3ЗýL§kˆÕ“¨Ü‘¬~Åñµ,´ù«ø¹ÿ嫯9Ò·ß­Ò,ǪX׿ŠuœQÅ[{X¥XtA"öšQc× .‰ê_Ú¶ykH’±.õcV4ä1äìð¸þ°7¨R«ïfaáÐ~5¶\`ÞÄ]—’c?žlý$*Ý—O µûùOö1å×=.~‚{ïÚ'ºõ8f¥-ZÙ‹[È«¼*3,†“·¦ÿ>˜êÔV›‹Å¢û››O ñ©—Lÿʾ)[ ‚*gÂ_áŽ;«hwÇcjcP±@³pÃ%`‰Ö<Š„ñ0D'd›ãv—€¶· ´^±{Q5³=»Œßæ>mÏl,ƒn‚–COòŠãv¸kzZX[n{‹‡–®(oÚ¡Ýá1 VôG_µŠWÊ%Ëwì0´PŠŸ×ñüJfèô˜Ô=~*«cÇ[Õª*€OñìSçž:_:sË;b ëÊðP—4â°Ðí«q³#Y‚’ÐKÜëz+ÁŠd'¯¸78ÐAÖ Ze«˜æ}»uËV±SöË;¥²ÕYö—w¬ˆŠá!—íâc˜]»¹Ãž¬ÎJc°âc²c!à~›:âŠe½Ä›@KÕ·›[²k¤fmeAÆ^ÜíÅH¨"À*_)"k<î…~ŠHH¨^B²–¼ë«y”XŽe7›A耴Bvؤ6Ð×£²½¾MS@T*•Áè  Ö&°‰µ\…iU]AŸ×€Wbä¼›08€C˜…k{¸æ–·©Muc“z¬fÐ#û¡Å(çF+rÀêˆ4(Õ!aUÄÀ!. —¢Cœ ¼í"D ÙÒöÐ zQ¦X6oÐŒ&,M )@¡.P P½^”%0) Ú] €j®'(m»O:Ä’ž:.C35««A‡[œ  ä;ÅI,j§›Ü”E²dÓ Cöh€µeE F·ë °+AÌÓ£¼æG1·B7 ½±P¥Õó¼”Ì“K·luƒnϳqÐkô݉2 ßôz—bÅ‚”‡nÓÎôRÜ„Á!BzÊ•Ž#ºp”äP%ÙÏšk·I0v³e#Oø+>o7›­Üä©7°_ò—è $Ä6ŒÝæ€ÇXs€- FmÏ6`ep\5Ðòf’³Vc`u½ Ž-´4±;¶WºJ*šù /¼ ¤îóÖµÕòê†,Bñ%×ÎBQ^œ]]ÝØ°Ó°¥&‡(Æî`à¾`õqK¬ØÀÞj€~y½MÜq[|fuuµTyK6èzqÁ/BËòéþéÒ³T„}Oóë=ÛSEÑVp³XR¬ø³cBâ'Àð°LaƒŽ@& Ö49 ‡·\ß¹”-rèbdŸ‚íåÚÙ ëb–c7è([§Þ ƒ†Ýp=`‰2¬(ßyñ6Ñ"F»M`‚Øm&Û4ƒ`ù•OYçCÇâN¥l½Þ|„ÎÊ«.0õ¥ Óµ}û8û­o•ß۰j•7*ÖZϱËÖ›•ËëU;ŒÅ8k•W*8X¸ƒpÙ1ˆ ß"%Ô„&-€ò©„s¾ö×ãü¹ÕÕ³„«œ[½(Ȯ׸±,,lk ¶"~è@ø„Ü‹lËíb7—Ŷ7´ìS¬W<[>WËz˜*¦ì߉ŠçËçKªRÀ­~…¶(ƒ—üž+)m¨x^på,±.aö`rb3"nZ­\À aÐkoáû›n“ËÍ+ŠmÜ aUñ.ÍX¯)1:n E«ØÇ¥{ H„µd=G½"¤×Þ¢ñ0Ý(Òº¾ÃûUÀ"± R5ä­v$Ž*~6½ gÈÒ6ªr¤ß¤mUR­/Õôê£ÛÚ5`.EGYl²ïúEMS|qN¾pÐl˜!5Þ«nÛ·acâÑ1xš¬ïF¤ãkí–zˆQË:¦w10k„Ú+éöa„8ÚpÈZà¾Cïmþ‹¶Q*Ô,oá€;3Ž£(}!A)à“Ð*°w2‹V°õ µ³ô²šFí¡͘«½NÇdgFh¦Ì÷ÿàC…)­žZC‹©†×ÐD¬íÏ ë‹ÆØ¢Æ˜þw|ƒ¯G„Û"œÈå~ \»V7A2Áš!{%ÓÃÆƒ \­Ðò1ŽkZ)³òò7)`‹#^nÓÒÜ1YtB⤭߭m<ÈÞË1`Ê[þ‚•ü¾É®Ÿ–ÇIÀ^í5}G±Ÿhç̱£ØÎd· aæðì+þެøá ž æ‰ :Ô¼t ð·þ©é_§I¶—¸×u¢žÒYDŒÄD™G‹˜7Æy“HvéðÉ”µÂ‘@ô ïá´ Üÿŵ€œ—¶é ãq_pÀ’bƒ"ŽIg>¥uªg‡m’3𿺜@uxÔœ ¯,)^éj„}‚#.—œ0ž52(¡“á—ì ¿´ jôCtžå”YªøAŠS¤4›#Nù4Íózé+DmB1î DãeŸ0LxØî`¥YwT¯î,mk¸ÕŽc‚ÕNbòðÔ—=©@)‚þ Ž[}Æ@‚9s,uâõ?w!§¢LNPFÐÒ¤²ªxYQÆP´RËÿC)¢U7õb^ЪÇ04X~t°uýãÔ`{¨äoG[¤>ÿyt°½ôâ¿Ò³Oïò´J ŽÀX§·R8\9oÛ#2FÆ6wÍ”‰7 n†­ôèʃ &¸à´1,(öÜÜ—Ä}z ÐF?ÄáK¦C–C)rÔT9½)k\g÷£ÄÀ’–ï‘uçˆ%Þ $õÉ–”ÅBiÊ ÚåIöJÛË}@/ì1Ú ‘`z›zAá×Gðÿ›#ìž«âìšJX %¡ P±)â(•ŠÀ¢‡ì´¯€¨7³Pü—쎚஡ wpe^ $!cƒ–`‰l«¯–ö2­ x4G“¦#t»c(¤AfzቭàÂÈ;@\êýÛò} ˆ 28iM´A«¦YX”$Ž ËÊMéØK_âr$ ’,Çc îš,Îh^áðW‡Û¤ü"néGƒI]‚WÛ&9œ ¶¶ñ0íx&¶» ³®P~ó¨ÑÏçwôÝÁÍ·;N¾Ýuñ톃o’{oĹ·›®½ÏèØû|n½]pê¥\z)‡^jáíž3ï3»òvב7Á§½ozÆ#ž·I~·Ïâuõ¹¥Æ´/¶Íˆo§}©Ân²(nïI4>=eî=®×éÆƒ‘°Ä¿K1ë³ÚÔ<ý¶F¥º’ºbYßuý‹^ûr¿É»òn˜*ãÀÊx^€*£”mêÎHrŸC(ÎÙK#ԅϹC÷Ùä ÈÄL½Yrï1S&EMŠX¸õÑèLÅì)–H¯ ‡&¡È;ñQöŒ`éƒ\±kS‹Ú£ø"¤¹ýòÁñÁ‰ QjSÃ8z’‰MRGpSlBÁBšE×^g*ä—Ê®085Äêè4óèvø(^‘æ{^ß5”\‘s¨€²ü¶!yT”Xê/òÝÚÆÃ¢Ù‘šw„í̱ð}Dðb´-›ø‹ø¬±^û ÿB;÷Rÿÿ¢*¿E(¼7ü+ª°/[áªÜ"\]î(ƒ°‘¤¢§0ð¦£\騴ˆó:CýJ­e’Z¹¥¼yÂ8f䌼±ß\4 ùg€§#;z¿ÐAê× 5m-Ú+>b õ®PPoÓö Âj>4äí…Û†q›äl°¶A˜E¯¡“âûV*K®©’yUÒQ%¸Þô²Î@«q¸•¼„`!Õ9ïé€úë&P–tÚè•ö3"FDèxÈ7Õ¢ÏÀYßv– °$϶v’#_ýUõ:ªõ:í.õz'pz>ÎÓ#šÌõ©©”5Ð~ÙASªÞs sF#s;8*2o§!E•'–©çÆ&éI$j†1D¤IWv6Å™"7c²Hj3ÙM᩽ǦøÍñÁáS§ƒ¦¾¾qxOÖ\Gä,MÔµ i‰›oxØq°9’>©Sýûº6UÃÀvaé!·$ã%ú&Ìå_îí(2FZnyœû²™½¥„ ÍýK)ž·é7íª|X-܉Ç&TQ°ÎÜTç«Oü@\SÛ¬2Þ0ã¥}…MRQ¯ÆDÐsJRà¥ÞHûRZRÀ}ôs…ž_þô—6ô÷çâ§0î=¦©·w>“5AìA#øÑŒLýü4mgšµ•u[Ñ•h›ð4šá“§’:LDæwÁóÊ&ä'v§/‰Ù;-З3äwÔî^4Ý:Ŭôîù矧D~äø10 1mi ·"¿ZEɯ¥ÉŒ:®ûx#ß[þWžƒæäž‹‰Ö€œ]û=&ïœ|Ì|r"3Ë(¹_exúÑây&âêõV7¿z½†ok·>ïˆQíi&C‹ôˆb ŸQ+;ÞŸ~)‡)t™Utì¹_wýV Ì1·ß«]THªa Q ïkx¬\C›°v  ©ª¡Ï«†K íkç5ª¿É%LÖ0AË´ö2&¯bò&$âÞÀgYkaâaÒÁÄÇ$Àcµ>&aò±&ìïcò ›¢Z,¾—[¸”^ ³ #=N˜GÌÆaó ±hæ;sÆb.??¹|>?Ÿß—Ÿ¥§Ù|!ïçoA¡™Ïåf Éå(¿Ò9øYÎå?”(_Ê—æÌüãÿPK1`!E8âf®ã.astropy_helpers/sphinx/ext/tests/test_utils.py½“1oÜ0 …wý "|®Blܱs‡.E:›Ž•“IW”“Ü¿/%û.ç :ÕƒÙOŸè[r#viž‚ Ä;è9Bï©kFî>< ƒOÐ:‚Á½ 8 ¦O[@5s@cü8qL '1}äZÛä™ÖoïÅ.òé”P’YŽX;'.ò ‚1ßÞCýí FQ߯SÏŸák ÷fq]<ªjÙØ¼³rô“ïw7zþæÎÓaùk³ñßÝ}1 O QöÐÿ"]Këõ–cW9I‘§S3`˜¤RÏ|ðÒà/ì9M×'ŒúVó:°¦¦ið”r*º9AbÝA戫Ë6øIKaTå⫦Ku`ÒàW*çÖ²ØÎdϳèí ØËÝ®*›SÐÐ-°BfROO£”ºÓaØç»=ÃÉÀsè¨:»¥Á%娤´É”[Ê.EîDP™r¢P×ððhþ-á¢ÊÏǨ­Ljþfñ-v)kS†¦Ú—òe&¥þ¦ ®³b\O:Á2Rÿ çGœ•æ ¦z§©ô_J)ƒl4Wýƒ>#ÿ¥ÁUQšü PKu@,F´f~ì&/astropy_helpers/sphinx/ext/tests/test_utils.pycµRËn1=öLMÒRà"¡Î€  „@,+Ý!…$ã¤ÎxŒ”HɆ²åø|P®=•´kfÆGß{ï9¶÷g¿uuêŸO°}8W4ôœ ¢AƒrΡŽÛÆ< ’50ÌëˆjxÕÓZÂü‰ù¢.-DM|'æ¶¥ùÐÛ£íä=g=FSÓ"HG‰ˆÌ"WBÚ¶ÊÀ>ÁT¦Ñ0É¢a6žkiÛ–žYx÷ñ؉ñ·ãÔŠùm£®aÚû“‡ °aØp+‰„ª‡50b} Ãñ¹'˜/û·ÐøXsÄuèÏ·’k7“É "Ð?¶ÉäËš¹•ŸUyIH+¿ª/ êüÌÜ!iSdùjx!T. íÌÒn_Ètˆ¥ ŒÐF;.ŒTÚÙš¥j¥²ÉHé¾5Jß'˜dJ‰‰‘YªƒkÛ{u õ­í}çïÁk­EaßEVVà-Q Çe¬ãçÅBôüêO¥‰v“é—´œØCs|=T ßŒREá8’ÚÉh’éåÑ“ÇÁ³£åó“áÉÓPÌfá ©a)5$©¡“^K ò•éÚ&ìÊÎ…9¨DƒÝó;~—{ìwȺôö:ÕUÒ+mÚ»æ”*­-DOÌN¿ÛÏÙdlíW{:Y:”é4ëóʇdTÄ®PÇ2—Sw%‡ôÛ;~üOSšÄú‚¼X(ñÒ©´=wØ!ïðC~—u½¿PKYHáDaŒÅC@-astropy_helpers/sphinx/local/python3links.invSV.ÈÈÌ«PÈÌ+KÍ+É/ªT(K-*ÎÌÏS0âRV(ÊÏJM.±R¨,ÉÈÏŠ„Ad­ŒõL€ÜŒT…¢ÔÜÄ̼”Ô"…ü4…’ŒÌb…´ÌœT œŸ[P”Z\œš¢PZœ™—®P•“™¤ÇU1géă|Mastropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.html³É0¶ ILÊIUÈOSpÎÏ+IÍ+)¶ÑŠrUW+”ä'—¥¦jä&V¤¤”dØêê(”d–ä¤ÇççåTÚ–•¦j*ÔÖrqPKYHáDêžêuãh ;astropy_helpers/sphinx/themes/bootstrap-astropy/layout.html•WÛnã6}^Å@AV ’H¹}ØØ*¶Y -Ð ¤}* ’(‹JTI*Ž‘øß;¼XÛɦOÉáÌ™37úù蓦M¡ ȈbyÌÉZt:ªtÍ8ÞÌfÏGp'8'­b§ XA3"Aå’µJ)j(hI:®Çw5pßV¬y‚£ÍìùÕþNZ2N,¦Ë3ø;L•&1xÑ7þ³Åð¹(@W–B,ÆŠf¥h´‚†Ò‚P i¹X o1ã"0îIRQREsΚ¨$-a¥u«>űU9µ¤e*ÊEçJýX’šñõâ^t2§g÷¤Qg_¥øt}yyþÃåe’òE¨ôÑW”êôº¥‹P£Es?L VB#4Ð:£…Áy¼™{æ¬t`¥¿‘GâvP2_ÏÏÐ]iqÒs’‹vuZ‹ÆÐrW§°ÙÉùŒ¿¦ÑöÀÌz/Þ£€ZCLÓÚv¸!¼ÕŽàŸ MN-ÎLàP¬½Òh2ûÝÞµ¡w nÑ”˜^~"úO_Anå†b»Ýl;Î/¶µ5ªCZ0Š&]2]uYïÇ( v$|nNwSCsZcà¯1|l2ÕÞÎFAhõÖ1ÃW©²À¡ Qã¥ûlHM^VLÅ!>Ɔ+ç eGO]æúXÚ·OЈ†bøNûÕ€vÏ%ßjI²{ìNâ(H~" -àOѺùÓ:â“=?ÍKÈF`‡t«þ$ìÏD/NàÎúºØ:<<‡~±è¿^ ]Íòv0¿»­¤ž Ð6›È圳‹E’ÉxÄWtÜw ôÖþŸ¥Ýty=Üs}•ÛN©T8CÓ¥Åw'©™¼Ð)Ö,¦üÃÈ]ˆZ‘ a^Fq¸?[Ò¦÷ýyO˜.švmaqìz0>\Œýo¦gã–׉¢}(¯rkóu»ž‘ÌvgÇPKYHáDK±ñÅ#"=astropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.html³É0¶ HLOUpÎÏ+IÍ+)¶ÑŠpUW+”ä'+ÔÖrqPKYHáD`¿Âƒ«>astropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.html…Í‚0„ï<ź A† ¼„`6íB ÐbYTBxw‹^'óÍdfIÐT0PÍŽz†™‚¶éš•=–Æ;…ËbÅï³—';Àº"ô,Ö…5 – @Ѹay`…ÂwAØÂ^†Ž4[ß Oï¦ü‡²1ì>œ¶¬ÛsËóÍ3"\©›¢<óøŸ¥Àô% W4uò¤Š|W&K¼€‰/ÄÁPKYHáDuâÄ5‰À:astropy_helpers/sphinx/themes/bootstrap-astropy/theme.conf=ŒÁ Â0 †ïyŠ€gõ&xP_@˜·1¤na-lMh®ooWpÇÿË÷e‡7µÄÏŒæi&ü8¥9âëÌ(áÙŠáMmµ:ÑS †×5=¨å‰ÔUôOöný-ùЫ‚äq¦hú®nÑT|ˆ @Ëb£v0ñÈF‹˵¦9"y›ç2/÷ ?PKYHáDŠrYº½Mastropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.pngu•i8›‰ÇßÈ ):¨Z¦¶T©%¨ˆ[Œ-TtPµu¼– MR!®´W)3˜¶t j‰}‚©)µFTMß.c›ÖV*¤4]ps ¦¦ÑäÆÇûážóüÏïyþÏó?Ϲvšè­¶_w?j@9#äÒܧ$Ÿï±n†r(Åøy{²½®ék,”;ˆ$//†œ0`¯4ÒH”=“î&7Õ¦÷s?ƾ¸g¦ÑÝäŒÜ[ ¸¢ëÆ@ñ>ÁÃ-8ôÙB)¹ *H§ÿÊhéìñÙóù‡ã½~Uq÷Ñ»06ҜהqÍ*œ£ë#­Ó0å¼V"熘ð‚‹Ã¿º»¿K‹@.›=S×Ðt ¹¹ÃvîÞªØ=ƒEJà½ÀYOõ¢ìêd«Ëª?7ß™ó¤g‰4—Øa;zvø¼Uc·å³w&iµýá…a…«4¼¨ÏŒ…R~M©Msl|q'„”…L1hvó­}aŽ¿·è¯u+ þ­„µ¹Nƒ¶[N,æddOÅ%üäÒ_z¾‘(|b}¢Ñšn1›¦Þ«ýÅ¢ŠÙóu:øzNwæØ#%Ëv¼Ö}ØŠFQ®Ó–3„póÄ=аõ®aHò“ìtêšÚeŸ4m,Ûí³Õ°>?O¼øIºf5øá%êg‰Í[5zÛþðä_zñó‚QÄêUÊnæ×l—£“¶Ï[Fi«¤ö°¬ÏhûóGÙÊÔ{Ù  ´· …Öt'âse,~PöÛ^ÈžîPÆÏß<¯ê¯FônDÒßå•êšJÂŦäìжvV¶h+[l°çàˆ³·?Ž¶Ã¡Ñuô¨øÿ Ð’âÈñ—þà•ÕÒ¬6Úzƒ¡Ü¸Å ?î~BбÚ寓äÀ Õ„[_â§Ùëe1T"§‚) •8x` JC¹Ãê*WŠ"7_ú”èÜo”¥8ÝÎ&I"ä’^Ø Ö8¢À©_æB¸]y ‚G,Ævã# TÈxöâ?ÿÂø•ÈœM¢9„º„£çÉ¡1Êžý’°šéED‚G¥.k‹À¯”àÞjÖXôÝ~ÊݹªJXö<õÖmj"©úÍ5êôM¦tyš®`•r'g;ËQEøÏ²oÌÓú’LÅšºIœ¥ú¦·^¥QVOÎÿA½| Ø9±£°°CF³_¤Ætõäý¯¦SécoRw¤^´üC¨ù;,FCº6vZ O˲ùVâ%Ϊ§.­Ðíí!‹öQ—ãÔóW3q’.óš0Γ¢—¦És“txN4÷¶†šØŠ—E¿ÿ‰îì¤Õ_#:q=ÃIÉøõóo­sÆ·Î\ §æŒ_+¼ÎႨհW–kû33ßÓk1Eíìì3N“è̯ԑïl½[ôìUòÒ¬ñ_ 5[ZlQû6‹~4ÁD*ÈȲúµö3êÌ-êµ¤Íøæó×]òÐ9ãï³·XïÛì¼Ãr¿w­¡ûñwj’äŠXnP‹;¨ëS'lŽ·ÿ& ˆàmËßÎï0ÿ(á½Ï:?FA»ÕßÎD^'%;Fz­¶o!¿šÉœ¯ã"ãh¥†bG¯û%Å ¼n[wé® G¼U|¨´½ä¢ÉÚ1Mž¾F÷Æ×”ÜÓ¶y¿‹¥fÙ8hˆ1@ŸíO°}üÔà"ìÌä3v¯V¥zy\èåúYŒAó=NGÓy ÇÔGz8ië3ZˆÓÚ`ˆ¡_»sõÀÚ/t3Þ3Ûz–ßC'Ѫó-}Èà§üObÿ¢ÚlÆ:óäÿPKYHáDæòwa\Jastropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.png\£ø‰PNG  IHDR szzôsBIT|dˆ pHYsÓÇòŽtEXtSoftwarewww.inkscape.org›î<ÙIDATX…Å—PT×Ç?÷ñc‘P° ˆ „FƒUBìȘ&Ådi”I# ±ÒÄJhC2æÇŒ5ÑÔtw:íÛª5ÑÒSÒÆª©é„Ú¡%¨ZÉF2Vk­JFŒ`ÁŠ(JdÙ÷öÝþqaß., É?½3gæ½sÏïýžûΞº®óÿ\Ñ_ÄÉ•ìÎ#šÅHŠl ø2pèZ€Ý8ØãéÔ¯KL”Wš;†AC°È‹h4¥z>ÕÀ$?ñôé—#¹hJ~‹»œ›´`;&y˜#D²ËÂß b0¨Â¤Åu‹»2RìqKàJr'âã7˜<6.´;`Îã2Ò‹@‹†Ž&°Ìa‹$`›+Æâ1ôWB]Ç, w.rÆM¶|»r€Þh?G6B—m"ù‘GêÕïKàƒ…“œ0º#Ñ&¢: WBÅaˆË°mL6¸pÏ€+àΔƒx¥Áti@D1Çä;«áz§ v³ú7zCýrׇóE9ÎÐäš ‹,“é_Gÿ±hbÞˆy•ˆ;¾Ñ Ðñ!,e÷ÙUÄ—¦AÚlˆO†„©ˆ€-^;V€¬…~ï;MçÅðKxUZùK%:Lü剜"¸ë9äžáT½rÝë†3WCúWaá8úè9ô³`p4XW·;KšxBjó«ËwÙÉ¥„Ö÷á“ýÐÚׇ.WêLDå_e5Êw`ÎDîzFíG;ßz9ì¾?@ÈghI^Ž ÄâUˆ¥›Ô³áƒÆMÈl…+çíãÇÄs%bñZˆK„»Ÿ‚Ão@ûÅ`ó!8¹ò—À¬o‚)Ô!ÔÊpu¹4W›;Uü0ˆ0×i'÷Ý@V— ë\Ð}>üÖßôÁž Èu Àôƒˆï¾ ¦übdëÇ‘‰Yáþ>rµ¡z—c0iØI,\1D‹‰ÜX §)‡Ìùׇˆ×üˆ__…Šm cáB3ì߬|f̃¹ÙI.œ²KŸ;ò“NÖ¤AqÐ!~*Üùr8Þg)ã¬BÄß…¬;!*â'#î©DÔôÁürdÓN;Ql’ à|(€Ùá Xôj®€[Ã`aPy÷ã* ÷ר—¦Ô¥h¹bâO½¶Î 9el¢­ïë 0HÆi¦a29HáReÜÝ 5*Ã@ä)}豄 ¢cU5ö»aÙIr mý0›Jú€nARÂPÊør‡j­&5â“+Þðçõ£AL:éµKðAƒÍ\îÿ´ž eà'_Œ໩âlg'ò›Èm/!7|ü¾p7z‘¯T@ß5å—0 KÕÞ¹Àg†öƒ ú@/fHN|ׯ@b bÁÃÈú8X‹lü,yf} ºÚ ®ú•ˆU; )U1·o»bSµ j€~Ú¦‚aS2!&A”8¼/‡‚û ¿Ž7ªhu¯Ž.@ùó0¿D=¿_oo nIøý/© Ió”è70è¦FÞ§¬&%ÀýÁ¶,Ô*}t â—ƒ{Ë#ÿ$'Ï@ütbÅËʾç?ÈuO„Ú j&Á¡DèºÎK î-T㎉E4| )épá,ò;·Ûí³ôˆµ¿…¨!ÊÎ7ÿ¼Èö3ˆiÙ0ý6X°“Ô¾¹ò8önðôB°ÚSjOEÑšÅNi 0ýÈÚ-ˆg<0c&”T@Ãe]· ùßKˆ» .²ó ;©Þzäæç¡³-Tû³™R[åt:iºÝy±è„·‹,, å4âÑçÝEBÛY8{Z5˜öðîFô÷A¬¦¤ƒÐK]àä?‘úÓð»upíjèLñ©,ñ<«÷…" ^?aReÁ ÀAO/¬YŽØü–±áHKCî}K7ÿÙ¼V='N†´ èhß@$.:4Á}žr½säFp"jÊw^ùÆqo?%Š…føä$¢äâþ2HÍ€÷€°O6àƒžËà75E)iנس\o™FÌ„ë*õj¬þ”î{YU†¬¢üI´¿…ܹ㠦!bò¦¦Qà©Ð[Ç¢&âX¾¶Æ])àWHTÿ]º í…ŸAÖ­Ê`Їu×W ëâXq;¤dÍúgõÚ± "20¼Ö¯Ð·k·að:µobÝ3¹u‹2pÄ!}rô¸nÒ,TjÝäN$9Là¿¡k“{rÀâAMP*a¦Öri.©išÜ[ï—ËÊÎ h“Ш™ì÷¼¨7O$éç0 Ë•Lg§$3ó3Çãÿ¼ G®ÿ.Á½8<ßÇIEND®B`‚PK*xbEeß5—æ 8-Lastropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.cssµksÛ6ò»~šL.V‡¤)Jrle:siÚ\3×ö:ÏÜ}Ë@$(òL´¬xüßoñ"”:•SÄc±»Ø7pþýw3ô=ú‘RÖ°Wèv¬‚Úxó{Zë|—1…‹º>䌑ÚC˘wÿšÇ¤lH‚Ú2!5bAï*ÃCõ ÛHÀBcÕæüüp8XŒh½;/䍿ü×ïþýÓÏ~Ô­ü Á·yqD{šäiKlèŸÇ‚ q½Åõ¥T-hÓ?ŽèšþÄL´·°2 š¡OU–—w<ŸÍþžï+Z3ÔÖÅÙ‹-nò8ˆ›æÅüíl¶¥ÉÝÏÚâøfWS ÇiAë z™ŠÏ[èÜãz——ò—”–ÌOñÜ ¿â–°<ÆèwÒ’ê<ô®Îqá¡—ß:O»éMþ…lÐbYÝuMÂÙ½A%­÷¸àÍE^?SÍ‹K9V#· ù÷íìa6;¦+RÃø›ùÏüp†aÁ½T^\%|qF˜Ö˜å´äÈ–d„j^f@,QÖµÎx“Ñ[{Õò;×bÆÑ_+º©ÍŽß„àláe‘—-½låek/»°Ó¼6!xCö(äßñNk²çxf ÅØðh%7Ñ'†-ä°؈ƒí'/$|5‰Å–ÖÀ%K£{è¯îPC‹<1…%[“‚=«QÏ…êYzVªçbÔ£DZì ˜•²µdÚ 4ÆÜÀjjÚ×h‚äƒÏhŒ´š4®$–³”bM5¢ )Sê\á$ÉËÝFî&ŠÖrR[ > TÎVÖ‚£W Õ”{ld10Y”äMÌ»¨£‹Ä¹ ïaVäª÷IúÞA[ ɨÖÇ!™³Ä‰·Þ|èM˜‡ø#™ÂEŽJÆlTlÎj£ „öø¹¸’tHáÜ<&©„ ᦽÜR"É›²,[Z$|hÂh Ãàl¦mÑ”íz˜û–)ëMئü+ X’Ô¤iD7ìrU`ðÛ‚Æ7 ì÷1Mˆ‡ªšX†8‚N ÈÐ ísö´¤ øR±Ó@Ñö&g¾bi“¼m6Hé“¿§_&º\­3Æz:Ö“Øš<©w[|zHý Þ¬ç–Vñ½U°5‰cvu£/ƒõÀBrºt™ÃK[® J’ÄÝ3ÄuÍ¿9 :d9#¾`؆o««Í?€ïB¼7j‚o|Þ ,ßï,}ºâê¤Ý7ª˜´rž ±'"ìÁH„0ú’rå!rKJ e¤†Óþ”‘)KùXÉÇZ>.Ä8ì!©WŠ®ðî’5^<©óD¢ÃCIMý Qˆ5kÔˆxv¬v£†µi*ùÜÕ$õ€ó|axMH—@W÷¸ixËP¿Ò@Úr,-øN5)0·I#Ø~ƒûC4?+¼#§@Ó´[ O 0â‘pà®I9msg vRÄ7îh¿ˆ€« xýIÍóæ+ßóT O!¶¡ÕYøª[enuÀÖ½ê×}dág!OŸ5ýésÓ¼`Ü‚U5ÝåÉæ§ÿ~ä®uzü–Ç5mhÊ‚X¶‚½çLXò‡× ìkp,eb4ËE ùj"$–ä‡pÞY ¥b8ØÂjÉ88zý‰¶uLÐ'À…—"^ŸÈ÷£ ;¦ï –e½Š7™l§åšÃåâ­3œÒ¶`©\}^qŽ¸Í‡ÿ++ÔR±¼?ÖpË È æñyuü\Ðý¼Œ‚ªÜ½˜~J«…™@*Gœ½ä£81<6ß#Ó (â#I»É£µ0Dý¼åÔ<{ËäŽÉ:¤6}äiqá £{½¼QŠpX/·]ÁO´^{¨ÿáz$;*/´ÞEøJêJß§Q’ª7©“aÂmÆé\…· Q‚O’‚8€Õ$êŽjW¯ü8uB+`ò„e\˜¢Ç(ŒÂ)XK+ðtU‡5iË>G¡[Û×cÚ¹ihšlÕ’b&x]þÑ-"„Ío‰iýqQeøŒòÈ‹Á”Ù› T30£KÚì&óÍÆ3/«v2KX­V_£þËù(]V‰¸¯Y.B×Ëì”ØÚ`Ft5åoNÒ RxG*¸X,N$Ì«é„yåL˜õ„$XNè[}™ p‡5Ê4!äQé‹îÑI:> ì¿ eÅ¡¹mÕ9îŽÆÝNÍ㶇‘RlÄb`Rb’Aº7°`ä‚ó6šñúg œôɽñª^J¾Á±n é^c… ¢=íªv+ž.fž:9!c¨eFgàÆ «Pj™kíõ]úªzáHè&tà‘ñO –”ç¶ÿæš–¢2qÆ+YI\·ûm#j1·*êù“r_Ûê"ƽA裑Î÷i×mz”>;¶ócW†lv¡ì¦Ã†)™y¬0±ÝnµÌjît±e?HµG(DÏß®þJp÷ΰ£;£ÒE4Œ?d£>@›(Ö(‚ƒª- _GßÏÆA¯…e(ÈÌpCQ,§Â¨ÉòÜRŒSYÔGq¾qÎ0U/vJƒ8™(È*®Œ—çuäŠÔ#‰P.g¦Ù¨gKWMîõuM¶mœgûíÓ(·µ%?XIþOãYa¿’K„ÇŸòTÕùêÙ˜/¿s-¶6Î.Ü*‘ó:Ú¹w)ô’ ¾Wš…J†Æó;½ïôü1Ž:7½-†T`ÑÁèóSŸ+ãL“+ÔÇ5=À¢½+èèú_ïÑ£1« ™{3”Š!q[‹äB«“,v±¥×ap©õÚ l%4x¥1ξMà–,9˜Øß‘éDMœù™kPÇœ'ï’=-E˜Ò ^c<àº\ÿO¸ŸË ƒ7§ðl¥n}¿'ÞU¿Ã…œva'NIO°> Ð@•H5”4qßEÜ}Ñ¿¦,± ´&°ê,Ú¼ê¯4à1 ãÅg9+†pGýÃe†ØúOGÓ”9ŽßFŽÌ5¿É2h¢…¸¢ßéÈÁôª¿K7ë‡"MËÞºÜO…7áUxNGFWà3®ž´5Óêú&|¾é°ýV U[x^…}à4«äªÇóQùpe¹¶«úïÚš<ÿ‚Ÿ2A*à"PöeµSûJ™™GÑ×YÞ ø‡¹ˆ³èÄ炨}[°¢”*¹+ö·GŸ?=ëb&¿áz2ptÓMR|ׯ“|/>“|ÿpÉ¿vÐÖ WW97½®úáb…ápû†AÁÛïr ñÁûð^V¯ì¶ßõ B¾I¤H|ƒ¡îœÝºLRRy•¤;¯6f˜,ìO¬‡Á†ŠA^¶®Í«gÑòÒCúÏ}'¯Õâ’¹—g™zë.?œä–ueHœT™¡¬“h·ŒQuú.YÕXÊk5'Ü”5îaöPKYHáDÈG÷‘œ¿ Dastropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.js½UÁnã6½ïW »‘”ÚJР(àÝØ[ïmOEPâXbC‘IÙq‹ü{gHY’“xw/­$‡o8óæqø!—¶:4¡( yÌwƒ©ƒ²&/àŸw@ßÍ5|‘ü±Ýnÿ„jÁ ¿Ð"Û¯jÚµuØ$‚]¯ÑÓh•Äè ®#†Ü€0ʲ„ÞÙ®>ÎÙf‡Ðaœ:ñˆÑÀNONjÛE¥±„뛸¶¤ÚÃ=|ȳ²¥x4Ç´î¡¥@ç•U?$/‹ï5ânÉŠéˆÞ!A•;edžÑ<+>½K,Ý@ƒ!†êÑ3ßQj)ôÁ9"˜Ç]Ê€e/x1/æAí=ù´^1ýÙ 2‡Zµ‡œb`2>Š$û…&ñˆ%‰Âl†øÖ&ȯ4ù6¤²N¢{8(ZBq¼1º´¾æªGÛ2²³¿€‰¶70µÕÖ]ÀDÛ& ðadù~Ti,$1íió†XT& c'B7‰Ê[=äuòÍK·‘èXè4›½A¤6g±®&kJis–ýk‰¬Í¯äã‚k®ÕÚ«¿ÙoöóO—Aí¬ ëè”>²µ³Æú^Ô1¥^H©L³Ö¸KÙ”?b·4Ìy&Ë«8jðqÜõOp ·YÜô<©¼¦60ʆ¼F)-®ºÐzº­Pi[?Rhw„2|÷£#¾D(êvn7t£ð©XT“kýWh•ך£øS;È£q¼ŠeÓgE©Ñ4$Ø-Ü. '5‰ÏDšZ ïïßs?IÆ÷Û«&|:ý¾á]Ûlq.ikꙋ·v‰\ž4—hº½/\¦THþ=R6 ºØò<¨ÁQ¹+ÁÔæeŠ‰ÛŠ Ä{޹¥ÜDÉÅ©péæàDß“€"´å`Ý#qXrô» JÓC{D ^„nÎqÉ>¾i…áP8 >žzÚNiB½~TNŸÃ08y¬oiH6¿{j÷pWÀÕ¤u)‚(ƒS]~Vã%CEÉ …Jö¼hÏ)ØÔ.+lÅ^ÙøZ-|hÑ€ ™'a¨úe„ò“2+„Ò ¶i4æÓÙ“{!º^ˆdzNb¶+ Eó½?%«&ÉU¢ ̹zÙèÈfã ³W^UJ«päÖ@¾%š¯H‚N&4£ N}L¼«]R¥3g"CSRe ÞçOØdÉËkÁVk5A/ýOt93¼_\ Åu±Š’×|KEàÖ·n³ös(x+µ¸?~ØØ ]JA]xO™L„šïžE p{€Ç©àylçLka|ÐB~Uô/#¾Ày.¡mtÈáu)c0 §¾?à R é7óñmf†Í½áÀó“' ½Ž·ðŽ3·òßo>xs\;èÈ‘¿ðwÚsw˜¸RÓºIVÑ÷EÍmùG07…å–¨zôèðŽÖݧœõïÌö£[{WG=Ú­Š[hè_Û}æ?ùÄ÷-WÝ›G&º2ÓS]+ÿPKYHáDastropy_helpers/src/__init__.pyPKu@,F‚Åz™ astropy_helpers/src/__init__.pyccþÌË%»)8™ ؈‹Y€D C°HÄO$‡F;‰¤ÒÌœý¤”Ìâ½ÜÄäüâ ]C=SÝ ³x3ýÔôtýÄâ’¢ü‚ÊøŒÔœ‚Ô¢býâ¢dýøøÌ¼Ì’øx½‚Ê 16¹ù)¥9©v ËŠA†PKYHáDæRežÙ astropy_helpers/src/compiler.c­VëoÛ6ÿ®¿â`f‰½´Ý†4EMµù?ºn_Y¢c6iPT¯Ýÿ¾£´üPâ`K<ÞÝï^¼c“‰§…÷£µ^Jq¶üà8ç'/÷8pý T2…TQMUÌw —B¯§ ¨Jâ#¿™.iB!PæR)ùH#X(ãJ&úA|•Н!˜+Ý!ƒ–Pz#_5UˆqaTs™jƒôrϹã4ÙBDt£¿/þ4 ü ýë?†còÙOüá>\Á…ÓD&hÆ]§IyB·‰$Šˆ-Ê—c·'Ó±?¸õÿñZ_Úp3$ÕµeÚ¡CóKfäÛò@Ü‚ypÍ7¸¯_ShšÀ­ëžB‚ÁÔ° Ö`µ¢üñõ ³MÀ§Às‡ý‘ßóÆÐÈu™„†E*(ˆhÜݘÒ"ÄL½)U´áû÷ê¦ÛÛ£¸;)Æ_hÊ­iOaäòý2I»ü9û®ÙhÙózÜ^°{Œ°{PØ;FسÂyÌV1wïbâ6õ³¥¹½Ÿ¿ÛÁÌ%$ËÀ]Ö—ÖÔVa•Äd6‡¤Èë$ð—T÷ÉR®À-M­Å1ìO:´¥»?qepŸ™¦%>³$ 0RçxJí§‰†9à;Á–ƒýªtšÂ®RaÖúÌn Ùœq¦±k™vÄ·*Ör¿‡î/Î^–K/m¢ßžu*5R¿8FüÝañ««#å}B¾{”|·NþÍ1ø¿Õã¿=Fþ÷zùwÇÈw;¦‡?Ç_"<4÷kûó¡jÞÅÈKÁþp>ÂûúÃ2÷B>nLÃÙŒœ¿È(åôgN(éÉ›h•†â ‚$§|3!À[lu„0?™©&"Nqà­ð æÂI¥ƒ}h{àØ‘Z¡Di¯/ËÈýwéÃo†Ç˜ÃÂFë<7xQÈí5W†+4·¬ž ùä]ßà8ò§§v»Al¶6ÄÁ¬×Û¬ö/•‹Ö¨´ëD~l•-Œ£æÝ´3ÈŸzãñp ŠêT‰œÓ)\Þ˜}òq6p ’/˜&Ö™Öƒd‘­Þ§ôÖªdFᎾ²œMxGëáü+ õ ÄÛ9Š1þeÔ‰«(ªõÊ&§}iʉ±<ç¾hUÓ‘G*ûoÛzp²ÖÞŠM[Év2[­SY-øuM´Â»±+&LèV| ‚½Äl{PD<ÞT¡ó?PKYHáDñ8Ï[KK$astropy_helpers/src/setup_package.pyKIMSHO-‰/HLÎNLOOI,IÔдâR‚¢Ô’Ò¢<…jõÄâ’¢ü‚ÊøŒÔœ‚Ô¢b½â¢du+…hõäü܂̜Ô"½dõØZ.PKu@,F‹pÆ—Î}%astropy_helpers/src/setup_package.pycµ± Â0†ÓvAÜ|‚.M´8ˆnì&HI“‹- ½ÚÝ'òÕ|/¢îþŸÜåç»\ð gç{*Èûx¨ Fh’!'¼x$ }ì|sjïrc´Âs î“8 Ý[C¯+S”ª¡¦Xr°Mmúì¢J£ ÐˆÐÁ~ hy[”’å²K+.jè¢Åœ®¢ngñ’)­ÙŽ!޲­É W®5½ K+ûie’[î–ÿµnºâøï_ µ©jÙ–jûšî&<PKu@,F“×2EGG-INFO/dependency_links.txtãPKYHáD“×2EGG-INFO/not-zip-safeãPKu@,F?<±‡ EGG-INFO/PKG-INFO•V]oÛ6}÷¯ ú²°¥Ë^Œm˜·th±4 æt{Œ)éZbK‰IYu}Ï¥$ú£îºA,S÷žûq/ù–¼,¤—‹¿É:eš¥x™¼œÝÊš–B:oM»_T¤[¼E“ï“«äj¶îêZÚýR¼óJ+¯È‰­±"ë”.TS ÙB5ÎK­ùçj@›OBn·ð“ž ÑÊüƒ,É̓“¯HYaɵ”{µ#Q˜¼«©ñÒ#|2{mjZ´°_ŠÊûv™¦c¦‰±ålÕùÊØ¥x¨(†º¦iŠ^/¨–JÇO²þµäµ$7õìFåÔ8àÿ¶¾ž]›¾ÑF‹wÝĈí¾UI»VÃQÓ©‚Ô™Îæ”Êô¬{ç¿¡‰‰—6)?Í®ÉåVµ>´÷¼ïbüü|ú‰ëñá¡RN´Ö¼Gßø{§ "Å}Èsêò\l6cˆÇ1Äf3}¥ò „広WĬe³8OlªN˜YXÒNoŒv¢sxÌöLçDDD“œÙOyÂQ+-ô>( ìo`'8éE¯\…0Oƒ` ¼E zc?$"( 6PPÈNdT© .nÒr¨[@!_³Ê Wu«)Ö&¤%ÔŠ‘yN-×m7“Ðîñß8©Cþ¯šJ6yÀÏW÷¯^ˆ+ñëÇA@¥òU—±Ú&eD…ÀÔ¥™6YZc‰lŠ…«Ä:ÿËæ1ù’õ lFA>ï"…ŒžeÆxÊöºRtšD2©8ª£Ô  Qˆžš"‹NFråDÌwôùŽÝ`1-@|°Ÿ:K{ÜÄKYO¬ œÜ™!It2¢¦Ç2LFÕãÏ©.!Ø€>=N)|¬9$ 4»Jµ-jéÁ‡p˜,GJC¥S7Ä&@eGßHf¦|Öåȳ`ßÊô`~™µ•ƒðxÓgÄcR0Çóøn³¢éê AJ—ºµ5Z›ž]"hn,MÓ„\Ë÷Ʀµj0Bä¡9#{ÐÔ÷ÓºPVß÷ÉÑhMQɰcC³dƒ¼ jYP¸£;‚Ü9D­rkÄó¬+·ê㋈{VY"^³ÃPµjp„@¦˜!$]Ð&$ÏÁCBÕCØóQ² fƒN{¥5«“· ;&†ä¬¦M ^y´Äž.bO/ðôšG%ƒ0"*n¹9L‡K0œtÜóƒÔˆFeÉ’'дoKæU¡ØöhÄ|q\ OÈ+ÿ9UFãÅd|YŽI‚’øHN8Æ‚ìwÊ-r¸?Rc±IÛ”„?Kœh%ù'Âü¯„rÃC^k—(“Z ý\šÉ¢¤oçvŠøíäîÑ@lÇwžÛ?oïþ¹ý®¥sj«7Žñ–T±Æ±Ñ9ì >Š.çy•â¦Ú‰ß›i´®ºB…-´\_YŽmÇ› [ܭ߈UËÇ<\—á®2½>q¹f%Âzã¤|5îÝsäZZY×ìp#›²c¥Áe¸D<Á”Ÿ~8±0­Êyym¶¾çõ¸e\Ïw˜ñ}’ãʬ´|=„þ×€b+V6¯ÔŽK`×°YðcöPKu@,FR£ÿ¯@ EGG-INFO/SOURCES.txt­–ÛrÚ0†ïyìy†’”iC:¡½ÖÈòb«‘µiMqž¾‹!”)ÆrœÞx4ÞoK{’_æë‡å&ñ&ßV‹åz³l×óõê~¹ù‘h;y^Î??_ËRdˆÈK—¸f¯"Õíú¸PÛbr~%D׈ŒR!´Õ$D—­`ÃiÝen5û‚Ð+P“6†?4ÚSlE1Õv‹é÷¯ÓÕúþé6±yúù¼àXÓžnC98°9XÕ£íKè§-ÒôU»i[¸M:a`¦K,UX9I½¹9!¡ÎœG¡3Žo:)ášY¯np¥¶û!ˆB»í1«ÃIõ" èá`ßÐ ìd’5a¨«Jú&æÀd…¹tzxPª”¶ƒÅ©"4VX |œuÚ€µuÒ‡XÌrTAqÏæÄñe?´m„‚œÓÅ]È¢¬³lëÊ5¬ÁG–³ tåÐÇ68û$<4»hd ÷0•[;=QM!¾×›“ë‚Ùiø­0几r†Ë#¤u-zH3ÉUÐÎøQîÊH ãý¹!j3`ú¯‘+¸½÷æµÏ€6½pÚ(.±ôTÒ¤®¡íÝqh»»ES Ç÷|KOO\Z̤áêLJªÌ»Ýl°¦‘¾‡ŒþréU™á~œ{kH÷Çû¿L’´z» ÚÌ1³O‰³Å‡Õ°ÀD+ü:ânö‘-]ÂX1Åë¬&â?ª_£E‚Î!“¾SÁ«þàÕùvKT§ùß¿…?PKu@,Fþ¥¥EGG-INFO/top_level.txtK,.)Ê/¨ŒÏHÍ)H-*æPK*xbEÚ2V£¤astropy_helpers/__init__.pyPKu@,FkRÝÂëI¤astropy_helpers/__init__.pycPKIz)FèªJŠ Ö¤´astropy_helpers/git_helpers.pyPKu@,F;¤ZÛôl¤ýastropy_helpers/git_helpers.pycPKIz)FP#Л?Yß ¤.astropy_helpers/setup_helpers.pyPKu@,Fd;I|ÎDù¶!¤íPastropy_helpers/setup_helpers.pycPKIz)FzÀ u%¤ú•astropy_helpers/test_helpers.pyPKu@,FÜ0~,$ ¤Æ¢astropy_helpers/test_helpers.pycPKIz)Frz—¯æ6¤0±astropy_helpers/utils.pyPKu@,FrF9¸Õ Ú¤L¹astropy_helpers/utils.pycPKu@,F´Ð„¾u¤XÃastropy_helpers/version.pyPKu@,Fò–1Eëú¤Ëastropy_helpers/version.pycPK*xbEÖ·U2Að"¤)Ôastropy_helpers/version_helpers.pyPKu@,FR括% ‹#¤ªÜastropy_helpers/version_helpers.pycPKYHáDŽƒu¾Ëp"¤çastropy_helpers/compat/__init__.pyPKu@,FáL?tÖÐ#¤èastropy_helpers/compat/__init__.pycPKYHáD_±6,($¤2êastropy_helpers/compat/subprocess.pyPKu@,F!øM†Õä%¤ ëastropy_helpers/compat/subprocess.pycPKYHáDÞ@‰"r2¤¸íastropy_helpers/compat/_subprocess_py2/__init__.pyPKu@,F§s•Aˆ3¤zðastropy_helpers/compat/_subprocess_py2/__init__.pycPKYHáDòËF­ "¤Lôastropy_helpers/sphinx/__init__.pyPKu@,F"Æx*¸#¤9õastropy_helpers/sphinx/__init__.pycPK*xbE“K'ÑÜ~)¤¤öastropy_helpers/sphinx/conf.pyPKu@,F¦¥lèϤ¼astropy_helpers/sphinx/conf.pycPKYHáD¾7ù¤ÉD'¤áastropy_helpers/sphinx/setup_package.pyPKu@,FÕç÷(¤ïastropy_helpers/sphinx/setup_package.pycPKYHáDvÕðL^&¤Eastropy_helpers/sphinx/ext/__init__.pyPKu@,F@Å‹%ùP'¤Õastropy_helpers/sphinx/ext/__init__.pycPK*xbEcxÈ’W 0¤astropy_helpers/sphinx/ext/astropyautosummary.pyPKu@,F?ÇL•ï> 1¤óastropy_helpers/sphinx/ext/astropyautosummary.pycPK1`!E":·‘ô…1(¤1astropy_helpers/sphinx/ext/automodapi.pyPKu@,F™pÊ¢ÄÔ')¤k/astropy_helpers/sphinx/ext/automodapi.pycPKIz)FP:بnKY)¤vAastropy_helpers/sphinx/ext/automodsumm.pyPKu@,Fü®ü欖D*¤+[astropy_helpers/sphinx/ext/automodsumm.pycPK[(EGñ3¹. -¤yastropy_helpers/sphinx/ext/changelog_links.pyPKu@,F[ÛŽ .¤˜}astropy_helpers/sphinx/ext/changelog_links.pycPKYHáDßdo›l)+¤¿‚astropy_helpers/sphinx/ext/comment_eater.pyPKu@,Fp‡ûF <,¤t‰astropy_helpers/sphinx/ext/comment_eater.pycPKYHáD‡;•<„¤`.¤”astropy_helpers/sphinx/ext/compiler_unparse.pyPKu@,F^ÉÉãU/¤Ô§astropy_helpers/sphinx/ext/compiler_unparse.pycPKYHáD ‹!Ë?'¤Àastropy_helpers/sphinx/ext/docscrape.pyPKu@,FÁŽàV±%O(¤[Ðastropy_helpers/sphinx/ext/docscrape.pycPKYHáD«…SÞÝ$.¤Rìastropy_helpers/sphinx/ext/docscrape_sphinx.pyPKu@,FìEñ‘-ó./¤|õastropy_helpers/sphinx/ext/docscrape_sphinx.pycPK*xbEÐ÷dûy%¤öastropy_helpers/sphinx/ext/doctest.pyPKu@,F T¸À]@&¤²astropy_helpers/sphinx/ext/doctest.pycPK1`!E4‚-R},¤S astropy_helpers/sphinx/ext/edit_on_github.pyPKu@,FÓüE‡, -¤astropy_helpers/sphinx/ext/edit_on_github.pycPKYHáDq¾oŽy &¤‘astropy_helpers/sphinx/ext/numpydoc.pyPKu@,F_½ø% ô'¤N'astropy_helpers/sphinx/ext/numpydoc.pycPKYHáD¤†<žÞ,¤¸4astropy_helpers/sphinx/ext/phantom_import.pyPKu@,F»ˆo) s-¤ <astropy_helpers/sphinx/ext/phantom_import.pycPK*xbE^Wlü¾~,¤Hastropy_helpers/sphinx/ext/smart_resolver.pyPKu@,F6®Ú)F -¤Mastropy_helpers/sphinx/ext/smart_resolver.pycPKYHáD{™jn¥)¤wSastropy_helpers/sphinx/ext/tocdepthfix.pyPKu@,F#@òÅ*¤,Uastropy_helpers/sphinx/ext/tocdepthfix.pycPKYHáD×g ¨¦±'¤9Wastropy_helpers/sphinx/ext/traitsdoc.pyPKu@,FÈ9_” (¤$]astropy_helpers/sphinx/ext/traitsdoc.pycPKYHáD–ï0‘ #¤þfastropy_helpers/sphinx/ext/utils.pyPKu@,F5Ç­Tü $¤Ðjastropy_helpers/sphinx/ext/utils.pycPK*xbE#¢ƒi_ &¤Õoastropy_helpers/sphinx/ext/viewcode.pyPKu@,FËÂó +'¤xzastropy_helpers/sphinx/ext/viewcode.pycPKYHáDÚ¨;Khª>¤Ñ‡astropy_helpers/sphinx/ext/templates/autosummary_core/base.rstPKYHáDavì'J‰?¤•ˆastropy_helpers/sphinx/ext/templates/autosummary_core/class.rstPKYHáD°KÐAÒ¿@¤<Šastropy_helpers/sphinx/ext/templates/autosummary_core/module.rstPK1`!Eo+.véá,¤l‹astropy_helpers/sphinx/ext/tests/__init__.pyPKu@,Fc{ìSÅ-¤ŸŽastropy_helpers/sphinx/ext/tests/__init__.pycPKIz)FíÍÓ`Ü3¤=“astropy_helpers/sphinx/ext/tests/test_automodapi.pyPKu@,Fnª¨6' §$4¤î˜astropy_helpers/sphinx/ext/tests/test_automodapi.pycPKIz)FBþ)ïr 4¤g¢astropy_helpers/sphinx/ext/tests/test_automodsumm.pyPKu@,FKX椧5¤¨¥astropy_helpers/sphinx/ext/tests/test_automodsumm.pycPKYHáDœ´ìW¹F2¤Ÿ«astropy_helpers/sphinx/ext/tests/test_docscrape.pyPKu@,Fx£ÃãO_3¤F½astropy_helpers/sphinx/ext/tests/test_docscrape.pycPK1`!E8âf®ã.¤z×astropy_helpers/sphinx/ext/tests/test_utils.pyPKu@,F´f~ì&/¤tÙastropy_helpers/sphinx/ext/tests/test_utils.pycPKYHáDaŒÅC@-¤çÛastropy_helpers/sphinx/local/python3links.invPKYHáD¥Í¥JI>¤uÝastropy_helpers/sphinx/themes/bootstrap-astropy/globaltoc.htmlPKYHáDêžêuãh ;¤Þastropy_helpers/sphinx/themes/bootstrap-astropy/layout.htmlPKYHáDK±ñÅ#"=¤Wãastropy_helpers/sphinx/themes/bootstrap-astropy/localtoc.htmlPKYHáD`¿Âƒ«>¤Õãastropy_helpers/sphinx/themes/bootstrap-astropy/searchbox.htmlPKYHáDuâÄ5‰À:¤Üäastropy_helpers/sphinx/themes/bootstrap-astropy/theme.confPKYHáDŠrYº½M¤½åastropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_linkout_20.pngPKYHáDf™¢m~G¤âìastropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo.icoPKYHáDæòwa\J¤´ðastropy_helpers/sphinx/themes/bootstrap-astropy/static/astropy_logo_32.pngPK*xbEeß5—æ 8-L¤}øastropy_helpers/sphinx/themes/bootstrap-astropy/static/bootstrap-astropy.cssPKYHáDÈG÷‘œ¿ D¤Íastropy_helpers/sphinx/themes/bootstrap-astropy/static/copybutton.jsPKYHáD/¬kA¤Ëastropy_helpers/sphinx/themes/bootstrap-astropy/static/sidebar.jsPKYHáD¤Iastropy_helpers/src/__init__.pyPKu@,F‚Åz™ ¤ˆastropy_helpers/src/__init__.pycPKYHáDæRežÙ ¤@astropy_helpers/src/compiler.cPKYHáDñ8Ï[KK$¤astropy_helpers/src/setup_package.pyPKu@,F‹pÆ—Î}%¤§astropy_helpers/src/setup_package.pycPKu@,F“×2¤¸EGG-INFO/dependency_links.txtPKYHáD“×2¤öEGG-INFO/not-zip-safePKu@,F?<±‡ ¤,EGG-INFO/PKG-INFOPKu@,FR£ÿ¯@ ¤âEGG-INFO/SOURCES.txtPKu@,Fþ¥¥¤TEGG-INFO/top_level.txtPKaa|!šastroquery-0.2.4/astropy_helpers/ez_setup.py0000644000077000000240000002757312354456432021435 0ustar adamstaff00000000000000#!python """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from ez_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import os import shutil import sys import tempfile import tarfile import optparse import subprocess import platform from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None DEFAULT_VERSION = "1.4.2" DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 def _check_call_py24(cmd, *args, **kwargs): res = subprocess.call(cmd, *args, **kwargs) class CalledProcessError(Exception): pass if not res == 0: msg = "Command '%s' return non-zero exit status %d" % (cmd, res) raise CalledProcessError(msg) vars(subprocess).setdefault('check_call', _check_call_py24) def _install(tarball, install_args=()): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # installing log.warn('Installing Setuptools') if not _python_cmd('setup.py', 'install', *install_args): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') # exitcode will be 2 return 2 finally: os.chdir(old_wd) shutil.rmtree(tmpdir) def _build_egg(egg, tarball, to_dir): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # building an egg log.warn('Building a Setuptools egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) shutil.rmtree(tmpdir) # returning the result log.warn(egg) if not os.path.exists(egg): raise IOError('Could not build the egg.') def _do_download(version, download_base, to_dir, download_delay): egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): tarball = download_setuptools(version, download_base, to_dir, download_delay) _build_egg(egg, tarball, to_dir) sys.path.insert(0, egg) # Remove previously-imported pkg_resources if present (see # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). if 'pkg_resources' in sys.modules: del sys.modules['pkg_resources'] import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15): # making sure we use the absolute path to_dir = os.path.abspath(to_dir) was_imported = 'pkg_resources' in sys.modules or \ 'setuptools' in sys.modules try: import pkg_resources except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("setuptools>=" + version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of setuptools (>=%s) is not available,\n" "and can't be installed while this script is running. Please\n" "install a more recent version first, using\n" "'easy_install -U setuptools'." "\n\n(Currently using %r)\n" % (version, e.args[0])) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return _do_download(version, download_base, to_dir, download_delay) except pkg_resources.DistributionNotFound: return _do_download(version, download_base, to_dir, download_delay) def _clean_check(cmd, target): """ Run the command to download target. If the command fails, clean up before re-raising the error. """ try: subprocess.check_call(cmd) except subprocess.CalledProcessError: if os.access(target, os.F_OK): os.unlink(target) raise def download_file_powershell(url, target): """ Download the file at url to target using Powershell (which will validate trust). Raise an exception if the command cannot complete. """ target = os.path.abspath(target) cmd = [ 'powershell', '-Command', "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(), ] _clean_check(cmd, target) def has_powershell(): if platform.system() != 'Windows': return False cmd = ['powershell', '-Command', 'echo test'] devnull = open(os.path.devnull, 'wb') try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except: return False finally: devnull.close() return True download_file_powershell.viable = has_powershell def download_file_curl(url, target): cmd = ['curl', url, '--silent', '--output', target] _clean_check(cmd, target) def has_curl(): cmd = ['curl', '--version'] devnull = open(os.path.devnull, 'wb') try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except: return False finally: devnull.close() return True download_file_curl.viable = has_curl def download_file_wget(url, target): cmd = ['wget', url, '--quiet', '--output-document', target] _clean_check(cmd, target) def has_wget(): cmd = ['wget', '--version'] devnull = open(os.path.devnull, 'wb') try: try: subprocess.check_call(cmd, stdout=devnull, stderr=devnull) except: return False finally: devnull.close() return True download_file_wget.viable = has_wget def download_file_insecure(url, target): """ Use Python to download the file, even though it cannot authenticate the connection. """ try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen src = dst = None try: src = urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = src.read() dst = open(target, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() download_file_insecure.viable = lambda: True def get_best_downloader(): downloaders = [ download_file_powershell, download_file_curl, download_file_wget, download_file_insecure, ] for dl in downloaders: if dl.viable(): return dl def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. ``downloader_factory`` should be a function taking no arguments and returning a function for downloading a URL to a target. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) tgz_name = "setuptools-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) if not os.path.exists(saveto): # Avoid repeated downloads log.warn("Downloading %s", url) downloader = downloader_factory() downloader(url, saveto) return os.path.realpath(saveto) def _extractall(self, path=".", members=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). """ import copy import operator from tarfile import ExtractError directories = [] if members is None: members = self for tarinfo in members: if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) tarinfo.mode = 448 # decimal for oct 0700 self.extract(tarinfo, path) # Reverse sort directories. if sys.version_info < (2, 4): def sorter(dir1, dir2): return cmp(dir1.name, dir2.name) directories.sort(sorter) directories.reverse() else: directories.sort(key=operator.attrgetter('name'), reverse=True) # Set correct owner, mtime and filemode on directories. for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: self.chown(tarinfo, dirpath) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError: e = sys.exc_info()[1] if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def _build_install_args(options): """ Build the arguments to 'python setup.py install' on the setuptools package """ install_args = [] if options.user_install: if sys.version_info < (2, 6): log.warn("--user requires Python 2.6 or later") raise SystemExit(1) install_args.append('--user') return install_args def _parse_args(): """ Parse the command line for options """ parser = optparse.OptionParser() parser.add_option( '--user', dest='user_install', action='store_true', default=False, help='install in user site package (requires Python 2.6 or later)') parser.add_option( '--download-base', dest='download_base', metavar="URL", default=DEFAULT_URL, help='alternative URL from where to download the setuptools package') parser.add_option( '--insecure', dest='downloader_factory', action='store_const', const=lambda: download_file_insecure, default=get_best_downloader, help='Use internal, non-validating downloader' ) options, args = parser.parse_args() # positional arguments are ignored return options def main(version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" options = _parse_args() tarball = download_setuptools(download_base=options.download_base, downloader_factory=options.downloader_factory) return _install(tarball, _build_install_args(options)) if __name__ == '__main__': sys.exit(main()) astroquery-0.2.4/astropy_helpers/LICENSE.rst0000644000077000000240000000272312403272746021026 0ustar adamstaff00000000000000Copyright (c) 2014, Astropy Developers All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Astropy Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. astroquery-0.2.4/astropy_helpers/licenses/0000755000077000000240000000000012505171566021014 5ustar adamstaff00000000000000astroquery-0.2.4/astropy_helpers/licenses/LICENSE_COPYBUTTON.rst0000644000077000000240000000471112354456432024421 0ustar adamstaff00000000000000Copyright 2014 Python Software Foundation License: PSF PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- . 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. . 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. . 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. . 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. . 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. . 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. . 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. . 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. astroquery-0.2.4/astropy_helpers/licenses/LICENSE_NUMPYDOC.rst0000644000077000000240000001350712354456432024154 0ustar adamstaff00000000000000------------------------------------------------------------------------------- The files - numpydoc.py - docscrape.py - docscrape_sphinx.py - phantom_import.py have the following license: Copyright (C) 2008 Stefan van der Walt , Pauli Virtanen Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------- The files - compiler_unparse.py - comment_eater.py - traitsdoc.py have the following license: This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative. Copyright (c) 2006, Enthought, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Enthought, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------- The file - plot_directive.py originates from Matplotlib (http://matplotlib.sf.net/) which has the following license: Copyright (c) 2002-2008 John D. Hunter; All Rights Reserved. 1. This LICENSE AGREEMENT is between John D. Hunter (“JDHâ€), and the Individual or Organization (“Licenseeâ€) accessing and otherwise using matplotlib software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, JDH hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use matplotlib 0.98.3 alone or in any derivative version, provided, however, that JDH’s License Agreement and JDH’s notice of copyright, i.e., “Copyright (c) 2002-2008 John D. Hunter; All Rights Reserved†are retained in matplotlib 0.98.3 alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates matplotlib 0.98.3 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to matplotlib 0.98.3. 4. JDH is making matplotlib 0.98.3 available to Licensee on an “AS IS†basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB 0.98.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB 0.98.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING MATPLOTLIB 0.98.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between JDH and Licensee. This License Agreement does not grant permission to use JDH trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using matplotlib 0.98.3, Licensee agrees to be bound by the terms and conditions of this License Agreement. astroquery-0.2.4/astropy_helpers/MANIFEST.in0000644000077000000240000000024312354456432020744 0ustar adamstaff00000000000000include README.rst include CHANGES.rst include LICENSE.rst include ez_setup.py include ah_bootstrap.py exclude *.pyc *.o prune build prune astropy_helpers/tests astroquery-0.2.4/astropy_helpers/README.rst0000644000077000000240000000324112464715714020701 0ustar adamstaff00000000000000astropy-helpers =============== This project provides a Python package, ``astropy_helpers``, which includes many build, installation, and documentation-related tools used by the Astropy project, but packaged separately for use by other projects that wish to leverage this work. The motivation behind this package and details of its implementation are in the accepted `Astropy Proposal for Enhancement (APE) 4 `_. ``astropy_helpers`` includes a special "bootstrap" module called ``ah_bootstrap.py`` which is intended to be used by a project's setup.py in order to ensure that the ``astropy_helpers`` package is available for build/installation. This is similar to the ``ez_setup.py`` module that is shipped with some projects to bootstrap `setuptools `_. As described in APE4, the version numbers for ``astropy_helpers`` follow the corresponding major/minor version of the `astropy core package `_, but with an independent sequence of micro (bugfix) version numbers. Hence, the initial release is 0.4, in parallel with Astropy v0.4, which will be the first version of Astropy to use ``astropy-helpers``. For examples of how to implement ``astropy-helpers`` in a project, see the ``setup.py`` and ``setup.cfg`` files of the `Affiliated package template `_. .. image:: https://travis-ci.org/astropy/astropy-helpers.png :target: https://travis-ci.org/astropy/astropy-helpers .. image:: https://coveralls.io/repos/astropy/astropy-helpers/badge.png :target: https://coveralls.io/r/astropy/astropy-helpers astroquery-0.2.4/astropy_helpers/setup.cfg0000644000077000000240000000014612354456432021031 0ustar adamstaff00000000000000[pytest] norecursedirs = .tox astropy_helpers/tests/package_template python_functions = test_ astroquery-0.2.4/astropy_helpers/setup.py0000755000077000000240000000357712464715714020743 0ustar adamstaff00000000000000#!/usr/bin/env python # Licensed under a 3-clause BSD style license - see LICENSE.rst import ah_bootstrap import pkg_resources from setuptools import setup from astropy_helpers.setup_helpers import register_commands, get_package_info from astropy_helpers.version_helpers import generate_version_py NAME = 'astropy_helpers' VERSION = '0.4.3' RELEASE = 'dev' not in VERSION DOWNLOAD_BASE_URL = 'http://pypi.python.org/packages/source/a/astropy-helpers' generate_version_py(NAME, VERSION, RELEASE, False) # Use the updated version including the git rev count from astropy_helpers.version import version as VERSION cmdclass = register_commands(NAME, VERSION, RELEASE) # This package actually doesn't use the Astropy test command del cmdclass['test'] setup( name=pkg_resources.safe_name(NAME), # astropy_helpers -> astropy-helpers version=VERSION, description='Utilities for building and installing Astropy, Astropy ' 'affiliated packages, and their respective documentation.', author='The Astropy Developers', author_email='astropy.team@gmail.com', license='BSD', url='http://astropy.org', long_description=open('README.rst').read(), download_url='{0}/astropy-helpers-{1}.tar.gz'.format(DOWNLOAD_BASE_URL, VERSION), classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Topic :: Software Development :: Build Tools', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Archiving :: Packaging' ], cmdclass=cmdclass, zip_safe=False, **get_package_info(exclude=['astropy_helpers.tests']) ) astroquery-0.2.4/astropy_helpers/tox.ini0000644000077000000240000000036412464715714020530 0ustar adamstaff00000000000000[tox] envlist = py26,py27,py32,py33,py34 [testenv] deps = pytest numpy Cython Sphinx # Note: Sphinx is required to run the sphinx.ext tests commands = python setup.py clean --all py.test {posargs} sitepackages = False astroquery-0.2.4/astroquery/0000755000077000000240000000000012505171566016202 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/__init__.py0000644000077000000240000000124712464716555020326 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Accessing Online Astronomical Data. Astroquery is an astropy affiliated package that contains a collection of tools to access online Astronomical data. Each web service has its own sub-package. """ # Affiliated packages may add whatever they like to this file, but # should keep this content at the top. # ---------------------------------------------------------------------------- from ._astropy_init import * # ---------------------------------------------------------------------------- # For egg_info test builds to pass, put package imports here. #if not _ASTROPY_SETUP_: # from astroquery import * astroquery-0.2.4/astroquery/_astropy_init.py0000644000077000000240000001510512505065047021435 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst __all__ = ['__version__', '__githash__', 'test'] # this indicates whether or not we are in the package's setup.py try: _ASTROPY_SETUP_ except NameError: from sys import version_info if version_info[0] >= 3: import builtins else: import __builtin__ as builtins builtins._ASTROPY_SETUP_ = False try: from .version import version as __version__ except ImportError: __version__ = '' try: from .version import githash as __githash__ except ImportError: __githash__ = '' # set up the test command def _get_test_runner(): import os from astropy.tests.helper import TestRunner return TestRunner(os.path.dirname(__file__)) def test(package=None, test_path=None, args=None, plugins=None, verbose=False, pastebin=None, remote_data=False, pep8=False, pdb=False, coverage=False, open_files=False, **kwargs): """ Run the tests using `py.test `__. A proper set of arguments is constructed and passed to `pytest.main`_. .. _py.test: http://pytest.org/latest/ .. _pytest.main: http://pytest.org/latest/builtin.html#pytest.main Parameters ---------- package : str, optional The name of a specific package to test, e.g. 'io.fits' or 'utils'. If nothing is specified all default tests are run. test_path : str, optional Specify location to test by path. May be a single file or directory. Must be specified absolutely or relative to the calling directory. args : str, optional Additional arguments to be passed to pytest.main_ in the ``args`` keyword argument. plugins : list, optional Plugins to be passed to pytest.main_ in the ``plugins`` keyword argument. verbose : bool, optional Convenience option to turn on verbose output from py.test_. Passing True is the same as specifying ``'-v'`` in ``args``. pastebin : {'failed','all',None}, optional Convenience option for turning on py.test_ pastebin output. Set to ``'failed'`` to upload info for failed tests, or ``'all'`` to upload info for all tests. remote_data : bool, optional Controls whether to run tests marked with @remote_data. These tests use online data and are not run by default. Set to True to run these tests. pep8 : bool, optional Turn on PEP8 checking via the `pytest-pep8 plugin `_ and disable normal tests. Same as specifying ``'--pep8 -k pep8'`` in ``args``. pdb : bool, optional Turn on PDB post-mortem analysis for failing tests. Same as specifying ``'--pdb'`` in ``args``. coverage : bool, optional Generate a test coverage report. The result will be placed in the directory htmlcov. open_files : bool, optional Fail when any tests leave files open. Off by default, because this adds extra run time to the test suite. Works only on platforms with a working ``lsof`` command. parallel : int, optional When provided, run the tests in parallel on the specified number of CPUs. If parallel is negative, it will use the all the cores on the machine. Requires the `pytest-xdist `_ plugin installed. Only available when using Astropy 0.3 or later. kwargs Any additional keywords passed into this function will be passed on to the astropy test runner. This allows use of test-related functionality implemented in later versions of astropy without explicitly updating the package template. """ test_runner = _get_test_runner() return test_runner.run_tests( package=package, test_path=test_path, args=args, plugins=plugins, verbose=verbose, pastebin=pastebin, remote_data=remote_data, pep8=pep8, pdb=pdb, coverage=coverage, open_files=open_files, **kwargs) if not _ASTROPY_SETUP_: import os from warnings import warn from astropy import config # add these here so we only need to cleanup the namespace at the end config_dir = None if not os.environ.get('ASTROPY_SKIP_CONFIG_UPDATE', False): config_dir = os.path.dirname(__file__) config_template = os.path.join(config_dir, __package__ + ".cfg") if os.path.isfile(config_template): try: config.configuration.update_default_config( __package__, config_dir, version=__version__) except TypeError as orig_error: try: config.configuration.update_default_config( __package__, config_dir) except config.configuration.ConfigurationDefaultMissingError as e: wmsg = (e.args[0] + " Cannot install default profile. If you are " "importing from source, this is expected.") warn(config.configuration.ConfigurationDefaultMissingWarning(wmsg)) del e except: raise orig_error # This is to monkey-patch around a config system bug in astropy 1.0.1. # REMOVEME: when astropy 1.0.1 support is no longer needed if not _ASTROPY_SETUP_: import astropy if astropy.__version__ == '1.0.1': from astropy.config import configuration _existing_ConfigItem__init__ = configuration.ConfigItem.__init__ def _monkey_patch_1_0_1_ConfigItem__init__( self, defaultvalue='', description=None, cfgtype=None, module=None, aliases=None): if module is None: from astropy.utils import find_current_module module = find_current_module(2) if module is None: msg1 = 'Cannot automatically determine get_config module, ' msg2 = 'because it is not called from inside a valid module' raise RuntimeError(msg1 + msg2) else: module = module.__name__ return _existing_ConfigItem__init__( self, defaultvalue=defaultvalue, description=description, cfgtype=cfgtype, module=module, aliases=aliases) # Don't apply the same monkey patch twice if (configuration.ConfigItem.__init__.__name__ != '_monkey_patch_1_0_1_ConfigItem__init__'): configuration.ConfigItem.__init__ = _monkey_patch_1_0_1_ConfigItem__init__ astroquery-0.2.4/astroquery/alfalfa/0000755000077000000240000000000012505171566017570 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alfalfa/__init__.py0000644000077000000240000000073512464716555021715 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ ALFALFA Spectra Archive Query Tool ----------------------------------- :Author: Jordan Mirocha (mirochaj@gmail.com) This package is for querying the ALFALFA data repository hosted at http://arecibo.tc.cornell.edu/hiarchive/alfalfa/ """ from .core import Alfalfa, AlfalfaClass import warnings warnings.warn("Experimental: ALFALFA has not yet been refactored to have its API match the rest of astroquery.") astroquery-0.2.4/astroquery/alfalfa/core.py0000644000077000000240000001460712505065036021074 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ Author: Jordan Mirocha Affiliation: University of Colorado at Boulder Created on: Fri May 3 09:45:13 2013 """ from __future__ import print_function import requests import numpy as np import numpy.ma as ma from astropy import units as u from astropy.coordinates import Angle from ..utils import commons from ..query import BaseQuery from ..utils.docstr_chompers import prepend_docstr_noreturns __all__ = ['Alfalfa', 'AlfalfaClass'] # have to skip because it tries to use the internet, which is not allowed __doctest_skip__ = ['AlfalfaClass.query_region', 'Alfalfa.query_region'] class AlfalfaClass(BaseQuery): FITS_PREFIX = "http://arecibo.tc.cornell.edu/hiarchive/alfalfa/spectraFITS" CATALOG_PREFIX = "http://egg.astro.cornell.edu/alfalfa/data/a40files/a40.datafile1.csv" PLACEHOLDER = -999999 def get_catalog(self): """ Download catalog of ALFALFA source properties. Notes ----- This catalog has ~15,000 entries, so after it's downloaded, it is made global to save some time later. Returns ------- result : Dictionary of results, each element is a masked array. """ if hasattr(self, 'ALFALFACAT'): return self.ALFALFACAT result = requests.get(self.CATALOG_PREFIX) iterable_lines = result.iter_lines() # Read header cols = [col for col in next(iterable_lines).rstrip('\n').split(',')] catalog = {} for col in cols: catalog[col] = [] # Parse result for line in iterable_lines: # skip blank lines or trailing newlines if line == "": continue l = line.rstrip('\n').split(',') for i, col in enumerate(cols): item = l[i].strip() if item == '\"\"': catalog[col].append(self.PLACEHOLDER) elif item.isdigit(): catalog[col].append(int(item)) elif item.replace('.', '').isdigit(): catalog[col].append(float(item)) else: catalog[col].append(item) result.close() # Mask out blank elements for col in cols: mask = np.zeros(len(catalog[col]), dtype='bool') # need to turn list -> array for boolean comparison colArr = np.array(catalog[col]) # placeholder must share Type with the array ph = np.array(self.PLACEHOLDER, dtype=colArr.dtype) mask[colArr == ph] = True catalog[col] = ma.array(catalog[col], mask=mask) # Make this globally available so we don't have to re-download it # again in this session self.ALFALFACAT = catalog return catalog def query_region(self, coordinates, radius=3. * u.arcmin, optical_counterpart=False): """ Perform object cross-ID in ALFALFA. Search for objects near position (ra, dec) within some radius. Parameters ---------- coordinates : str or `astropy.coordinates` object The target around which to search. It may be specified as a string in which case it is resolved using online services or as the appropriate `astropy.coordinates` object. ICRS coordinates may also be entered as strings as specified in the `astropy.coordinates` module. radius : str or `~astropy.units.Quantity` object, optional The string must be parsable by `astropy.coordinates.Angle`. The appropriate `~astropy.units.Quantity` object from `astropy.units` may also be used. Defaults to 3 arcmin. optical_counterpart : bool Search for position match using radio positions or position of any optical counterpart identified by ALFALFA team? Keep in mind that the ALFA beam size is about 3x3 arcminutes. See documentation for astropy.coordinates.angles for more information about ('ra', 'dec', 'unit') parameters. Examples -------- >>> from astroquery.alfalfa import Alfalfa >>> from astropy import coordinates as coords >>> C = coords.SkyCoord('0h8m05.63s +14d50m23.3s') >>> agc = Alfalfa.query_region(C,'3 arcmin') Returns ------- result : AGC number for object nearest supplied position. """ coordinates = commons.parse_coordinates(coordinates) ra = coordinates.ra.degree dec = coordinates.dec.degree dr = Angle(radius).to('degree').value cat = self.get_catalog() # Use RA and DEC to find appropriate AGC if optical_counterpart: ra_ref = cat['RAdeg_OC'] dec_ref = cat['DECdeg_OC'] else: ra_ref = cat['RAdeg_HI'] dec_ref = cat['Decdeg_HI'] dra = np.abs(ra_ref - ra) \ * np.cos(dec * np.pi / 180.) ddec = np.abs(dec_ref - dec) sep = np.sqrt(dra ** 2 + ddec ** 2) i_minsep = np.argmin(sep) minsep = sep[i_minsep] # Matched object within our search radius? if minsep < dr: return cat['AGCNr'][i_minsep] else: return None def get_spectrum_async(self, agc): """ Download spectrum from ALFALFA catalogue. Parameters ---------- agc : int Identification number for object in ALFALFA catalog. ascii : bool Download spectrum from remote server in ASCII or FITS format? Returns ------- result : A file context manager See Also -------- get_catalog : method that downloads ALFALFA catalog query_region : find object in catalog closest to supplied position (use this to determine AGC number first) """ agc = str(agc).zfill(6) link = "%s/A%s.fits" % (self.FITS_PREFIX, agc) result = commons.FileContainer(link) return result @prepend_docstr_noreturns(get_spectrum_async.__doc__) def get_spectrum(self, agc): """ Returns ------- spectrum : `~astropy.io.fits.HDUList` Spectrum is in ``hdulist[0].data[0][2]`` """ result = self.get_spectrum_async(agc) hdulist = result.get_fits() return hdulist Alfalfa = AlfalfaClass() astroquery-0.2.4/astroquery/alfalfa/tests/0000755000077000000240000000000012505171566020732 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alfalfa/tests/__init__.py0000644000077000000240000000000012464660121023023 0ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alfalfa/tests/data/0000755000077000000240000000000012505171566021643 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alfalfa/tests/data/alfalfa_cat_small.txt0000644000077000000240000001020212464660121025776 0ustar adamstaff00000000000000AGCNr,Name,RAdeg_HI,Decdeg_HI,RAdeg_OC,DECdeg_OC,Vhelio,W50,errW50,HIflux,errflux,SNR,RMS,Dist,logMsun,HIcode,OCcode,NoteFlag 331061,456-013,0.01042,15.87222,0.00875,15.88167,6007,260,45,1.13,0.09,6.5,2.40,85.2,9.29,1,I,"" 331405,"",0.01375,26.01639,0.01458,26.01389,10409,315,8,2.62,0.09,16.1,2.05,143.8,10.11,1,I,"" 102896,"",0.02833,28.20194,0.02500,28.20194,16254,406,17,2.37,0.12,11.2,2.31,227.4,10.46,1,I,* 102574,"",0.03792,28.09528,0.00000,0.00000,-368,23,3,1.29,0.08,11.2,5.05,"","",9,U,* 102975,"",0.05125,29.02695,0.00000,0.00000,-367,23,3,2.85,0.07,26.7,4.69,"","",9,U,* 102571,"",0.07167,27.39972,0.07208,27.40083,4654,104,3,2.00,0.06,19.0,2.29,65.9,9.31,1,I,"" 102976,"",0.07917,28.99195,0.00000,0.00000,-365,26,2,2.53,0.11,18.3,5.76,"","",9,U,* 102728,"",0.08833,31.01056,0.08917,31.02194,566,21,6,0.31,0.03,7.5,1.92,9.1,6.78,1,I,"" 102575,"",0.11667,28.14583,0.00000,0.00000,-371,33,7,0.47,0.03,8.6,2.11,"","",9,U,* 12896,478-010,0.12542,26.32445,0.13083,26.32528,7653,170,10,3.14,0.08,22.0,2.44,104.5,9.91,1,I,* 102729,"",0.13375,30.86444,0.13333,30.86917,4618,53,6,0.70,0.04,10.5,2.02,65.4,8.85,1,I,"" 102576,"",0.14708,26.45333,0.00000,0.00000,-430,21,2,0.60,0.04,11.7,2.50,"","",9,U,* 102730,"",0.16708,31.93611,0.16458,31.93833,12631,79,23,0.66,0.05,7.3,2.25,175.8,9.68,1,I,"" 102578,"",0.17625,26.55305,0.00000,0.00000,-429,22,3,0.67,0.04,12.8,2.44,"","",9,U,* 101866,"",0.20875,14.27000,0.19958,14.27750,10877,291,149,0.79,0.11,4.1,2.52,150.3,9.62,2,I,* 12901,499-035,0.24792,28.90861,0.24542,28.91139,6896,395,5,5.03,0.11,25.2,2.24,93.7,10.02,1,I,* 102731,FGC290A,0.28875,30.87250,0.27667,30.87972,7366,257,8,1.33,0.08,8.9,2.08,100.5,9.50,1,I,"" 102977,"",0.28625,28.79389,0.00000,0.00000,-364,22,3,2.03,0.11,13.8,6.64,"","",9,U,* 102861,"",0.29208,32.07361,0.00000,0.00000,-181,22,0,7.30,0.06,55.0,4.69,"","",9,U,* 102732,"",0.31167,31.37167,0.31250,31.37417,12532,292,5,1.54,0.09,9.1,2.20,174.3,10.04,1,I,"" 101869,"",0.36292,14.40861,0.38083,14.40750,12639,183,16,1.00,0.09,6.4,2.57,175.4,9.86,1,I,* 102733,"",0.37417,31.23833,0.37500,31.23417,12581,134,12,1.03,0.08,8.6,2.29,175.0,9.87,1,I,"" 12911,N7806,0.38125,31.44139,0.37542,31.44194,4767,231,23,1.40,0.08,9.4,2.19,67.5,9.18,1,I,* 331082,433-016,0.39375,15.08000,0.39167,15.08167,6368,118,8,2.72,0.08,21.4,2.60,85.9,9.67,1,I,"" 748776,"",0.42667,13.83861,0.42208,13.84250,6337,53,5,0.65,0.05,8.7,2.27,89.9,9.09,1,I,"" 102862,"",0.42833,30.70528,0.00000,0.00000,-193,22,0,3.33,0.05,31.8,4.27,"","",9,U,* 102734,"",0.42792,32.10778,0.42333,32.10778,12560,226,9,1.61,0.08,10.7,2.23,174.8,10.06,1,I,"" 102978,"",0.46917,29.32472,0.00000,0.00000,-368,26,2,5.34,0.09,37.5,5.96,"","",9,U,* 101873,"",0.48292,16.14167,0.47375,16.13778,12786,256,17,1.34,0.10,7.3,2.57,177.6,10.00,1,I,"" 102735,"",0.50083,30.98306,0.50542,30.98278,2878,152,2,1.79,0.07,13.8,2.34,40.6,8.84,1,I,* 102863,"",0.52292,31.70639,0.00000,0.00000,-177,22,0,8.27,0.08,56.1,5.80,"","",9,U,* 102979,"",0.53167,29.54472,0.00000,0.00000,-370,26,2,6.98,0.09,53.0,5.55,"","",9,U,* 749126,"",0.55500,16.05500,0.00000,0.00000,-365,22,0,6.82,0.06,55.6,4.90,"","",9,U,* 101877,"",0.56000,14.48917,0.56167,14.48778,5149,185,4,2.97,0.09,19.8,2.46,72.9,9.57,1,I,"" 102980,"",0.59167,28.31194,0.58042,28.33056,6819,45,6,0.72,0.04,11.2,2.09,92.6,9.16,1,I,"" 12920,478-014,0.59625,27.21417,0.59583,27.21056,7613,281,2,2.88,0.10,16.0,2.40,103.9,9.86,1,I,"" 102864,"",0.62125,31.03111,0.00000,0.00000,-188,20,0,7.81,0.08,58.1,5.77,"","",9,U,* 749127,"",0.68625,13.87444,0.00000,0.00000,-173,27,1,2.48,0.05,20.8,4.07,"","",9,U,* 100006,499-039,0.70958,31.48639,0.70917,31.48500,4947,109,2,1.20,0.06,12.1,2.11,70.1,9.14,1,I,"" 100008,Eder Dw,0.72583,29.57972,0.73500,29.58417,4842,119,7,1.33,0.05,15.5,1.75,68.5,9.17,1,I,"" 101879,"",0.73000,14.36528,0.72958,14.36000,5758,62,10,0.36,0.05,4.4,2.28,81.6,8.75,2,I,"" 102981,"",0.73708,28.29833,0.73167,28.27722,4583,65,15,0.53,0.05,6.5,2.25,64.8,8.72,1,I,* 748777,"",0.78667,15.04667,0.79583,15.04445,13800,98,10,0.88,0.07,7.8,2.51,192.1,9.88,1,I,"" 7,I5381,0.79417,15.96778,0.79667,15.96500,11223,678,22,3.99,0.16,10.9,2.42,155.2,10.36,1,I,* 100051,433-025,2.00375,14.83972,2.02333,14.83972,13632,136,13,0.77,0.08,5.6,2.63,189.7,9.81,2,I,"" astroquery-0.2.4/astroquery/alfalfa/tests/data/alfalfa_sp.fits0000644000077000000240000024310012464660121024614 0ustar adamstaff00000000000000SIMPLE = T /Dummy Created by MWRFITS v1.4a BITPIX = 8 /Dummy primary header created by MWRFITS NAXIS = 0 /No data is associated with this header EXTEND = T /Extensions may (will!) be present END XTENSION= 'BINTABLE' /Written by IDL: Thu Jul 8 12:45:08 2010 BITPIX = 8 / NAXIS = 2 /Binary table NAXIS1 = 32768 /Number of bytes per row NAXIS2 = 1 /Number of rows PCOUNT = 0 /Random parameter count GCOUNT = 1 /Group count TFIELDS = 4 /Number of columns COMMENT COMMENT *** End of mandatory fields *** COMMENT COMMENT COMMENT *** Column names *** COMMENT TTYPE1 = 'VHELIO ' /Heliocentric velocity [km/s] TTYPE2 = 'FREQ ' /Radio frequency [MHz] TTYPE3 = 'FLUXDENS ' /Flux Density [mJy] TTYPE4 = 'BASELINE ' /Subtracted Polynomial baseline fit TUNIT1 = 'KM/S ' /Units of velocity axis TUNIT2 = 'MHz ' /Units of frequency axis TUNIT3 = 'mJy ' /Units of flux density axis TUNIT4 = 'mJy ' /Units of subtracted baseline COMMENT COMMENT *** Column formats *** COMMENT TFORM1 = '1024D ' / TFORM2 = '1024D ' / TFORM3 = '1024D ' / TFORM4 = '1024D ' / TELESCOP= 'Arecibo Radio Telescope' /Designation of Telescope INSTRUME= 'ALFA ' /Instrument in use BEAM = '3.5x3.8 ' /Beam size [arcminutes] OBJECT = 'AGC 100051' /Name of observed object ORIGIN = 'CORNELL ' /File creation location RA = 2.0037095 /Right Ascension in degrees DEC = 14.839847 /Declination in degrees EQUINOX = 2000.00 /Epoch for coordinates (years) RESTFRQ = 1.4204058E+09 /Rest Freqeuncy [Hz] COMMENT BW = 24.975586 /Bandwidth [MHz] CHAN = 1024 /Number of spectral channels COMMENT COMMENT Arecibo Legacy Fast ALFA Survey COMMENT Cornell University COMMENT http://egg.astro.cornell.edu/alfalfa/ COMMENT Last updated: Thu Jul 8 12:45:08 2010 G. Hallenbeck COMMENT ALFALFA archive at http://arecibo.tc.cornell.edu/hiarchive/alfalfa/ COMMENT This spectrum has been baselined. END @Ñ~•¡æ@Ñ|©8à @Ñ{6ß“-@Ñyĉºw€@ÑxR7UÝ@ÑvßèeQT@ÑumœèÈ@ÑsûTà4ª@Ñr‰KŠè@ÑqÏ*¾„@Ño¤‘}Âë@Ñn2WD‹ö@ÑlÀ  "@ÑkMí-:%@ÑiÛ½O @Ñhiäf7@Ñf÷gíLž@Ñe…Bi­S@Ñd Y|@Ñb¡¼¬Ÿ@Ña.æ“2z@Ñ_¼ÎÝ@@Ñ^Jºš ¤@Ñ\Ø©ÊH\@Ñ[fœm¨ @ÑYô’„?@ÑX‚Œ ¡¯@ÑW‰ #@ÑUž‰y–î@ÑT,[ñ@ÑRº”±%@ÑQHŸy&e@ÑOÖ­³é @ÑNd¿a`p@ÑLòÔ€Z@ÑK€í€eZWÚ@Ñ= d†æ@Ñ;œÞàÊ_@Ñ:+ Ïø@Ñ8¹f/]h@Ñ7G¯”Q@Ñ5ÕûE®f@Ñ4dJûŸK@Ñ2òž#Z£@Ñ1€ô¼ÔF@Ñ0NÇÿ²@Ñ.¬DЯ@Ñ-, 3:ß@Ñ+ºq“1ä@Ñ*HÙd©˜@Ñ(×D§•y@Ñ'e³[é_@Ñ%ô%˜Ü@Ñ$‚›—¤@Ñ# Ùk@Ñ!ŸšQç@Ñ .„ôº@Ѽ“൙@ÑK­ˆJ@ÑÙ¤ë`L@Ñh2š1Š@Ñöùï‚@Ñ…XJŽ@ÑðLÐ@Ñ¢‹¾;k@Ñ1*¡1¤@Ñ¿Ìô× @ÑNr¹“@ÑÝíþÃ@Ñ kÈ“hT@Ñ úx©Oú@Ñ ‰,/©i@Ñ ã&hE@Ѧ€f@Ñ5[då^@ÑĬŠò@ÑRáddÅ@ÑᩌfŸ@Ñpu$„4@ÐþÿD,±9@Ðýޤáb@ÐüìS@Ðú«ÅåÒ@Ðù:¢­ ”@Ð÷É‚äË`@ÐöXfŒRÆ@ÐôçM£“ @Ðóv8*@Ðò&!J@Ðð”‡3–@Ðï# \ß)@Ðí²¢¸@ÐìAVž @ÐêÏÿz˜¬@Ðé_ ê|@Ðçî‡,@Ðæ}‚br@Ðå cp@Ðã›.³£¤@Ðâ*Brñ @Ðà¹Y¡KÛ@ÐßHt>§í@ÐÝ×’Jøö@ÐÜf³Æ2ª@ÐÚõذH¿@ÐÙ… .ú@ÐØ,ÐÙ@ÐÖ£\:»@ÐÕ2ެGÎ@ÐÓÁÄ¿óÛ@ÐÒPþB2¼@ÐÐà;2ø7@ÐÏo{’7Þ@ÐÍþ¿_å›@ÐÌŽ›õ@ÐËQFZ@ÐɬŸ_3@ÐÈ;ðåóZ@ÐÆËEÛD@ÐÅZž>O”@ÐÃéú¨"@ÐÂyYO ¥@ÐÁ»üpÏ@п˜"Èi@о'‹¡L@м¶ø˜!@лFhý v@йÕÜÏ´]@иeTs@жôξ ~@е„LÙÉ2@дÎcX@в£SY¶@б2Û½û@ЯÂg $@ЮQöÎ¥ž@Ьá‰zÿl@Ыq”¡1@Ъ¹~´@ШV‹©@Чöp»ý@Ð¥¯š?R@Ф?AzU€@ТÎì"¦>@С^š7é?@ПîKºp@О~©r@Ð ¹æ @ЛtÍx-@К-4¿a@И¼ö¤¯–@ЗL¼³<€@Е܆.Yæ@ДlSû@Ð’ü#jC@Б‹÷*šÈ@ÐÎWå@ÐŽ«¨ð¸b@Ð;†ö8@ЋËhgò–@Њ[MEÛÛ@Јë5ç@Ї{!F ¡@І h5¯@Є›ö_ @Ѓ*øð{@кòV|@ЀJï(V2@Ð~Úïeý?@Ð}jóe&@Ð{úú$ˆ@Ðz‹¥FQ@Ðy‘§5@Ðw«#é—ü@Ðv;8­ ’@ÐtËPÛø™@Ðs[lvOê@Ðqë‹|^@Ðp{­í½@Ðo ÓÉ_Î@Ðm›ýêX@Ðl,)ã!@Ðj¼Yá~@ÐiLjnÚ@ÐgÜÄ^iV@Ðflþ½aT@Ðdý<‡J™@Ðc}¼í@ÐbÂ[À<@Ð`® f4:@Ð_>UÛh®@Ð]Τ»Q„@Ð\^÷âq@ÐZïL»`@ÐY¥ÚÌ@ÐXe +@ÐV bYÃÌ@ÐU0ŸæŒ@ÐSÁ,‚hD@ÐRQ–¶<ß@ÐPâTX@ÐOru\­¸@ÐNéÏ1–@ÐL“a«×™@ÐK#Üò“u@ÐI´[£Y@ÐHDݾ1@ÐFÕcBв@ÐEeì1jq@ÐCöx‰Ý@ÐB‡L¢@ÐA›xÈ@Ð?¨2 Ñm@Ð>8Ì .k@Ð<Éiv'‰@Ð;Z H° @Ð9ꮄ½x@Ð8{V*Aé@Ð7 91à@Ð5œ¯±$@Ð4-a“#{@Ð2¾Þ ¿@Ð1NÏ’0Û@Ð/ß‹¯ƒ˜@Ð.pK5ø»@Ð-%„B@Ð+‘Ô~ã@Ð*"ž?­w@Ð(³kj2×@Ð'D;ýï@Ð%Õùâs@Ð$eç^ôb@Ð"öÂ,Ç‚@Ð!‡ cO›@Ð ‚€™@Щg NT@Ð:Oz¬“@ÐË;SV@Ð\*”êP@Ðí>±[@Ð~PØb@Ð ËSQ@Р ®Ë@Ð1 ùà@Р¬AV@ÐSÇ‘ö@ÐäJù½@Ð u-6lq@Ð >‰Ýí@Ð —SEB@Ð (khŒØ@й†ó±æ@ÐJ¥æ¥4@ÐÛÈAZ›@ÐlîÆ@Ðþ-Û;@ÐC¿Ž'@Ïþ@çq¥#@ÏûcN38ï@Ïø…»Ã¿f@Ïõ¨0# @ÏòÊ«QBÕ@Ïïí-N{@Ïí¶m—@Ïê2E³Dÿ@ÏçTÜ}g@ÏäwyQþ¦@ÏášV°m@ÏÞ¼È)z–@ÏÛßyÊD­@ÏÙ28öŠ@ÏÖ$ñuwá@ÏÓG·°¬@ÏÐj„Wˆz@ÏÍWüç"@Ïʰ2o´W@ÏÇÓ¯×Ì@ÏÄõû½9|@ÏÂê—Àö@Ï¿;à?V6@ϼ^ܳàî@ϹßõH¬@϶¤êum@ϳÇúÞO@ϰë…½.@Ï®0ù§”@Ï«1V9ö@ϨT‚FV@Ï¥wµ^a@Ï¢šîÄGã@ÏŸ¾/54@Ïœávr d@ÏšÄz¶ì@Ï—(O$@Ï”Ktï#À@Ï‘n×Zµ–@ÏŽ’@‘¹Y@Ï‹µ°”@ψÙ'a¶N@Ï…ü¤ú~å@σ )^XÆ@Ï€C´+É@Ï}gF†ß|@ÏzŠßK\@Ïw®~Úˆâ@ÏtÒ%4N@ÏqõÒX“h@Ïo†G@—@Ïl=A=¥@Ïiaƒr"@Ïf„ÊÐÆ @Ïc¨™è!4@Ï`ÌoÉkv@Ï]ðLtŒ…@Ï[/él6@ÏX8'ò‡@ÏU\ 0N@ÏR€’@ÏO¤œ{.@ÏLÈ©ö@ÏIì.’@ÏG&$x´@ÏD4?ãè4@ÏAX`l= @Ï>|‡½^ó@Ï; µ×5à@Ï8Ä깩‰@Ï5é&d¢ @Ï3 hØû@Ï01²À*@Ï-Vµº@Ï*zXãÏ^@Ï'ž¶wõ@Ï$ÃÔ‰@Ï!ç…øš@Ï ÷ã¼e@Ï0p— y@ÏTð÷@ÏyvTе@Ïž^`f@Ï—/@Ï ç1ÇÔm@Ï Ó'B–@Ï0{M³4@ÏU*;h@Ïyßï;ä@Îÿžœj#¥@ÎüÃ_«­@Îùè)³Át@Î÷ ú‚G2@Îô1Ò&µ@ÎñV°rGû@Îî{•“’Ú@Îë zï*@ÎèÅt(Dæ@Îåêm›{æ@ÎãmÔ|&@Îà4tÓ-}@ÎÝY‚—wÂ@ÎÚ~—!Bò@Î×£²pw@ÎÔÈÔ„ü@ÎÑíý^¹i@ÎÏ,ý—†@ÎÌ8ca~ @ÎÉ] ŠU@ÎÆ‚äxe@Îè/*t @ÎÀÍ€¡‹¿@νòØÝ3¢@λ7ÝS°@θ=¡Óœ@εc *›b@βˆ}w’ý@ί­÷ˆ¢Ž@άÓx]±¤@Ωøÿö¨‚@ΧŽSnÝ@ΤD#sìù@Ρi¿X d@Ξaÿ¯>@Λµ jÄ@Θڻ™/@ΖrŠÙú@Γ&0?¬"@ÎKô·[@Îq¿òeÈ@Ί—‘ðb@·½j°œ@΄ãJ3É¥@΂ 0yŽE@Î/ÑÞ@Î|UL|m@Îy{ Ùuî@Îv¡ (¦7@ÎsÇ9õD@Îpí$ K7@În9¢æ@Îk9Uù«r@Îh_y…³@Îe…¢í£@Îb«Ó‰@@Î_Ò æœ©@Î\øI·@ÎZå­d@ÎWDÙ‡Ñ@ÎTk+éxÖ@ÎQ‘… è“@ÎN·äñ>à@ÎKÞK–c¸@ÎI¸ü?a@ÎF+-"¹@ÎCQ¨ º\@Î@x)±)ð@Î=ž²ïú@Î:ÅA@ôæ@Î7ë×) @@Î5sÑZs@Î299‹0@Î/_Áaš¾@Î,†rIpô@Î)­)ðõò@Î&ÓèX´@Î#ú­~¬@Î!!yd­s@ÎHL ý@Îo%n„€@Ζ’*F@μìt×@ÎãÚr­@Î Îvåj@Î 1É–@Î XËsï¾@ÎÔWq@Φãk6n@ÎÍù„th@Íþõ[ù¤@Íü9ñ®B@ÍùCdEyõ@Íöj•WE'@Íó‘Í&÷®@Íð¹ ´yÑ@ÍíàPÿ³B@ÍëŒj@Íè.ïÎìý@ÍåVIR½c@Íâ}©“åš@Íߥ’Mw@ÍÜÌ~MÝA@ÍÙóòÆ|ó@Í×mü®@ÍÔBïîŒn@ÍÑjxÌR@ÍÎ’ ¼}@Í˹ž2Dé@ÍÈá;M·@ÍÆÞ¸¿@ÍÃ0‰€²@ÍÀX:0{ @ͽò–)@ͺ§°˜¹í@Í·ÏuæÎ²@Í´÷Að¼O@Ͳ¶jä@ͯFî7·@ͬnÎt«Ã@Í©–µm(@ͦ¾£ Ñä@Í£æ—ß;@Í¡’º(@Íž6”ŸvÍ@Í›^?Ñ$@͘†¬›™@Í•®Â±,@Í’Ößü€@Íÿ oX@Í'-Slª@ÍŠO^SÜN@͇w–¦ˆ@Í„ŸÔƒ³ž@ÍȲëh@Í~ðeœ6O@Í|¸?|)@ÍyAœ¥=@Íviq³™«@Ís‘Ø„A“@ÍpºF…@ÍmâºRLU@Ík 5Oo@Íh3·†@Íe\?uɹ@Íb„Ξ±*@Í_­d€¥@Í\Ö@ÍYþ¤oR @ÍW'N{Ü•@ÍTOÿAŽ@ÍQx¶¾ß­@ÍN¡tõ)5@ÍKÊ9ã×ÿ@ÍHóŠÔt@ÍF×ê@ÍCD±V½@Í@mЬ÷@Í=–wWñ]@Í:¿d— @Í7èXå~@Í5S§‚@Ì×hYÎQ@ÌÔ’8©œÛ@ÌѼ9N`@ÌÎæ }M˜@ÌÌýuƒ@ÌÉ9÷!ÖË@ÌÆc÷‚1@ÌÃþ–z @ÌÀ¸ ^š@̽â ÚyZ@Ì» < 0@̸6]í¾@̵`†ƒ¥J@Ì²ŠµÍ”@̯´ëÊËG@̬ß({3C@̪ kÞ´,@̧3µõ6H@̤^¾¡Ú@Ì¡ˆ^:ßM@Ìž²¼iÖ@Ì›Ý!Kp3@Ì™Œß”U@Ì–1ÿ&+"@Ì“\x@̆÷ÊRD@̱~'³"@ÌŠÜ 7'Á@̈žø˜e@Ì…19kí@Ì‚[Ú‘d@̆‚gæ@Ì|±0ðZ@ÌyÛæ*S_@Ìw¢º†@Ìt1d²w¼@Ìq\.sD@Ìn†ýÿ•‰@Ìk±Ô¯Æ«@Ìhܲîï@Ìf–"ö¿@Ìc2€åÆa@Ì`]rYEô@Ì]ˆj}^@ÌZ³iQö¹@ÌWÞnÖøw@ÌU { K_@ÌR4ñ×ÿ@ÌO_§‡†y@ÌLŠÇÍ?@ÌIµîÂê3@ÌFáhp!@ÌD P½¹F@ÌA7‹Â­Â@Ì>bÍw6@Ì;ŽÛ:D@Ì8¹dî£@Ì5亱X†@Ì3#Bê@Ì0;zDJ±@Ì-fäXF@Ì*’T“SÉ@Ì'½ËÁ%¤@Ì$éI¶@Ì"Î(íš@Ì@Yb´e@ÌkëJòä@Ì—ƒá‘^@ÌÃ#&x=@ÌîÉÄ@ÌuºÀ_@ÌF) òR@Ì qã@Ì£±ûÂ@ÌÉk £ï@Ìõ9îÑ@Ì! ÄÄÒ@ËýLé&]@ËúxË4³¶@Ë÷¤³ðG@ËôУY³U@Ëñü™oÞI@Ëï(–3@ËìT™£i@Ë連¿ðh@Ëæ¬´‰‚«@ËãØËÿ³œ@Ëáê"kÉ@ËÞ1ñ“x@ËÛ]:mí@ËØ‰l”Ò“@ËÕµ¥hº÷@ËÒáäè´^@ËÐ+§@ËÍ:wì{r@ËÊfËp@ËÇ“%Ÿk?@ËÄ¿†zWY@ËÁëîÆË@Ë¿\2¡Ü@˼DÑÑ@˹qL˜<É@˶ÎËÍS@˳ÊWªkH@˰öç3þÇ@Ë®#}hpƒ@Ë«PG¨œ@˨|½Ñ¢@Ë¥©h ý@Ë¢Öå @Ë Ðnr[@Ë/Ž¢) @Ëš\S€»@Ë—‰)ô@Ë”µñ:D´@Ë‘âÊQÑ@Ë©œ9“@ËŒ<Ëä<@ˉi|¥:@ˆ–p($¦@˃ÃjT‹@Ë€ðk*V\@Ë~r©nÁ@Ë{J€Ñ¼Ò@Ëxw•£(Ó@Ëu¤±›x@ËrÑÓ@ý@Ëoþü 5ç@Ëm,+‚.„@ËjYaŸÏl@Ëg†žf,@Ëd³áÔ«å@Ëaá+ë¸K@Ë_|«Ç@Ë\;Ô—ž@ËYi2";ƒ@ËV––Ùâº@ËSÄ9uÔ@ËPñt@Ý\@ËNìðš@ËKLlFÊö@ËHyòE"#@ËE§~êï‹@ËBÕ8t@Ë@¬,Žj@Ë=0LÈ1#@Ë:]ô ë¼@Ë7‹¡ô¦ë@Ë4¹V…K@Ë1ç¼ÀÒ@Ë/Óšð]@Ë,BœÂn@Ë)pkKH@Ë&žAïŸ@Ë#Ì•·@Ë ú³ŒD@Ë'êx)°@ËUÚâ܈@˃Ñó@˱Ϫ$@ËßÔ‰¾@Ë ß¦´@Ë ;ð°c”@Ë jý¨É@˘'ð^à@ËÆMˆn @ËôyÅ¿`@Êÿ"¬¨:ä@ÊüPæ/É;@Êù&\Ró@Êö­m-Àw@ÊóÛº£úx@Êñ ¾é`@Êî8i~uš@ÊëfÊâ‡Ø@Êè•2ë„@Êåá—à,@Êâòè÷^@Êà ’Þ6…@ÊÝOw†R@ÊÚ}ž´Ï1@Ê׬.•ù®@ÊÔÚÅî4@ÊÒ bC•u@ÊÏ8Ø@ÊÌf°ž@@ÊÉ•a’Ðå@ÊÆÄIX6@ÊÃò×£ @ÊÁ!œ Ë@ʾPh@ã@Ê»:‚ñ(@ʸ®hÀà@ʵÜòñX¿@ʳ Ù¡Q@ʰ:Åêƒ'@Ê­i¹Zæ¨@ʪ˜³m´ˆ@ʧǴ"ÕV@ʤö»z1 @Ê¢%És±ô@ÊŸTÞ>»@ÊœƒùLÀÎ@Ê™³, •@Ê–âC­F @Ê”rÐ|@Ê‘@¨”‡Ý@ÊŽoäút,@Ê‹Ÿ(É@ʈÎqªo:@Ê…ýÁôO@ʃ-ßQ?@Ê€\vk^B@Ê}‹Ú˜^ö@Êz»Ef;¡@Êwê¶ÔÜõ@Êu.ä+‚@ÊrI­”ù@Êoy2ärÅ@Êl¨¾Õ<½@ÊiØQfVK@Êgê—¨!@Êd7Ši©@Êag0Ú–¼@Ê^–Ýìæ@Ê[Æ‘M’@ÊXöKîY˜@ÊV& ß`@ÊSUÔo]Ã@ÊP…¢Ÿ'*@ÊMµwnVH@ÊJåRÜÓ«@ÊH4ê‡â@ÊEE—[Å@ÊBu ã7à@Ê?¥ÎŸ@Ê<ÔÿWªØ@Ê:€@Ê75 G%ô@Ê4e¬Ì<@Ê1•3°î]@Ê.ÅQSu@Ê+õu”HÎ@Ê)% sR„@Ê&UÑðzº@Ê#† ©Ù@Ê ¶HÄÈÝ@ÊæŽÀ0@ÊÚx„@ÊG,¢Ú@Êw…ÒÎþ@ʧå >@@ÊØL *@Ê ¹0L@Ê 9,¸„|@Êi¦úö$@Êš'Úm÷@ÊʯVÔÍ@Éþû=p@Éü+Ò&•@Éù\mx¹@Éögò@Éó½·ó¥'@Éðîg»'@ÉîàÄ@ÉëOÙ@²Œ@É耜=eY@Éå±eÖ’@Éââ6 Ä@Éà ÛA…@ÉÝCêG~€@ÉÚtÎOcØ@É×¥¸òÚ@ÉÔÖª1Ê#@ÉÒ¢ W@ÉÏ8 ¹³@ÉÌi¥’ŠÆ@ÉÉš±>x@ÉÆËÃ…jº@ÉÃüÜgK$@ÉÁ-ûäì@ɾ_!ûx@É»N­•õ@ɸÁúD›@ɵò»álj@ɳ#übö;@ɰUC~Êå@É­†‘4Òõ@ɪ·å„÷ @ɧé@o @É¥¡ó6±@É¢L #@ÉŸ}xÈÏV@Éœ®î"ë@É™àjï@É—ì‰d@É”Cu§#6@É‘u^,à@ÉŽ¦›®iÄ@É‹Ø8—Âà@ɉ Ü Â@Ɇ;†5l@Ƀm6éÆ@É€žî6nO@É}Ьö²@É{pš}@Éx4;°¡‰@Éuf _•ˆ@Ér—å¦ÔR@ÉoÉĆFt@Élû©ýÔÇ@Éj-– h"@Ég_ˆ´é@Éd‘ô@r@ÉaÃËW@É^õˆ:±@É\'•@dø@ÉYY¨Þ-Á@ÉV‹ÃX¿@ÉS½ãßΦ@ÉPð Cxq@ÉN"9>>®@ÉKTmÐ 5@ÉH†¨øÃÞ@ÉE¸ê¸T\@ÉBë3¤`@É@ûœÄ@É=O×&^@É:‚3™)á@É7´–I@É4æÿA·@É2om'¹@É/Kåà*¹@É,~bé3@É)°æˆ+@É&ãp¼ùô@É$‡‰ @É!H˜çÁ6@É{6Ý‹ @É­ÛhÏ£@Éà†‰w—@É8?k‰@ÉEðŠ”œ@Éx¯jÛ@É «tà(ë@É Þ@êe²@ɉzÒ@ÉCì½PÚ@ÉvÌ…ÐÄ@Èÿ©²âãE@ÈüÜŸÔq4@Èú“Zch@È÷Bt¢¹@ÈôuŽ#ý@Èñ¨•e«é@ÈîÛ£v@È´´É‘!@ȱESAî@È®xøL=Ç@È«¬£èiK@ȨàVY~@ȦÕ÷7@È£GÎ'+M@È {” Þ˜@ȯ`}ú@Èšã3ƒft@Ș  ³@È•JíAÕª@È’~Óúª/@ȲÁDs@@Ȍ浳@ÈŠ¯Š†„@ȇN°†¢B@È„‚¸V2@ȶÆ0Šã@È~êÚÞ)t@È|ö¾@ÈySêGs@Èv‡@H˜Ú@Ès»o6÷~@Èp蘆L_@Èn#àÀv@ÈkX#a|›@ÈhŒl)§@ÈeÀ¼Lp•@Èbõ™:b@È`)ouo¿@È]]Òàùª@ÈZ’<ÛÁB@ÈWÆ­e¯@ÈTû$~¬I@ÈR/¢&¡¯@ÈOd&]xj@ÈL˜±# @ÈIÍBwl«@ÈGÚZ\N@ÈD6xËУ@ÈAk˲Í@È>ŸÉYëÆ@È;Ô{vdA@È9 4!<@È6=óY·±@È3r¹ d@È0§…tôØ@È-ÜXWQ]@È+1Çc(@È(FÅ@È%zøPJ@È"¯åhñ0@ÈäÙñ7@ÈÓB3)@ÈNÔ @ȃÛP ¹@ȸé*ž,@Èíý’y@È#†3R@È X:Ú@È b§ @È®ºâ@È÷ÅÕA@È-ˆ"ß@ÇþbCÇHþ@Çû—Œ’œ³@ÇøÌÛê±@Çö1Íp@Çó7Ž<ÁÁ@Çðlñ7äÌ@Çí¢Z¾Â@Çê×ÊÑBŠ@Çè AoOY@ÇåB¾˜Ñ2@ÇâxBM±~@Çß­ÌØË@ÇÜã]Y0:@ÇÚô¯ ë@Ç×N’‘¶@ÇÔ„6ýq˜@Çѹáô£Œ@ÇÎï“v’Ž@ÇÌ%Kƒ'ã@ÇÉ[ L@ÇÆÏ;èz@ÇÃÆšçåü@ÇÀüm-x@Ǿ2EÞ¨5@Ç»h%)>ä@Ǹž ýÚÌ@ǵÓ÷\dÃ@dz êDÅë@ǰ?ã¶ç@Ç­uã²±r@Ǫ«ê8 î@ǧá÷Få°@Ç¥ ß!Ž@Ç¢N%ªª@”ñIÿU @”ñbÿU¡@”ñ{ÿU @”ñ”ÿU @”ñ­ÿU @”ñÆÿU¡@”ñßÿU @”ñøÿU @”òÿU @”ò*ÿUŸ@”òCÿU @”ò\ÿU @”òuÿU @”òŽÿU @”ò§ÿU @”òÀÿU¡@”òÙÿU @”òòÿU @”ó ÿU¡@”ó$ÿU @”ó=ÿUŸ@”óVÿU @”óoÿU¡@”óˆÿU @”ó¡ÿU @”óºÿU @”óÓÿU¡@”óìÿU @”ôÿU @”ôÿU @”ô7ÿU @”ôPÿU @”ôiÿU @”ô‚ÿU @”ô›ÿU¡@”ô´ÿU @”ôÍÿU¡@”ôæÿU @”ôÿÿU @”õÿU @”õ1ÿU¡@”õJÿUŸ@”õcÿU @”õ|ÿU @”õ•ÿU¡@”õ®ÿU @”õÇÿU @”õàÿU @”õùÿU @”öÿU @”ö+ÿU @”öDÿU @”ö]ÿU¡@”övÿU @”öÿU @”ö¨ÿUŸ@”öÁÿUŸ@”öÚÿU¡@”öóÿU @”÷ ÿU¡@”÷%ÿU @”÷>ÿU @”÷WÿU @”÷pÿU @”÷‰ÿU @”÷¢ÿU @”÷»ÿU @”÷ÔÿUŸ@”÷íÿU¡@”øÿU @”øÿU @”ø8ÿU @”øQÿUŸ@”øjÿU @”øƒÿU @”øœÿU @”øµÿU¡@”øÎÿU @”øçÿU @”ùÿU @”ùÿUŸ@”ù2ÿU @”ùKÿUŸ@”ùdÿU @”ù}ÿUŸ@”ù–ÿU @”ù¯ÿU @”ùÈÿU @”ùáÿU @”ùúÿU @”úÿU @”ú,ÿU @”úEÿU¡@”ú^ÿU @”úwÿU @”úÿU @”ú©ÿU @”úÂÿU @”úÛÿU @”úôÿU @”û ÿU @”û&ÿUŸ@”û?ÿU @”ûXÿU @”ûqÿU @”ûŠÿU @”û£ÿU @”û¼ÿU @”ûÕÿUŸ@”ûîÿU @”üÿU @”ü ÿU @”ü9ÿU @”üRÿU @”ükÿU @”ü„ÿU @”üÿU¡@”ü¶ÿU @”üÏÿU @”üèÿU @”ýÿU @”ýÿU @”ý3ÿU @”ýLÿU @”ýeÿU @”ý~ÿU @”ý—ÿU @”ý°ÿU @”ýÉÿU @”ýâÿU @”ýûÿU @”þÿU @”þ-ÿU¡@”þFÿUŸ@”þ_ÿU @”þxÿU @”þ‘ÿU @”þªÿU @”þÃÿUŸ@”þÜÿU @”þõÿU @”ÿÿU @”ÿ'ÿU @”ÿ@ÿUŸ@”ÿYÿU @”ÿrÿU @”ÿ‹ÿUŸ@”ÿ¤ÿUŸ@”ÿ½ÿU¡@”ÿÖÿU @”ÿïÿU @•ÿU @•!ÿUŸ@•:ÿU @•SÿU @•lÿU @•…ÿUŸ@•žÿU @•·ÿU @•ÐÿU @•éÿU @•ÿU @•ÿU @•4ÿU @•MÿU @•fÿU @•ÿU @•˜ÿU @•±ÿU @•ÊÿU @•ãÿU @•üÿU @•ÿU @•.ÿUŸ@•GÿU @•`ÿU @•yÿUŸ@•’ÿU @•«ÿU @•ÄÿU @•ÝÿU @•öÿU @•ÿU @•(ÿU @•AÿU @•ZÿU¡@•sÿU @•ŒÿU @•¥ÿU @•¾ÿU @•×ÿU @•ðÿU @• ÿU @•"ÿU @•;ÿU @•TÿU @•mÿU @•†ÿU @•ŸÿU @•¸ÿU @•ÑÿU @•êÿU @•ÿU @•ÿUŸ@•5ÿU @•NÿU @•gÿU @•€ÿU @•™ÿU @•²ÿU @•ËÿU @•äÿU @•ýÿU @•ÿU @•/ÿU @•HÿU @•aÿU @•zÿUŸ@•“ÿU¡@•¬ÿU @•ÅÿU @•ÞÿU¡@•÷ÿU @•ÿU @•)ÿUŸ@•BÿU @•[ÿU¡@•tÿU @•ÿU @•¦ÿU @•¿ÿU @•ØÿU @•ñÿU @• ÿU @•#ÿU @•<ÿUŸ@•UÿU @•nÿU @•‡ÿU @• ÿU¡@•¹ÿU @•ÒÿU @•ëÿU @• ÿU @• ÿU @• 6ÿU¡@• OÿU @• hÿUŸ@• ÿU @• šÿU¡@• ³ÿUŸ@• ÌÿU¡@• åÿU @• þÿU @• ÿU¡@• 0ÿU @• IÿU @• bÿU¡@• {ÿU @• ”ÿU @• ­ÿU @• ÆÿU @• ßÿU @• øÿU @• ÿU @• *ÿUŸ@• CÿU @• \ÿU @• uÿU @• ŽÿU @• §ÿU @• ÀÿU @• ÙÿU @• òÿU @• ÿU¡@• $ÿU¡@• =ÿU¡@• VÿU @• oÿU @• ˆÿU @• ¡ÿU¡@• ºÿU @• ÓÿU @• ìÿUŸ@• ÿUŸ@• ÿU @• 7ÿU @• PÿU¡@• iÿU @• ‚ÿUŸ@• ›ÿU @• ´ÿU¡@• ÍÿU @• æÿU @• ÿÿU @•ÿU @•1ÿU @•JÿU @•cÿU @•|ÿU @••ÿU @•®ÿU @•ÇÿU @•àÿU @•ùÿU @•ÿU @•+ÿU @•DÿUŸ@•]ÿU @•vÿU @•ÿU @•¨ÿU @•ÁÿU @•ÚÿU @•óÿU @• ÿU @•%ÿU @•>ÿU @•WÿU @•pÿU @•‰ÿU @•¢ÿU @•»ÿU @•ÔÿU @•íÿU @•ÿU @•ÿU¡@•8ÿUŸ@•QÿU @•jÿU @•ƒÿU @•œÿU @•µÿU @•ÎÿU @•çÿU @•ÿU¡@•ÿU @•2ÿUŸ@•KÿU¡@•dÿU @•}ÿU¡@•–ÿU @•¯ÿU @•ÈÿU @•áÿU @•úÿU @•ÿU @•,ÿUŸ@•EÿUŸ@•^ÿU @•wÿU @•ÿU @•©ÿU @•ÂÿU @•ÛÿU @•ôÿU @• ÿU @•&ÿUŸ@•?ÿU @•XÿU @•qÿU @•ŠÿU @•£ÿU @•¼ÿU @•ÕÿU @•îÿU @•ÿUŸ@• ÿU @•9ÿU¡@•RÿU¡@•kÿUŸ@•„ÿU @•ÿU @•¶ÿU @•ÏÿU @•èÿU @•ÿU @•ÿU @•3ÿU @•LÿUŸ@•eÿUŸ@•~ÿU @•—ÿU¡@•°ÿU @•ÉÿU @•âÿU @•ûÿU¡@•ÿUŸ@•-ÿU @•FÿU @•_ÿU @•xÿU @•‘ÿU @•ªÿU @•ÃÿU @•ÜÿU¡@•õÿU @•ÿU @•'ÿU @•@ÿU¡@•YÿU¡@•rÿU @•‹ÿU @•¤ÿU @•½ÿU @•ÖÿU @•ïÿU @•ÿU @•!ÿU @•:ÿU @•SÿU¡@•lÿU @•…ÿU @•žÿU¡@•·ÿU @•ÐÿU @•éÿU @•ÿU @•ÿU @•4ÿU @•MÿU @•fÿU @•ÿU @•˜ÿU¡@•±ÿUŸ@•ÊÿU @•ãÿU @•üÿU @•ÿU @•.ÿU @•GÿU @•`ÿUŸ@•yÿU¡@•’ÿU @•«ÿU @•ÄÿU @•ÝÿU @•öÿU @•ÿU @•(ÿU @•AÿU @•ZÿU @•sÿU @•ŒÿUŸ@•¥ÿU @•¾ÿU @•×ÿU @•ðÿU¡@• ÿU @•"ÿU¡@•;ÿU @•TÿU @•mÿU @•†ÿU¡@•ŸÿU @•¸ÿU @•ÑÿU @•êÿU @•ÿU @•ÿU @•5ÿU @•NÿU @•gÿU @•€ÿU @•™ÿU @•²ÿUŸ@•ËÿU @•äÿU @•ýÿU @•ÿU @•/ÿU @•HÿU @•aÿU¡@•zÿU @•“ÿU @•¬ÿU @•ÅÿU @•ÞÿU @•÷ÿU @• ÿUŸ@• )ÿU @• BÿU @• [ÿU @• tÿU¡@• ÿU @• ¦ÿUŸ@• ¿ÿU @• ØÿU @• ñÿU @•! ÿU @•!#ÿUŸ@•!<ÿU @•!UÿU @•!nÿU @•!‡ÿU @•! ÿU @•!¹ÿU @•!ÒÿU @•!ëÿU @•"ÿU @•"ÿU @•"6ÿU @•"OÿU @•"hÿU @•"ÿU¡@•"šÿU¡@•"³ÿU¡@•"ÌÿUŸ@•"åÿU @•"þÿU @•#ÿU¡@•#0ÿU @•#IÿUŸ@•#bÿUŸ@•#{ÿU @•#”ÿU @•#­ÿU @•#ÆÿUŸ@•#ßÿU @•#øÿU @•$ÿU @•$*ÿU @•$CÿU @•$\ÿU @•$uÿUŸ@•$ŽÿU @•$§ÿU @•$ÀÿU @•$ÙÿU¡@•$òÿU @•% ÿU @•%$ÿU @•%=ÿU @•%VÿU @•%oÿU @•%ˆÿU @•%¡ÿU @•%ºÿU @•%ÓÿU @•%ìÿU¡@•&ÿUŸ@•&ÿU @•&7ÿU @•&PÿU @•&iÿU @•&‚ÿU @•&›ÿU @•&´ÿU @•&ÍÿU @•&æÿU @•&ÿÿU @•'ÿUŸ@•'1ÿU @•'JÿU @•'cÿUŸ@•'|ÿU @•'•ÿU @•'®ÿU @•'ÇÿU @•'àÿU @•'ùÿU @•(ÿU @•(+ÿUŸ@•(DÿU @•(]ÿUŸ@•(vÿU @•(ÿU @•(¨ÿU @•(ÁÿUŸ@•(ÚÿU @•(óÿU @•) ÿU @•)%ÿU @•)>ÿU¡@•)WÿU @•)pÿU @•)‰ÿU @•)¢ÿU @•)»ÿU @•)ÔÿUŸ@•)íÿU @•*ÿU @•*ÿU @•*8ÿU @•*QÿU @•*jÿU¡@•*ƒÿU @•*œÿU @•*µÿU @•*ÎÿU @•*çÿU @•+ÿU @•+ÿU @•+2ÿU @•+KÿU @•+dÿU¡@•+}ÿU @•+–ÿU @•+¯ÿU @•+ÈÿU @•+áÿU @•+úÿU @•,ÿU @•,,ÿU @•,EÿU¡@•,^ÿUŸ@•,wÿU @•,ÿU @•,©ÿU @•,ÂÿU @•,ÛÿU @•,ôÿUŸ@•- ÿU @•-&ÿU @•-?ÿU @•-XÿU @•-qÿU @•-ŠÿU @•-£ÿU @•-¼ÿU @•-ÕÿU @•-îÿU @•.ÿU @•. ÿU @•.9ÿU @•.RÿU @•.kÿU @•.„ÿU @•.ÿUŸ@•.¶ÿU @•.ÏÿU @•.èÿU @•/ÿU @•/ÿU @•/3ÿU @•/LÿU @•/eÿU @•/~ÿU @•/—ÿU @•/°ÿU @•/ÉÿU @•/âÿUŸ@•/ûÿU @•0ÿU @•0-ÿU @•0FÿU @•0_ÿU @•0xÿU @•0‘ÿU @•0ªÿU @•0ÃÿU @•0ÜÿU @•0õÿU @•1ÿU @•1'ÿUŸ@•1@ÿU @•1YÿU @•1rÿU @•1‹ÿU @•1¤ÿU @•1½ÿU @•1ÖÿU¡@•1ïÿUŸ@•2ÿU @•2!ÿU @•2:ÿU @•2SÿU¡@•2lÿU @•2…ÿU @•2žÿU @•2·ÿU @•2ÐÿU @•2éÿU @•3ÿU @•3ÿU @•34ÿU @•3MÿU @•3fÿU @•3ÿU¡@•3˜ÿU @•3±ÿU @•3ÊÿU @•3ãÿU @•3üÿU @•4ÿU @•4.ÿU @•4GÿU¡@•4`ÿU @•4yÿU @•4’ÿU @•4«ÿU @•4ÄÿUŸ@•4ÝÿU @•4öÿU¡@•5ÿU @•5(ÿU @•5AÿU @•5ZÿU @•5sÿUŸ@•5ŒÿU @•5¥ÿUŸ@•5¾ÿU @•5×ÿU @•5ðÿU¡@•6 ÿU¡@•6"ÿU @•6;ÿU @•6TÿU @•6mÿU @•6†ÿU @•6ŸÿU @•6¸ÿU @•6ÑÿU @•6êÿU @•7ÿU @•7ÿU @•75ÿU @•7NÿU @•7gÿU @•7€ÿU¡@•7™ÿU @•7²ÿU @•7ËÿU @•7äÿU @•7ýÿU @•8ÿU @•8/ÿU @•8HÿU¡@•8aÿU @•8zÿU @•8“ÿU @•8¬ÿU @•8ÅÿU¡@•8ÞÿU @•8÷ÿU @•9ÿU @•9)ÿU @•9BÿU @•9[ÿU @•9tÿU @•9ÿU @•9¦ÿU @•9¿ÿU @•9ØÿU @•9ñÿUŸ@•: ÿU @•:#ÿU @•:<ÿU @•:UÿU @•:nÿUŸ@•:‡ÿU @•: ÿU @•:¹ÿU @•:ÒÿU @•:ëÿU @•;ÿU @•;ÿU @•;6ÿU @•;OÿU @•;hÿU @•;ÿU @•;šÿU¡@•;³ÿU @•;ÌÿUŸ@•;åÿUŸ@•;þÿU @•<ÿU @•<0ÿU @• ÿU @•>$ÿU¡@•>=ÿU @•>VÿU @•>oÿU @•>ˆÿU¡@•>¡ÿU @•>ºÿU @•>ÓÿU¡@•>ìÿU @•?ÿU @•?ÿU @•?7ÿU @•?PÿUŸ@•?iÿU @•?‚ÿU @•?›ÿU @•?´ÿUŸ@•?ÍÿUŸ@•?æÿU @•?ÿÿU @•@ÿU @•@1ÿU @•@JÿU @•@cÿUŸ@•@|ÿU @•@•ÿU¡@•@®ÿU @•@ÇÿU @•@àÿU @•@ùÿU @•AÿU @•A+ÿU @•ADÿU @•A]ÿU @•AvÿU @•AÿU @•A¨ÿU @•AÁÿU @•AÚÿU @•AóÿU¡@•B ÿU @•B%ÿU @•B>ÿU @•BWÿU @•BpÿU @•B‰ÿU @•B¢ÿU @•B»ÿU¡@•BÔÿU @•BíÿU @•CÿU @•CÿU @•C8ÿU @•CQÿU @•CjÿU @•CƒÿU @•CœÿU @•CµÿU @•CÎÿUŸ@•CçÿUŸ@•DÿU @•DÿU @•D2ÿUŸ@•DKÿU @•DdÿUŸ@•D}ÿU @•D–ÿU @•D¯ÿU @•DÈÿU @•DáÿU¡@•DúÿU @•EÿU @•E,ÿU @•EEÿU @•E^ÿU @•EwÿU @•EÿU @•E©ÿU @•EÂÿU @•EÛÿU @•EôÿU @•F ÿU¡@•F&ÿU @•F?ÿU @•FXÿU @•FqÿU @•FŠÿU @•F£ÿU @•F¼ÿU @•FÕÿU @•FîÿU @•GÿU¡@•G ÿU @•G9ÿU @•GRÿU @•GkÿU @•G„ÿU @•GÿU @•G¶ÿU¡@•GÏÿU @•GèÿU @•HÿU @•HÿUŸ@•H3ÿU @•HLÿU @•HeÿU @•H~ÿU @•H—ÿU¡@•H°ÿU @•HÉÿU @•HâÿU @•HûÿU @•IÿU @•I-ÿU @•IFÿU @•I_ÿU @•IxÿU @•I‘ÿU @•IªÿU @•IÃÿU @•IÜÿU @•IõÿU¡@•JÿU @•J'ÿU¡@•J@ÿUŸ@•JYÿU @•JrÿU @•J‹ÿU @•J¤ÿU¡@•J½ÿU @•JÖÿU @•JïÿU @•KÿUŸ@•K!ÿUŸ@•K:ÿU¡@•KSÿU @•KlÿU @•K…ÿUŸ@•KžÿU¡@•K·ÿU @•KÐÿU @•KéÿU¡@•LÿU @•LÿU @•L4ÿU @•LMÿU @•LfÿUŸ@•LÿU @•L˜ÿU @•L±ÿU @•LÊÿU @•LãÿU¡@•LüÿU¡@•MÿU @•M.ÿU @•MGÿU @•M`ÿU @•MyÿU @•M’ÿU @•M«ÿU¡@•MÄÿUŸ@•MÝÿUŸ@•MöÿU @•NÿU @•N(ÿUŸ@•NAÿU @•NZÿU @•NsÿUŸ@•NŒÿU @•N¥ÿU @•N¾ÿUŸ@•N×ÿU @•NðÿU @•O ÿU¡@•O"ÿUŸ@•O;ÿU @•OTÿU @•OmÿU @•O†ÿU @•OŸÿU @•O¸ÿUŸ@•OÑÿUŸ@•OêÿU @•PÿU @•PÿU @•P5ÿU @•PNÿU @•PgÿU @•P€ÿU @•P™ÿU @•P²ÿU @•PËÿU @•PäÿU @•PýÿU @•QÿU @•Q/ÿU @•QHÿU @•QaÿU @•QzÿU¡@•Q“ÿU @•Q¬ÿUŸ@•QÅÿU @•QÞÿU @•Q÷ÿU @•RÿU @•R)ÿU @•RBÿUŸ@•R[ÿU @•RtÿUŸ@•RÿUŸ@•R¦ÿU @•R¿ÿU @•RØÿU¡@•RñÿUŸ@•S ÿU @•S#ÿU @•S<ÿU @•SUÿUŸ@•SnÿUŸ@•S‡ÿU @•S ÿU¡@•S¹ÿUŸ@•SÒÿU @•SëÿU @•TÿU @•TÿU¡@•T6ÿU @•TOÿU @•ThÿU @•TÿU @•TšÿU @•T³ÿU @•TÌÿU @•TåÿU @•TþÿU @•UÿU @•U0ÿU À¼á“]À#“•Íaìh@¥Û”ö/@L €0Dº@®WKFÇÄ?ü§_H¬SX¿²L:Žx(r¿òÆÙCBÚÀ è[À¾À È5«àò"¿èññzoi¿ûUZŒlGÀUNp©òäÀµ -âPí@òÌ2 ¡@òtº-?ö™Kµð¨%¿ì?‘`ÀWÞÄž£À¶•`ň?ÖЋ.~B?ûä­Lž R@›UÑ<¿â¢§fº¿ú ØðA@ý¿ñ“›Cÿ¶9¿¿l¥+¨=@,ÃïêjÖ@\ó0™N@ (ãy˜@Ì­L?"Í@Dà6©ˆ¿þ8É×î<Àv~ÿ£ÀÂ6x€dÀ[(ŒÕX}¿öƒÙ¿ZQ@Ìj/Uú¤@ô *.O@T¶¹Aƒå@ ›dO8ê@)ÐXx#@°nd0½?ú0bKŸl¤À : Ù!@TÀ’õÓŒu@%:È5÷¿éÈ3Ál½z¿ñAî¼+Ö~?í¦¦z¨ñ¿Òc)4émÀÓà|JêXÀ÷L¢(ÀäØBÙŒ˜?ò²8é%@öòš@ {ŒU°@«ûuBÒ?áþ­Àå¡zY?ê_“E EÊ@(„1`µ®@?Ê9U ¿ðïg¹ääÙÀÉRê•7?Ï*>MI™ß'J}ÀÝ“žÎ¢¿ö‚¢¯"‰c?êµjU(?ìâÉ)K]‘?Ñ\QÛ¨×ê¿åùîƒÖ7t¿÷\æe±8K¿ð‹pgSA&¿Ü^6~|J@ ÐŒ”·œ@š©¼n»@ §ßŸè}ÀKÇ@«ÍÀ,äïÌŒ?Èw‚X U @h‹«+^:?€N¡©Û#¿û‘×)¿ï_ žJd¿³ÊCTy1?×Å$æ¾M?æÞvÁ4~?äןo¿×?ºD d½Àº…¡‰j¢ÀkÍòî[¶¿ô²\/ëˆ$?ü¼Ô‹;Žù@ …Ýpˆ?üÚc è@„?ûŠùgû®?ÿwp1;¿ìÊ{î?€ÀSE®‰~9ÀŠ1¬J¤ÀE6ßE|ÀpÏuÏýêÀªí°\?ðsÇa §<í™AŽ¿æþHƒ’À)­œ¿óEšÝdÒ?Û^ê/‘c?ø `"So@ 6â#lê@šŸR.Ob¿ÍØP³êRêÀÔŸ7ãWÀ°mÈjÀøf ͆ÂÀuì §F2¿áêÎ/ð¦?ü"Hò¼Úã?ÛV;I‡7Ÿ¿üoþmÁÀq ˆ&΄@‡r•;de@"Ð|<P¿ÿ "æ?窽vŸ[@ÓSë=Í@4ÖtµÂä?ÒžiæšÄÀ ˜p  ÀÆ—û1¿ð0DãúÆ‚?äH­‡ÈŽ?åÁ0sñµ¿àò°p_£Â¿óî)bÜ?æN¼= "@ ‚SpË@Ó6RNMT?Ö‡ú—ÑýÀ§·z§¾ÀemÄo3«¿í‘ !|~?ñBž{€ÙŸ¿æží-âu¿ìE†) ²?ô ^M™þé@ '³u/šD@ € ËZ‹Ú?þß_æ‘?â—7 .v?­q@ŒŸ'?úõAVÅG@¬­–š5À@^â¶`ó/@¹{½é.@žiÏÝÁk?õwã¤ì)ÅÀ’=½Bú¿áÖæó>?÷àƒ¿w†Ž¿éB ¥H¡XÀ,Îí…[À `ÎQ•ÌPÀ ‡õ]ïÀN#»ÇÀ ¨>¯fG¿ö¢ih2?ÿ¾\TnÎC@ < dÁá?ûÅWr–Y¿Þå™îjM™?å[ÂŒÀåã@ÀÑ'Éj?ÿ *+‹ž\?øæ'E´?õ2ˆ<­v‘?ò_ÝüNA@ 74Ý™Û@К¸é@õau'p†@ röòwV±@Lè p46@ JVgÉ:?×í¶ßñÀ/Eýã×ÀTÙ1åQ”Àa»k$h¿ù-Um l¿ázܽ:줿햦EE´.À$KÜÊ¿ûC¶Ðç7æ?l›¸_âÚG¿äû%´ð鳿â$wk` c@謘¾þ?@ ~•|z©C?ÇgÑ`×qÀ˾hã¤YÀˆ!“! Ÿ¿þŽïœš-²@ :¥WÄí@Ðq½y@F™Ç Ö@—èK“€x@âå ùWË?ù–G—‘ô#¿Ñù¼K–bæ@im)gœ@æ››/ ?õîÆlû°?úxŸø€?þ.7Jp?ð&÷3YY?ýä¤Ó½Ô@Ã)ìõ¿ô-”¢É)À8}ÚGÀbGJ#†ÀÇôé,+ÀŒð‡˜LÖ?›ÿÏÀG:¨¿ü³Á>À'‹Ö2?Ìøl2Ýì¶@¡ëæ’ò?þ<)Œó0«À”DÊ£íh¿ù?i°û Ù?Ùàçñ+ÿ*?Ògy@ ®¡?åûħÂ@šfö÷´‚@Ï;™}[?òáÕípšk¿¤.¹vÆJ@â8zÈ¥@<L&üË@ ß÷€ïi@ Œ)$¿@âÈDǽ?Ô¬Ò:W(›Àé½…ÐÏ¥À!œþß`À‹pÝY¢/@Hq¤! @GªŠßK@ V'žÄ·–@ Ç (?G=@Ž©’lÙà¿Ò“Ç8„ØŽ¿ú—Çht›ÝÀýô4‹¡À"(›/ïjüÀƒ{¡¦»?óW,Ù½ã@ P©{0û@'0¢1s@ Ú›lí@KÔhóF‰¿üŠ„¦¹·À;ïZ )ÀÍý³È{À$ÄKÙZL¿úºg‘y N¿º6Ío±;hÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿø@ <™ýz»I@ Yw)9ì¬@ @VA‰ãŠ@ —š™|æ@ýTx˜Í@-ˆú‹Ádø@žÐË/þÀ¹ >ÈôÀ¶ÅôÍ@²ÚY—·Ü@¨ Öïw¬@ôø¨O@z@ר+?óšY fG@ ãKðƉ@âf¿É Î«BÖ?æ)&P0È;?ù˜H3(|?ÔéiûT”ý?ÛËPò\íÒ@ î_Θ@ù‡»<¯?ú<Í„kÓ¿¶íÔÃ1~@©q§nJn@QŽ×Æð¿Ânâ9px?óÞÒ*Ü´ÀJ1ö[€ÀÞvo¿ø¿ù©šÓcÀé£ =a•?÷Âgîˆ ?ÿü9 @Ì@ :Etí@—$á%?LÿrDšÀƒ€þB„¤ÀºsFbè?ì3ÑÊd–º¿ã4Ÿ!ä®À¼;²vfÀó†@[ÀË Ši&ÓÀóQyZ¿óúF˜ƒ»?ã7Q¾V ¥@ Ì8ù$@xŽæõë[@è½”é[@ Uö½"ðÍÀÞúùAJ¶Àî0 !À ½OÀ -wú·À·2ÝQ4CÀœÚë¿—$¿ü\#_Ê ÀŽâGÂý.ÀY5—C Àæ…[VWÀNþõªÀÅùƒ1UÀ{§~DÀ'_·¬L@:À»””g@Õ·»™‹@™£¼¶d@[µün´ÀÀã‚ÓÅÀ†oCIý ?ñ' &‰8@2'Ð!¹@ÍÊm¤Èò@! ˜iã@^©ÁXü@GØzlf¨@â[@ DéZH­È?à5PÌ ?üÚº6›ÜÁ@ ÕŒU^3 ?ÝÚêI$®À…Âôüè¤?þ-Ÿ £·@ƒx߃JQ@ )·P{ú—¿új©,Š¿é®à B?ô9¾?ûã\9 O?ð‹òSWúÀ!Z[öõ3À Å7‚ÓjÀgæº>5•¿ÕO¼#$øy?ú ™5?ø[r_kH¿Óu4Í(߿˕d¯šý?þÒ¢ôbE?üŒ óFÌ]Àuµ&ÎfÀ D&…€u˜¿òén² ¦Z?­¥¢µÂl_@­ªÑ ¹@…%¬E9¿ö}YŠðÀaë?p4 ¿ð6 Ð ¿ûpd‰æÞ'¿õ%bêé•¿åŽÉ¨‰Lä¿ð™cÙ>•Àñ1ê8„²À@¯ñ3ëÀç<.ƒ?á4×ói@céB?ë?âß#…¾>¿ï$$,ác!À·/31¹”Àÿç`¦Ï?¯ÖÂ¨Ž¹?þÃ{^?cò?ñŽç—XX"?È}I²9’?äŒ$pñ< ¿Ã}ëð8SÅ¿ÿí¹[Éï¿þÛæå8úÀåÂföz¿ò©¥òß»'?ñ q¹„ñ?óú>Fš,¿Ý+.^ʈs¿ã¾ìž˜?õb…ô|¦â?û ;crpË?˜òFvÞ¿ów®O‰¿õóTî3œ?ïø@’Qd?ú‚ã6rß³?ôb“Ó÷x?³F,0¾¥À†ê[ÜĦÀÔì z@ E\¤¦a@‚ 5H›ö@<¯ý¼i¹@-„Äîä,?ú´°ß7ä?ã¾eØäÙè¿åÊJi&`ÀÛV˺T¿ú~¦ƒ×µ¿Ã©@âA¡?àe %ú¹°?É/õLF©?ë8*N'?×oª<ÿÑ¿üdPǯ»©Àûîè²Å¿ôFmx\-£ÀMZèø¥ˆÀ–›¢‹pÀ³¸¡ÜÂYÀßEY~À"…\ƒ?Ô¬û™(8þ@‚½ŒÂ@ëŠvÆÌ?øY“=S`¿åL”ß“?ñÕ?óž@âð]¶M?û~Ç Dv?ÿÐæ"Ά²@ ŸÓ!F ¦@´C«.#Ì?Ý­RjÞ±¿ðly(]¦-¿ï¥ÏS ¿R@Ô2æ òÄ@ Ax@?ØE°!‘º¿õ‰¡¹* ¿§Ü‚¼sBó?ºË Ò¦>?Ù™L–C«?÷±1g¨í?û²Ällqv?úþhhw‚?í³Z9ЦW?ÍÇ4Õ¢ñ²?üA3ïkŠ@ìýçÌ@qÞPº ?çÑf¤bc?ñöðÒsÉ»?פûÙóÀlT~†mÀ$Ǭb¿ôêS ¼~q?¤S‡˜µ0 ¿XJÓ‚½a¿ì(Ì¢uƒÀ¿ÊY(‚ÝÃ@¹ê¯!@+ÃsyŸ@ZÐeiä@¼U«î¹¿@v½±¬c?á/´¿âmŽ?Üj÷S'?ø¡“ë—x™@¨Gÿ~q§@Æ 9±Ø¿õd¬;i÷cÀ ´…#õ¿úh†Œœ@ `b˜Ú÷k@ _6laè@"£¾ƒK@ªˆõÚl?æ=»pv¿¿ÁÃc#v³ýÀ >”ì¹»¨À (fýZ:¿ñk“%ñø¿Ý=¼ê.¶¸¿Â÷e;˜E÷¿êëSïŒñÀ ˆR <À À {û¿å½µƒÊ?ýÂ((„d?Î&$p›¶˜À+˜ÍQ ô¿û!¹7‘?þY‡¾^s@ÒæW)tj?ûÊBïá@°ÕK;~Â@{=ñ@1@2ë·ah?ú~©YÒyº?÷ßj”-©¿ÃÎ ·ÄÀ^ÏmƒÈ?Ä?Ñ„qÑ @÷w”|û?ðî-Kæ´¿ídÉØÕ ÁÀšöþœ¿À©Â\¼•꿾Q\ºôGw@ )t™W’¿ÇºªGxWšÀ¾¶3o6?æã—wŸ?óPEL J?õvì)éu@£À8ÔDB@ÜéV´r˜?÷õþÒÛA?ò‚‰¢†É¿Ù¸«~·M¿ú3; cŸj¿ùûUêhj¿ø±È{?Ì”Ó v‹@ÒÊšÔ@ ÓÝDb£q@в`>@ÀQ»ÎÈ@óÍîÞƒ.@„.Pî&@4Î2½@½A-´-ñ@4?*ç›@˜„Çäg¥?óPCX]U:@ ØÞ‚Ìî@Á—ß0–@jRüJ?õRøO\?üáJ'û/^@U¥ö Y@HrʰI`@&¤Iè‡~@!ñ÷*…@Zø=©C9@›Ýœ¼9Ò@·Q´dM@ëNTÁ@èR¡ÝŸh@?øÄV(@ I@î@¾¤ {v?ÑD†\w@Š-˜?îŽÜ$™i¿ÿ_'6žÅ?®§å²ÕX@ÅAQà Ó@Z€Á’@ %“Yüƒ×@´æ÷Ÿ@Êúé!}@ -—nóî@M¹G­y)?ð&š‡ãúQ@êÉÍÄþ@6.óŽ@=R[Ì /@ Pî™4wŽ@ /Ožm†œ?ÿ‚Ôÿ„/?Ñv¾ãDó?ðë\©ü?óŠ{Ó8{Ž¿ó[O<¶BA?ÊmâÒ™ªK@ÒŽ¿û/ÑÐâƒ@J͑ӈ@&Wš=ô¿Ü,—¿ãÿú4¾z &¿äŽCÊ q@ö߈·G™@‚Ü:Û‘å@cõ‹°š@/àñÓ@ ÁÎWkƒ@ÐA¬ž ?ø†»Ž´Ï¿î©YÓÚw¿éG“9ÆY?ãøøÖ^^@$nóJ?ç¶k¡£“¿ò…~¨§­?ß qWÌ@ ‘* w@s¸¨1N@luÏ)‚?ïw¸e5È?äÔü¤Øé¿”½}¿à ¿ûL!iWW?ô*ýª€êØ@ ƒšG'kj?ñxݯ>µ¤?ªÒªwpc%?ðØÄ2S[èÀ8ñµÒÀðSصfØÀ©ÌV‡zóÀ÷M ¿Ü°`Ü  @ @n¹«ô@ÊùiECì@ êãŠ)tÐ@ 0Ê-–@Š?ù"Ž3Ë¿ïÂQV¢ìi¿ó:D”r0‘?Õ “Üì?üÞo{p„2@,ŽüÑ †@ _PÉŽ‹Ó@”©µXä@à]K.G?×»,JHr¿¸ëK8&?öºRwÐÿ?óugð¿íô]îÁ+¿ÿ”ÎßSÔ¿ò%X$3i•¿ë ðÃHn¿ç8Á¼G¸¿è† x·OÀô½L?<§À[e²naµÀ¿»8o‹Ù¿ñŽÓü‚À¨½š!ÀZ,à((Àƒ#~ F0ÀNÊ,Æ·u¿ù{ëGx,ÀØ$ŠZ ¿úÌJ‘q?ód÷(vÚc@Ò£¸ @­±ÚR8Ñ@˜ TNP?çwÂдNÀæiË/|¿×ïIjo?ôä™É-•?ñÚk„lV@àµOW þ?îw t#ÀÑò3+õÀ¸›—õv¿ö;Ûó$‰b¿ôæ°,¥¿þ±Ì¢óqò¿õ²å‰}Ùþ¿ñ(ÜÍ¿û×x¥õ1k¿ãj¥ædJ?âvCG52¿Ô»G ÔÔÀMÞ÷6ÀÞ5.4‰ÀÑ—Þ}\ ÀCn_áåÀ Sk†‰ æÀ4‹{w`¿þóº29_¾À›o¶`À …a Ð[¿ò—[žKÜü?óC5´_9?ã–FÛ&l?䮨û`¸?ïÓìƒÅŽ?É+âO¯œ ¿è8Ø?ù4=¿â=Ãíœû¿õ”Nëa!¿÷¸sÐb97?ø¶Té6{@ 'HÅøóÐ?ññÞˆÓ?Á¡g'E›?ôpÿ¸¥Ñ‹¿¼ø`‚áY¿ñ|'ªÙÄA?þLIÕxaI?øžÔ¡¤Ð[¿óf>\¡ì¿æÔõøl¿Â*K ¯¥¿óF·[‡Vs¿òËþÊ,=¿÷²üü0G¿ðZ0[®¶©?ðzïœÆyÅ?öJÀ÷D×?æ¼tŠ:Û?ðÉçØiß@yx•|qM@s@›yp&?úÌ%Vço?ì‘ßk®¿¶5š&&£?üÒ“cpÇ›@(¦¸F²Í@0Niw@š@Xåaj@¶aà0¹@\sO;W?ûjð .?ø»9g¿õÍ‘ê'‰Ê¿õ¸Ì<ŸD¿æëá̪b=À<¿gÀ|l«µTÀ½Þk¢ Ü¿úx“cjÆ@$ÚPP@gtß¡@û°»ê,?Ý ;sDsÀ"M&2å¿×)Ä‹~ÒÜ@ 9v~v?üÒê<É]?óßÉOÅ.†?óú>0•>¿¤»_ =(¢¿Ø{|ÝPq/?ôëéß ?òvó@Î?ñ¿«®‰ºÆªk?ô(t¦~ý½?éGÁ(Bµt¿ê"¤é¥ª¿÷—N蜕+¿öÐY´b¿æJŠÓY»¿ô“ÚÄhýòÀ½¿¥7º¿ý§§‰!w¿÷‹\Zaã¿ÙŒxü²Ö¿ÝøšÍž@vÀ¡À6zC¶À ?ÐK§÷À~3›.¿øŠ#ÂÑ\;¿êh <'¦`¿éªq‚$å©@ž$ ªKy@\5Þ ? @ÌЀšP@ÙèKL(Œ@™‡¶ÿ’÷@Yª|w`S@PÛõ@Ûw¹¡“ @!ˆZ@_KOœGb@!ö55Ú@å öÞ@¨ÊZÐÖ@lòÐþ‘­@1™^b_?ÿízÛ|îK?ÿx¼Ø…¹Z?ÿ÷‹þú€?þ’)ÏVA”?þ R|Ù±?ý¯pnKÉ1?ý?‚»Ñ¯?üЇŒ­p?üb~q„Ü^?ûõf > ?û‰=7l§¸?ûÔ<D?ú³µÀo•Ó?úJTÛaëÉ?ùáß¼Ï?ùzSå_Ï?ù°"æð?ø­ô¢xœ?øIÒ6’‚?÷å0yGƒŽ?÷‚%{+ñð?÷ý»ü˜?ö¾¸ ië¸?ö^S¼Å?õþÎéÓn?õ )&‰.?õBaÅ̺?ôåušX ?ô‰e¸\?ô.0Jèh'?óÓÔ<+{)?ózPuëIa?ó!£âÅ™ ?òÉÍmïë®?òrÌ7~?òžH?ñÇCþIý/?ñr»>¦ È?ñ>A±?ðÌëà—î?ðz6ÞšÍ?ð(µ/Ø?ï°jʹǼ?ïU%Ó?îs. è8ž?íÖí’Ô‘7?í<=¯7I?ì£{¨ú?ì …MlÚï?ëuyÝå8]?êàöv¢ò?êMùwârÙ?é¼€ZvÔ?é,‰2;ô?èžR?肱¿Ë?ç…šÝ2éF?æû–ñûB?æs µ_Ã?åëôÇNÎ?åfQt‘ù?ä⮼"‹?ä_]ËipU?ãÞ lwa¥?ã^ S\?âß¡)ŽÌ?âb‰?yûÏ?áæÖÍŒ¼È?ál‡Ó®’—?àóšR÷*?à| M­¨½?àÛÇH§i?ß" ˆÜo?Þ;•çÁ?ÝVÎý@¯?Üu2"ÅÖå?Û–<ÅÉY”?Ú¹êÁ?Ùà8.»/?Ù !&«?Ø4¡Ä;¿b?×b¶'ÕÑ?Ö“ZqãDR?ÕÆŠÅÄj?ÔüCI8€”?Ô4€$]²Æ?Óo=±ï?Ò¬wޏ.?Ñì*x±‚°?Ñ.Rs3W£?Ðrë±N?ÏsäÔ,}Ö?ÎÅ« aw?Ìžr]áØ?Ë:ãg˜âE?ÉÜG×ZÃ?Èôƒö@?Ç,…¢;Cl?ÅÛ½3c«)?Ä“ÉpC?ÃHú¸¯„?Âd[_ü?ÀƇ¦ÙRŽ?¿ Ïdq?¼®&¢÷?ºL& N&?·òÔÀe©?µ¢_ã&??³Z¥àêz?±•µ§:5?­ÊFî à]?©nȇ?¥#¹:^>Ö? éÖ˜ûD*?™v•¼zµ?‘P•“íp{?‚¢Œ®­ ?UËn0¿yñM!&Ø¿ŒT \Ê¿•·² ºÎ¿%ÇÌÌî¿¢9f¸õ¦c¿¥ÐzƈN¿©Wágü%¦¿¬Ï¶e·Þ¿° º”¾æ¿±Èdÿ³mp ç"¿µ ÁƒÎŠå¿¶ ŽüuZ¿¸.æ5ML^¿¹µÔÐ'¥t¿»5heYôD¿¼­®ƒ¾e¿¾´°²-D¿¿ˆˆh±à¿Àu›Ž,0´¿Á#g.#h¿ÁÍ­ŠÉÜ•¿Âtu‡ù-¸¿ÃŸø ò¿Ã·¤¿Dš»¿ÄT7Ÿk¿Äí)º í!¿Å‚ÜÙÉ«G¿Æ9%eӿƤE&¤Û¿Ç0b”(þ¿Ç¸†Y€š¿È=Ȇ÷óü¿È¿ÔaÍ0÷¿É>°\g˜¿Éºbã V¬¿Ê2ò_‹ã¿Ê¨e50˜¿ËÁÃ)$ݿˊcÕaœ¿ËöQlÕJ…¿Ì_‘/ ‚@¿ÌÅÓöœÑR¿Í) ð&>¿Í‰{®®•¨¿ÍæíÃYÍ¿ÎAz—[ӿΙ*Iç‡í¿Îîg$¬¿Ï@ á{œ¿ÏDˆy„Ü¿ÏÛºÔX^޿й &¿¿Ð689 Ýp¿ÐX]÷—›—¿Ðy-P¼4¿Ð˜©G-­;¿Ð¶Ôßšï«¿ÐÓ³nm¿ÐïFòkËŠ¿Ñ “eùÅÈ¿Ñ"›mÓ ¿Ñ:aþ‚Ó>¿ÑPên¹'¿Ñf6ŽÌж¿ÑzJo'`Š¿Ñ(œ«fš¿ÑžÔ%ÛŠ¿Ñ¯Oˆ¿Ñ¾žXkõ¿ÑÌŠÐcοÑٿ̾ƒl¿Ñ嘹hZ¿ÑðP,hÃB¿ÑùéíWµ¿Òfxüv¿Ò Ê*‚šÒ¿Ò("/f¿ÒRØÉÇ¿Ò}¨Œd¿Ò™…䬨¿Ò«asf¿Ò´Š\;®¿Ò¸³sø¿Òº欿Ò»³M6¿ÒÀ3)ð¿ÒÊQî.¿ÒÜÆFg,¿Ò úICuL¿Ò%ŽP Ô¿ÑüaGS0Ú¿Ñó°#Ôý²¿ÑêÐþžˆ¿Ñß‘ùšR•¿ÑÔ*Fkð¿ÑÇà\vOʿѺ¶àpvF¿Ñ¬°sPjj¿ÑÏ´Ê]¿ÑŽ?!G¿Ñ}‰®Ô¤°¿Ñl)šòº¿ÑYù˜ïqm¿ÑFü;ßÇ„¿Ñ34yÌr¿Ñ£±¢ú¿Ñ M¨¿Ðó4cί™¿ÐÜZŠÁŠq¿ÐÄ—\€u¿Ð¬o ƒ¿Ð“biØE¿ÐyŸ, v–¿Ð_'Ѓ©-¿ÐCþÏH=Ë¿Ð(&ŸD¿Ð ¡´#¿ÏÜå¬Ûä¿Ï¡6æ|4¿Ïd=óöi\¿Ï%þþª9:¿Îæ~×h44¿Î¥ÂJC%†¿ÎcÎþ0¿Î §åÕ¿ÍÜQñçt¿Í–ÓfS˜ ¿ÍP0*äoÚ¿Ílîpп̿Ž[Øv¨¿Ìu™AuJ¿Ì*‘È:,¿ËÞ}ð ,¿Ë‘_gÈX¿ËC=ƒÆ°Z¿ÊôçYÍ®¿Ê£ÿ2Ž<¿ÊRë§CöÜ¿ÊæÃ1ü¿É­ò¼'è¿ÉZ8*†Ì¿ÉTîdzˆ¿È¯³M<×Ä¿ÈY5¼ Ü¿ÈàžðΘ¿Ç©¸TõãÌ¿ÇPÁ8_tØ¿Æöÿž¶€¿ÆœwØÄ2¬¿ÆA.2–Ñ`¿Åå&ó|М¿Åˆf^H ¿Å*ð° u”¿ÄÌÊ"˜¼ð¿Ämöê ¨(¿Ä{5þæä¿Ã®[1KN\¿ÃM›Û¿Âì>ɬ­¬¿ÂŠJ¤Ä`¿Â'«:j¤¿ÁĪð6U\¿Áa‚ ˆœ¿ÀüÜj£ãT¿À˜-®­k¿À2ÿNlK¿¿šªŠ£©€¿¾Îg"ý°¿¾<AÎ8¿½31€o À¿¼dO G@¿»”œKà ¿ºÄ!ÀnÔð¿¹òæV‰Ü€¿¹ ñü¡÷¨¿¸NLT@u@¿·züõrí¿¶§ nËF°¿µÒE_²x¿´ý_ôÊ­è¿´'´ï+˜¿³Q…#Ű¿²zÙ]ÜXX¿±£·‡fø¿°Ì'd¿ë`¿¯è`sžU ¿®7²~ÍiÀ¿¬†SJ†ÌпªÔQ#LÒ0¿©!ºBªa ¿§nœÏ2ü`¿¥»Ü‚º ¿¤k>Là¿¢R©iü€¿ ý°¶¨€¿Ò"Ï•@¿šgâRÚâ¿–ýWb.‰¿“’œ_{€¿'ÌB‚ À¿‰zº,‚¤¯¶8¯€¿wŸ£ #¤¿cîw›È?M{kßx?qSð0Ì ?~õäèþ(?†Jr42½?DÈK?‘ò‹²W?•W J…2?˜ºÕLÑ?œdáh€?Ÿ~ŸÊ$º€?¡o6ˆ_  ?£Z1‚`?¤Ì®= ?¦z&îŽÒ€?¨&¸¡ ?©ÒUž+ÍÀ?«|ó®-?­&†d€q ?®ÏùŠÀ?°;-\=¢?±BÝ÷ ?±àº @¦?²²ÿ>à?³ƒ¼é7 ?´T;²tÿ?µ$¹ÉÏð?µóg?ß?¶Ák,]Bp?·Žù„#Ç?¸[½óê?¹'³ß°?¹òÓW¿?º½…æ•0?»†€;ÿ?€?¼O-ñ’€?½š!Eà?½ÝBÄmÄÀ?¾¢÷20?¿g±¦EZà?À¶Ìüç@?Àwäâ¨?À×ê“}˜À?Á8;[+Ú ?Á˜¿ºU8?Á÷>J‡Žè?ÂU뉯ç€?´ ˜ð?Ñu8¸p?Ãn…U‡40?ÃÊáR Õ?Ä&£›<@?ÄÈ;Áæà?ÄÜN‚Î,?Å63™Ë<À?Åu9‚" ?ÅèyÂ?Æ@ öÛ?Æ—NËü ?Æíì%Iµ@?ÇCÚê^5À?Ç™ðu®?Çí¤Š!P?ÈAz,Sg€?È”™$G7à?Èæþá™ °?É8©Q:‹?ɉ–dÚ¹ ?ÉÙÄæÊÐ?Ê)0V‰µ?ÊwÙ/¬J ?Êż¢õ5P?ËعÈû@?Ë_+‚Iü?˪³Xr0?Ëõmx’nÀ?Ì?XÚSá0?̈sU¶`?Ìл’?Í.5|Ð?Í^ÊóÇÐ?ͤ†@?Íéz†vÀ?Î-ˆçU¥P?ÎpºC>_?γ lI<`?Îô}®<®ð?Ï5 YÀ?Ït¶Ã¬]P?ϳ{Fj¿À?ÏñX@–P?Ð& Ôï?Ð5*–ïíà?ÐR¸û²È?ÐoÐp&ßP?ÐŒp1W(?Ш—|@“È?ÐÄEÚÿx?Ðßy±|™P?Ðú3"Ú£x?Ñq, Mx?Ñ.3{³h?ÑGx.ÞÈ?Ñ`?ÀÒÅÈ?Ñx‰xLH?ÑSœãAØ?ѧžŽad¨?ѾiKŸ^h?ÑÔ³.¨ÇX?Ñê{“è#€?ÑÿÁÚ&ä°?Ò…bhè?Ò(Å¢ü0?Ò<ÊMÖØ?ÒO¹wÓ°?ÒblÖæ?Òt˜Û\,¸?Ò†?mÄß0?Ò—_,Ñ×H?Ò§÷Œ¢Ûø?Ò¸¶ p?ÒÇ êÅà?ÒÖ{Ù€?Òå¹V€?Òòð]¤`?ÓQJÀ?Ó 'ÍôP?Ór£ÿfÐ?Ó%1›y‹°?Ó0d?Zl@?Ó; Õýð?ÓE"Ç#à?ÓN­ÏG® ?ÓWªÊ€YÐ?Ó`PØÐp?Ógøü_©?ÓoIi‚i0?Óv 7 à?Ó|;,LP?ÓÛzi`?Ó†ë9­@?Ó‹iì@ƒ ?ÓW<ÊVð?Ó’²ØPšP?Ó•|n89€?Ó—³°E 0?Ó™XR™Ûð?Óšj ¸Yp?Óšè”%0?ÓšÓ¨3Íp?Óš+nË?Ó˜îi/‡?Ó—˜ÒUð?Ó”¸Xwp?Ó‘¾n °?ÓŽ/¤2\ ?ÓŠ ÆcD0?Ó…R¢ÓÆð?Ó€ È?ÓzÏ*?Ós¥ÇXn@?Ól•ÊWz@?Ódï²8Ð?Ó\³[lôà?ÓSà¤ÃWÀ?ÓJwojVà?Ó@wžï<ð?Ó5á>A ?Ó*³Æ¢‰ ?Óï‘Æ& ?Ó”g²@?Ó¢7ÎHð?Òøóá’Ð?Òéøº ?ÒÛAãs€?ÒËòE:^?Ò¼ RY°?Ò«'àæÀ?ÒšzÅÒf@?ÒˆÏ.ŒØ?ÒvŒfÎ~p?Òc²u´† ?ÒPAd» ?Ò<9?½°?Ò'šô™ð?Òcôúz0?Ñü–òÆ…À?Ñæ3#¯xÀ?ÑÏ8Ÿjü ?Ñ·§€ §?ÑŸâ ûÀ?цÁä5j0?Ñmm§¾P@?ÑSƒP5ø`?Ñ9‹™0?Ñìê Wà?ÑA.hD?Ðåÿý¨^Ð?ÐÉ)‡8‘?Ы½üâ´p?н’ÏŽ?Ðo(†ÏÐ?ÐOþûïP?Ð0ACMù`?Ðï“Gæ`?ÏÞWÀ@?Ï›"žòãÀ?ÏW …©HÀ?ÏÌš$À?ÎËioaŽ€?΃á³@?Î;5¿ÒsÀ?Íñfx·€?ͦtm¨€?ÍZ`I§4€?Í *»Öƒ@?̾ÔxÁ€?Ìo^8õÀ?Ìȹ±þ@?Ë;N–?ËzC ŒP?Ë&TsO—@?ÊÑIÀ:¸À?Ê{#É­Ó€?Ê#ãiÆã@?Éˉa¾?ÉrîÀ?ÉŒžAo@?È»ë|ó2À?È_4|Ÿ?Èh‘úÉ?Ç¢ˆº0¥@?ÇB•ô®ÿ€?Æá‘F@}@?Æ{¸mŸ€?ÆVY|¿À?Ÿ"¿¿±R†o`¿²G#\®É€¿³|D _–¿´²°V ¿µêcx²¹¿·#Xù]ŒAÎ…¿¹˜ø®êF¿ºÕ™–]z€¿¼jCÈ6€¿½ReùNÓ¿¾’‡ï™ñ€¿¿ÓËUÖ‡¿À‹¨Ú怿Á,Ѷ§€¿ÁϸÛr€¿ÂqâØèU¿Ã3_¾ƒ€¿Ã¹È`€¿Ä]W‰–j€¿Å&¥I¿Å§nÖ—Ì¿ÆM/7™è¿Æód›´¿Çš _Çt€¿ÈA#ß•Œ€¿Èè¨o¸‡€¿É—`§¿Ê8íþ¿Êá© †¿ËŠÇU»€¿Ì4D¦S¿ÌÞuŽs¿ÍˆR;wm€¿Î2ݧ€¿Îݼ¥€¿ÏˆìŽ;®¿Ð5¾»z@¿ÐpÒŸÀ¿ÐÆ$¥+…€¿ÑQ)/xÀ¿ÑrŸèÝ¿ÑÉ ö(À¿Ò™EÊãÀ¿ÒvB‡-ª@¿ÒÍ7º+€¿Ó#åÒ &€¿ÓzÜаr¿ÓÑê¨\õ¿Ô) ͸©€¿Ô€D²w€¿Ô×Åîñ€¿Õ.çuØ@¿Õ†P*€˜€¿ÕÝÆNjŒ€¿Ö5HF¬€¿ÖŒÔv¿Ñ@¿Öäi?Á4¿×<l퀿ד¦ µ€¿×ëJ×ÛW@¿ØBñ <±¿Øš˜Ã…´€¿Øò>”˜eÀ¿ÙIác÷ÛÀ¿Ù¡È?À¿Ùù3ÎЀ¿ÚP¦ÉqÝÀ¿Ú¨,‡¸É@¿Úÿ¦³L ¿ÛWŽu*@¿Û®qYÄÀ¿Ü¾PÔˆ¿Ü\ø°Ã7¿Ü´±¸¦€¿Ý .Š#¿¿Ýb&nyÀ¿Ý¹;äÀ¿ÞÇì$@¿ÞflDg€¿Þ¼ò/Tø¿ßW×-À¿ßi˜ðuyÀ¿ß¿¶§V€¿à ÖB¬à¿à5½8d“à¿à`Žöæ½`¿à‹J‹GÀ¿àµïS÷à¿àà{c¬p@¿á ü`¿á5HÎ¥`¿á_†lé@¿á‰¨Òð2 ¿á³®H•Ü¿áÝ•Ñ\2`¿â^o•ðÀ¿â1$f[ ¿âZŽïÁ@¿âƒôÐjö`¿â­7Ãøa ¿âÖVÆÎéà¿âÿPÔ$…`¿ã($åÿ° ¿ãPÑõ7rÀ¿ãyVùs] ¿ã¡²é+‰€¿ãÉ乨šà¿ãñë_¿€¿äÅÌ&­@¿äAròˤ€¿ähñÃ}nÀ¿äA-—_ ¿ä·`ER¿äÞM…ƒ®@¿åLb@¿å+]µç ¿åQᣵ@À¿åwþ[ú¿åãl¹(€¿åü¬k¿åéÚåêÀ¿æ>ªæY€¿æ3=þò ¿æWþèQy ¿æ|ƒÐ?@¿æ Èy>À¿æÄÍí.lÀ¿æè’O à¿ç yö«`¿ç/SH €¿çRM’à¿çu/°ê¿ç—o÷e@¿ç¹•¾ro ¿çÛrXðŸÀ¿çý™ÇÞ¿èKR°ì@¿è?ET5€¿è_ñm®%À¿è€NmF@¿è [ù ¿èÀQ‘5À¿èß~̪ø€¿èþ“Z²ÕÀ¿éRÃåÛ¿é;»ÏQ›€¿éYÍBÔ9@¿éw…ã[€¿é”äs©5¿é±ç¶Ê€À¿éÎŽm „€¿éê×X@¿êÁ4þx@¿ê"JÁÙ À¿ê=r»õÀ¿êX7ÛÔj@¿êr˜Þ*|€¿êŒ”zæ4À¿ê¦)i¬$¿ê¿V`ñd€¿êØûš€¿êðs<àó@¿ë`ˆˆ&@¿ëનs¿ë6òSɤÀ¿ëM”3DÀ¿ëcÄ÷@€¿ëyƒL¸‡@¿ëŽÍßuí¿ë££Z7€¿ë¸eûiÀ¿ëËé«j¿ëßWÑkA@¿ëòK}Ûœ@¿ìÃUhI€¿ì½ûŽû€¿ì(:î@¿ì96;³ç@¿ìI±À5@¿ìY©B‚±@¿ìi\‹»€¿ìx ÉÓ¢¿âöaüäK¿â¬ÉÒ™¼€¿âaþ°­Ð€¿âþ´ªê¿áÈÇúëó¿ázXžœc¿á*®¹¸9¿àÙÈe þ¿à‡£¸4¿à4>É $¿ß¿/]Œ¿ßXö±¿Þdöƒä%¿Ý´)õl¿Ý~ D¿ÜJ`@qá¿Û‘¦ëÁt¿ÚÖN%¤¿ÚRöR¿ÙW®†x¿Ø”`Ž¿×ÎbIuQ¿×±zEP¿Ö:I¢¨W¿Õl&Ë鸿ԛDüõÙ¿ÓÇ :Z6¿Òñ4†E\¿Òýà†ê¿Ñ;øF•¿Ð]³q ¿Îöà?¼Æ¿Í-ËVš¿Ë^÷œ™¶¿ÉŠ]ë²@¿Ç¯õÐz¿ÅÏ·#^Ü¿Ã険•ø¿Áý•e芿À ¡ðÍt¿¼'nCûp¿¸+™vé¿´#´ôÞp¿°°.Úx¿§ÞõÀ迟 ­ß€¿ŒQÑdÀ?g^A'€?”2G?4à?¢Õk÷H?«ªÞ¼°È?²LÎÒIH?¶Ðå;û ?»aÉEˆ?¿ÿz±x¸?ÂU Ú±f?İÛϦr?Ç/Á}ö?É|>Ø@?Ëë‹Ûz?Îa¥.K ?Ðo3j­I?Ѱì¸ì?ÒöÕ Å?Ô>z™D?ÕŠVÏz ?ÖÙ_öì?Ø,R"¶!?Ù‚yv½)?ÚܽpY?Ü91Z’ø?ݙʴG3?Þýè3$?à2Ç ãì€?àè`¦Ù¤?áŸÂã7+?âXðúê?ãêdR¿€?ãдœ€?äOzc}?åO¾µes€?æž?æÖ!Å÷,€?çœìÅ?ècïUè„€?é-£´“þ€?éù9}È<?êÆ²÷½€?ë–iy€?ìgZÛÝ€?í:ŒVbÍ?î«fw¢?îæ¹—.?5Q¶€?ðMVGÈ~À?ð»Êú©?ñ+;Û¤@?ñ›ª¬F€?ò ÌI¶€?òƒ/×À?òòðhakÀ?óg_¡äñÀ?óÜÒ¡?ôSHÇdo?ôÊÅ ø ÀXTENSION= 'BINTABLE' /Written by IDL: Thu Jul 8 16:06:31 2010 BITPIX = 8 / NAXIS = 2 /Binary table NAXIS1 = 32768 /Number of bytes per row NAXIS2 = 1 /Number of rows PCOUNT = 0 /Random parameter count GCOUNT = 1 /Group count TFIELDS = 4 /Number of columns COMMENT COMMENT *** End of mandatory fields *** COMMENT COMMENT COMMENT *** Column names *** COMMENT TTYPE1 = 'VHELIO ' /Heliocentric velocity [km/s] TTYPE2 = 'FREQ ' /Radio frequency [MHz] TTYPE3 = 'FLUXDENS ' /Flux Density [mJy] TTYPE4 = 'BASELINE ' /Subtracted Polynomial baseline fit TUNIT1 = 'KM/S ' /Units of velocity axis TUNIT2 = 'MHz ' /Units of frequency axis TUNIT3 = 'mJy ' /Units of flux density axis TUNIT4 = 'mJy ' /Units of subtracted baseline COMMENT COMMENT *** Column formats *** COMMENT TFORM1 = '1024D ' / TFORM2 = '1024D ' / TFORM3 = '1024D ' / TFORM4 = '1024D ' / TELESCOP= 'Arecibo Radio Telescope' /Designation of Telescope INSTRUME= 'ALFA ' /Instrument in use BEAM = '3.5x3.8 ' /Beam size [arcminutes] OBJECT = 'AGC 100051' /Name of observed object ORIGIN = 'CORNELL ' /File creation location RA = 2.0037095 /Right Ascension in degrees DEC = 14.839847 /Declination in degrees EQUINOX = 2000.00 /Epoch for coordinates (years) RESTFRQ = 1.4204058E+09 /Rest Freqeuncy [Hz] COMMENT BW = 24.975586 /Bandwidth [MHz] CHAN = 1024 /Number of spectral channels COMMENT COMMENT Arecibo Legacy Fast ALFA Survey COMMENT Cornell University COMMENT http://egg.astro.cornell.edu/alfalfa/ COMMENT Last updated: Thu Jul 8 16:06:31 2010 G. Hallenbeck COMMENT ALFALFA archive at http://arecibo.tc.cornell.edu/hiarchive/alfalfa/ COMMENT This spectrum has been baselined. END @Ñ~•¡æ@Ñ|©8à @Ñ{6ß“-@Ñyĉºw€@ÑxR7UÝ@ÑvßèeQT@ÑumœèÈ@ÑsûTà4ª@Ñr‰KŠè@ÑqÏ*¾„@Ño¤‘}Âë@Ñn2WD‹ö@ÑlÀ  "@ÑkMí-:%@ÑiÛ½O @Ñhiäf7@Ñf÷gíLž@Ñe…Bi­S@Ñd Y|@Ñb¡¼¬Ÿ@Ña.æ“2z@Ñ_¼ÎÝ@@Ñ^Jºš ¤@Ñ\Ø©ÊH\@Ñ[fœm¨ @ÑYô’„?@ÑX‚Œ ¡¯@ÑW‰ #@ÑUž‰y–î@ÑT,[ñ@ÑRº”±%@ÑQHŸy&e@ÑOÖ­³é @ÑNd¿a`p@ÑLòÔ€Z@ÑK€í€eZWÚ@Ñ= d†æ@Ñ;œÞàÊ_@Ñ:+ Ïø@Ñ8¹f/]h@Ñ7G¯”Q@Ñ5ÕûE®f@Ñ4dJûŸK@Ñ2òž#Z£@Ñ1€ô¼ÔF@Ñ0NÇÿ²@Ñ.¬DЯ@Ñ-, 3:ß@Ñ+ºq“1ä@Ñ*HÙd©˜@Ñ(×D§•y@Ñ'e³[é_@Ñ%ô%˜Ü@Ñ$‚›—¤@Ñ# Ùk@Ñ!ŸšQç@Ñ .„ôº@Ѽ“൙@ÑK­ˆJ@ÑÙ¤ë`L@Ñh2š1Š@Ñöùï‚@Ñ…XJŽ@ÑðLÐ@Ñ¢‹¾;k@Ñ1*¡1¤@Ñ¿Ìô× @ÑNr¹“@ÑÝíþÃ@Ñ kÈ“hT@Ñ úx©Oú@Ñ ‰,/©i@Ñ ã&hE@Ѧ€f@Ñ5[då^@ÑĬŠò@ÑRáddÅ@ÑᩌfŸ@Ñpu$„4@ÐþÿD,±9@Ðýޤáb@ÐüìS@Ðú«ÅåÒ@Ðù:¢­ ”@Ð÷É‚äË`@ÐöXfŒRÆ@ÐôçM£“ @Ðóv8*@Ðò&!J@Ðð”‡3–@Ðï# \ß)@Ðí²¢¸@ÐìAVž @ÐêÏÿz˜¬@Ðé_ ê|@Ðçî‡,@Ðæ}‚br@Ðå cp@Ðã›.³£¤@Ðâ*Brñ @Ðà¹Y¡KÛ@ÐßHt>§í@ÐÝ×’Jøö@ÐÜf³Æ2ª@ÐÚõذH¿@ÐÙ… .ú@ÐØ,ÐÙ@ÐÖ£\:»@ÐÕ2ެGÎ@ÐÓÁÄ¿óÛ@ÐÒPþB2¼@ÐÐà;2ø7@ÐÏo{’7Þ@ÐÍþ¿_å›@ÐÌŽ›õ@ÐËQFZ@ÐɬŸ_3@ÐÈ;ðåóZ@ÐÆËEÛD@ÐÅZž>O”@ÐÃéú¨"@ÐÂyYO ¥@ÐÁ»üpÏ@п˜"Èi@о'‹¡L@м¶ø˜!@лFhý v@йÕÜÏ´]@иeTs@жôξ ~@е„LÙÉ2@дÎcX@в£SY¶@б2Û½û@ЯÂg $@ЮQöÎ¥ž@Ьá‰zÿl@Ыq”¡1@Ъ¹~´@ШV‹©@Чöp»ý@Ð¥¯š?R@Ф?AzU€@ТÎì"¦>@С^š7é?@ПîKºp@О~©r@Ð ¹æ @ЛtÍx-@К-4¿a@И¼ö¤¯–@ЗL¼³<€@Е܆.Yæ@ДlSû@Ð’ü#jC@Б‹÷*šÈ@ÐÎWå@ÐŽ«¨ð¸b@Ð;†ö8@ЋËhgò–@Њ[MEÛÛ@Јë5ç@Ї{!F ¡@І h5¯@Є›ö_ @Ѓ*øð{@кòV|@ЀJï(V2@Ð~Úïeý?@Ð}jóe&@Ð{úú$ˆ@Ðz‹¥FQ@Ðy‘§5@Ðw«#é—ü@Ðv;8­ ’@ÐtËPÛø™@Ðs[lvOê@Ðqë‹|^@Ðp{­í½@Ðo ÓÉ_Î@Ðm›ýêX@Ðl,)ã!@Ðj¼Yá~@ÐiLjnÚ@ÐgÜÄ^iV@Ðflþ½aT@Ðdý<‡J™@Ðc}¼í@ÐbÂ[À<@Ð`® f4:@Ð_>UÛh®@Ð]Τ»Q„@Ð\^÷âq@ÐZïL»`@ÐY¥ÚÌ@ÐXe +@ÐV bYÃÌ@ÐU0ŸæŒ@ÐSÁ,‚hD@ÐRQ–¶<ß@ÐPâTX@ÐOru\­¸@ÐNéÏ1–@ÐL“a«×™@ÐK#Üò“u@ÐI´[£Y@ÐHDݾ1@ÐFÕcBв@ÐEeì1jq@ÐCöx‰Ý@ÐB‡L¢@ÐA›xÈ@Ð?¨2 Ñm@Ð>8Ì .k@Ð<Éiv'‰@Ð;Z H° @Ð9ꮄ½x@Ð8{V*Aé@Ð7 91à@Ð5œ¯±$@Ð4-a“#{@Ð2¾Þ ¿@Ð1NÏ’0Û@Ð/ß‹¯ƒ˜@Ð.pK5ø»@Ð-%„B@Ð+‘Ô~ã@Ð*"ž?­w@Ð(³kj2×@Ð'D;ýï@Ð%Õùâs@Ð$eç^ôb@Ð"öÂ,Ç‚@Ð!‡ cO›@Ð ‚€™@Щg NT@Ð:Oz¬“@ÐË;SV@Ð\*”êP@Ðí>±[@Ð~PØb@Ð ËSQ@Р ®Ë@Ð1 ùà@Р¬AV@ÐSÇ‘ö@ÐäJù½@Ð u-6lq@Ð >‰Ýí@Ð —SEB@Ð (khŒØ@й†ó±æ@ÐJ¥æ¥4@ÐÛÈAZ›@ÐlîÆ@Ðþ-Û;@ÐC¿Ž'@Ïþ@çq¥#@ÏûcN38ï@Ïø…»Ã¿f@Ïõ¨0# @ÏòÊ«QBÕ@Ïïí-N{@Ïí¶m—@Ïê2E³Dÿ@ÏçTÜ}g@ÏäwyQþ¦@ÏášV°m@ÏÞ¼È)z–@ÏÛßyÊD­@ÏÙ28öŠ@ÏÖ$ñuwá@ÏÓG·°¬@ÏÐj„Wˆz@ÏÍWüç"@Ïʰ2o´W@ÏÇÓ¯×Ì@ÏÄõû½9|@ÏÂê—Àö@Ï¿;à?V6@ϼ^ܳàî@ϹßõH¬@϶¤êum@ϳÇúÞO@ϰë…½.@Ï®0ù§”@Ï«1V9ö@ϨT‚FV@Ï¥wµ^a@Ï¢šîÄGã@ÏŸ¾/54@Ïœávr d@ÏšÄz¶ì@Ï—(O$@Ï”Ktï#À@Ï‘n×Zµ–@ÏŽ’@‘¹Y@Ï‹µ°”@ψÙ'a¶N@Ï…ü¤ú~å@σ )^XÆ@Ï€C´+É@Ï}gF†ß|@ÏzŠßK\@Ïw®~Úˆâ@ÏtÒ%4N@ÏqõÒX“h@Ïo†G@—@Ïl=A=¥@Ïiaƒr"@Ïf„ÊÐÆ @Ïc¨™è!4@Ï`ÌoÉkv@Ï]ðLtŒ…@Ï[/él6@ÏX8'ò‡@ÏU\ 0N@ÏR€’@ÏO¤œ{.@ÏLÈ©ö@ÏIì.’@ÏG&$x´@ÏD4?ãè4@ÏAX`l= @Ï>|‡½^ó@Ï; µ×5à@Ï8Ä깩‰@Ï5é&d¢ @Ï3 hØû@Ï01²À*@Ï-Vµº@Ï*zXãÏ^@Ï'ž¶wõ@Ï$ÃÔ‰@Ï!ç…øš@Ï ÷ã¼e@Ï0p— y@ÏTð÷@ÏyvTе@Ïž^`f@Ï—/@Ï ç1ÇÔm@Ï Ó'B–@Ï0{M³4@ÏU*;h@Ïyßï;ä@Îÿžœj#¥@ÎüÃ_«­@Îùè)³Át@Î÷ ú‚G2@Îô1Ò&µ@ÎñV°rGû@Îî{•“’Ú@Îë zï*@ÎèÅt(Dæ@Îåêm›{æ@ÎãmÔ|&@Îà4tÓ-}@ÎÝY‚—wÂ@ÎÚ~—!Bò@Î×£²pw@ÎÔÈÔ„ü@ÎÑíý^¹i@ÎÏ,ý—†@ÎÌ8ca~ @ÎÉ] ŠU@ÎÆ‚äxe@Îè/*t @ÎÀÍ€¡‹¿@νòØÝ3¢@λ7ÝS°@θ=¡Óœ@εc *›b@βˆ}w’ý@ί­÷ˆ¢Ž@άÓx]±¤@Ωøÿö¨‚@ΧŽSnÝ@ΤD#sìù@Ρi¿X d@Ξaÿ¯>@Λµ jÄ@Θڻ™/@ΖrŠÙú@Γ&0?¬"@ÎKô·[@Îq¿òeÈ@Ί—‘ðb@·½j°œ@΄ãJ3É¥@΂ 0yŽE@Î/ÑÞ@Î|UL|m@Îy{ Ùuî@Îv¡ (¦7@ÎsÇ9õD@Îpí$ K7@În9¢æ@Îk9Uù«r@Îh_y…³@Îe…¢í£@Îb«Ó‰@@Î_Ò æœ©@Î\øI·@ÎZå­d@ÎWDÙ‡Ñ@ÎTk+éxÖ@ÎQ‘… è“@ÎN·äñ>à@ÎKÞK–c¸@ÎI¸ü?a@ÎF+-"¹@ÎCQ¨ º\@Î@x)±)ð@Î=ž²ïú@Î:ÅA@ôæ@Î7ë×) @@Î5sÑZs@Î299‹0@Î/_Áaš¾@Î,†rIpô@Î)­)ðõò@Î&ÓèX´@Î#ú­~¬@Î!!yd­s@ÎHL ý@Îo%n„€@Ζ’*F@μìt×@ÎãÚr­@Î Îvåj@Î 1É–@Î XËsï¾@ÎÔWq@Φãk6n@ÎÍù„th@Íþõ[ù¤@Íü9ñ®B@ÍùCdEyõ@Íöj•WE'@Íó‘Í&÷®@Íð¹ ´yÑ@ÍíàPÿ³B@ÍëŒj@Íè.ïÎìý@ÍåVIR½c@Íâ}©“åš@Íߥ’Mw@ÍÜÌ~MÝA@ÍÙóòÆ|ó@Í×mü®@ÍÔBïîŒn@ÍÑjxÌR@ÍÎ’ ¼}@Í˹ž2Dé@ÍÈá;M·@ÍÆÞ¸¿@ÍÃ0‰€²@ÍÀX:0{ @ͽò–)@ͺ§°˜¹í@Í·ÏuæÎ²@Í´÷Að¼O@Ͳ¶jä@ͯFî7·@ͬnÎt«Ã@Í©–µm(@ͦ¾£ Ñä@Í£æ—ß;@Í¡’º(@Íž6”ŸvÍ@Í›^?Ñ$@͘†¬›™@Í•®Â±,@Í’Ößü€@Íÿ oX@Í'-Slª@ÍŠO^SÜN@͇w–¦ˆ@Í„ŸÔƒ³ž@ÍȲëh@Í~ðeœ6O@Í|¸?|)@ÍyAœ¥=@Íviq³™«@Ís‘Ø„A“@ÍpºF…@ÍmâºRLU@Ík 5Oo@Íh3·†@Íe\?uɹ@Íb„Ξ±*@Í_­d€¥@Í\Ö@ÍYþ¤oR @ÍW'N{Ü•@ÍTOÿAŽ@ÍQx¶¾ß­@ÍN¡tõ)5@ÍKÊ9ã×ÿ@ÍHóŠÔt@ÍF×ê@ÍCD±V½@Í@mЬ÷@Í=–wWñ]@Í:¿d— @Í7èXå~@Í5S§‚@Ì×hYÎQ@ÌÔ’8©œÛ@ÌѼ9N`@ÌÎæ }M˜@ÌÌýuƒ@ÌÉ9÷!ÖË@ÌÆc÷‚1@ÌÃþ–z @ÌÀ¸ ^š@̽â ÚyZ@Ì» < 0@̸6]í¾@̵`†ƒ¥J@Ì²ŠµÍ”@̯´ëÊËG@̬ß({3C@̪ kÞ´,@̧3µõ6H@̤^¾¡Ú@Ì¡ˆ^:ßM@Ìž²¼iÖ@Ì›Ý!Kp3@Ì™Œß”U@Ì–1ÿ&+"@Ì“\x@̆÷ÊRD@̱~'³"@ÌŠÜ 7'Á@̈žø˜e@Ì…19kí@Ì‚[Ú‘d@̆‚gæ@Ì|±0ðZ@ÌyÛæ*S_@Ìw¢º†@Ìt1d²w¼@Ìq\.sD@Ìn†ýÿ•‰@Ìk±Ô¯Æ«@Ìhܲîï@Ìf–"ö¿@Ìc2€åÆa@Ì`]rYEô@Ì]ˆj}^@ÌZ³iQö¹@ÌWÞnÖøw@ÌU { K_@ÌR4ñ×ÿ@ÌO_§‡†y@ÌLŠÇÍ?@ÌIµîÂê3@ÌFáhp!@ÌD P½¹F@ÌA7‹Â­Â@Ì>bÍw6@Ì;ŽÛ:D@Ì8¹dî£@Ì5亱X†@Ì3#Bê@Ì0;zDJ±@Ì-fäXF@Ì*’T“SÉ@Ì'½ËÁ%¤@Ì$éI¶@Ì"Î(íš@Ì@Yb´e@ÌkëJòä@Ì—ƒá‘^@ÌÃ#&x=@ÌîÉÄ@ÌuºÀ_@ÌF) òR@Ì qã@Ì£±ûÂ@ÌÉk £ï@Ìõ9îÑ@Ì! ÄÄÒ@ËýLé&]@ËúxË4³¶@Ë÷¤³ðG@ËôУY³U@Ëñü™oÞI@Ëï(–3@ËìT™£i@Ë連¿ðh@Ëæ¬´‰‚«@ËãØËÿ³œ@Ëáê"kÉ@ËÞ1ñ“x@ËÛ]:mí@ËØ‰l”Ò“@ËÕµ¥hº÷@ËÒáäè´^@ËÐ+§@ËÍ:wì{r@ËÊfËp@ËÇ“%Ÿk?@ËÄ¿†zWY@ËÁëîÆË@Ë¿\2¡Ü@˼DÑÑ@˹qL˜<É@˶ÎËÍS@˳ÊWªkH@˰öç3þÇ@Ë®#}hpƒ@Ë«PG¨œ@˨|½Ñ¢@Ë¥©h ý@Ë¢Öå @Ë Ðnr[@Ë/Ž¢) @Ëš\S€»@Ë—‰)ô@Ë”µñ:D´@Ë‘âÊQÑ@Ë©œ9“@ËŒ<Ëä<@ˉi|¥:@ˆ–p($¦@˃ÃjT‹@Ë€ðk*V\@Ë~r©nÁ@Ë{J€Ñ¼Ò@Ëxw•£(Ó@Ëu¤±›x@ËrÑÓ@ý@Ëoþü 5ç@Ëm,+‚.„@ËjYaŸÏl@Ëg†žf,@Ëd³áÔ«å@Ëaá+ë¸K@Ë_|«Ç@Ë\;Ô—ž@ËYi2";ƒ@ËV––Ùâº@ËSÄ9uÔ@ËPñt@Ý\@ËNìðš@ËKLlFÊö@ËHyòE"#@ËE§~êï‹@ËBÕ8t@Ë@¬,Žj@Ë=0LÈ1#@Ë:]ô ë¼@Ë7‹¡ô¦ë@Ë4¹V…K@Ë1ç¼ÀÒ@Ë/Óšð]@Ë,BœÂn@Ë)pkKH@Ë&žAïŸ@Ë#Ì•·@Ë ú³ŒD@Ë'êx)°@ËUÚâ܈@˃Ñó@˱Ϫ$@ËßÔ‰¾@Ë ß¦´@Ë ;ð°c”@Ë jý¨É@˘'ð^à@ËÆMˆn @ËôyÅ¿`@Êÿ"¬¨:ä@ÊüPæ/É;@Êù&\Ró@Êö­m-Àw@ÊóÛº£úx@Êñ ¾é`@Êî8i~uš@ÊëfÊâ‡Ø@Êè•2ë„@Êåá—à,@Êâòè÷^@Êà ’Þ6…@ÊÝOw†R@ÊÚ}ž´Ï1@Ê׬.•ù®@ÊÔÚÅî4@ÊÒ bC•u@ÊÏ8Ø@ÊÌf°ž@@ÊÉ•a’Ðå@ÊÆÄIX6@ÊÃò×£ @ÊÁ!œ Ë@ʾPh@ã@Ê»:‚ñ(@ʸ®hÀà@ʵÜòñX¿@ʳ Ù¡Q@ʰ:Åêƒ'@Ê­i¹Zæ¨@ʪ˜³m´ˆ@ʧǴ"ÕV@ʤö»z1 @Ê¢%És±ô@ÊŸTÞ>»@ÊœƒùLÀÎ@Ê™³, •@Ê–âC­F @Ê”rÐ|@Ê‘@¨”‡Ý@ÊŽoäút,@Ê‹Ÿ(É@ʈÎqªo:@Ê…ýÁôO@ʃ-ßQ?@Ê€\vk^B@Ê}‹Ú˜^ö@Êz»Ef;¡@Êwê¶ÔÜõ@Êu.ä+‚@ÊrI­”ù@Êoy2ärÅ@Êl¨¾Õ<½@ÊiØQfVK@Êgê—¨!@Êd7Ši©@Êag0Ú–¼@Ê^–Ýìæ@Ê[Æ‘M’@ÊXöKîY˜@ÊV& ß`@ÊSUÔo]Ã@ÊP…¢Ÿ'*@ÊMµwnVH@ÊJåRÜÓ«@ÊH4ê‡â@ÊEE—[Å@ÊBu ã7à@Ê?¥ÎŸ@Ê<ÔÿWªØ@Ê:€@Ê75 G%ô@Ê4e¬Ì<@Ê1•3°î]@Ê.ÅQSu@Ê+õu”HÎ@Ê)% sR„@Ê&UÑðzº@Ê#† ©Ù@Ê ¶HÄÈÝ@ÊæŽÀ0@ÊÚx„@ÊG,¢Ú@Êw…ÒÎþ@ʧå >@@ÊØL *@Ê ¹0L@Ê 9,¸„|@Êi¦úö$@Êš'Úm÷@ÊʯVÔÍ@Éþû=p@Éü+Ò&•@Éù\mx¹@Éögò@Éó½·ó¥'@Éðîg»'@ÉîàÄ@ÉëOÙ@²Œ@É耜=eY@Éå±eÖ’@Éââ6 Ä@Éà ÛA…@ÉÝCêG~€@ÉÚtÎOcØ@É×¥¸òÚ@ÉÔÖª1Ê#@ÉÒ¢ W@ÉÏ8 ¹³@ÉÌi¥’ŠÆ@ÉÉš±>x@ÉÆËÃ…jº@ÉÃüÜgK$@ÉÁ-ûäì@ɾ_!ûx@É»N­•õ@ɸÁúD›@ɵò»álj@ɳ#übö;@ɰUC~Êå@É­†‘4Òõ@ɪ·å„÷ @ɧé@o @É¥¡ó6±@É¢L #@ÉŸ}xÈÏV@Éœ®î"ë@É™àjï@É—ì‰d@É”Cu§#6@É‘u^,à@ÉŽ¦›®iÄ@É‹Ø8—Âà@ɉ Ü Â@Ɇ;†5l@Ƀm6éÆ@É€žî6nO@É}Ьö²@É{pš}@Éx4;°¡‰@Éuf _•ˆ@Ér—å¦ÔR@ÉoÉĆFt@Élû©ýÔÇ@Éj-– h"@Ég_ˆ´é@Éd‘ô@r@ÉaÃËW@É^õˆ:±@É\'•@dø@ÉYY¨Þ-Á@ÉV‹ÃX¿@ÉS½ãßΦ@ÉPð Cxq@ÉN"9>>®@ÉKTmÐ 5@ÉH†¨øÃÞ@ÉE¸ê¸T\@ÉBë3¤`@É@ûœÄ@É=O×&^@É:‚3™)á@É7´–I@É4æÿA·@É2om'¹@É/Kåà*¹@É,~bé3@É)°æˆ+@É&ãp¼ùô@É$‡‰ @É!H˜çÁ6@É{6Ý‹ @É­ÛhÏ£@Éà†‰w—@É8?k‰@ÉEðŠ”œ@Éx¯jÛ@É «tà(ë@É Þ@êe²@ɉzÒ@ÉCì½PÚ@ÉvÌ…ÐÄ@Èÿ©²âãE@ÈüÜŸÔq4@Èú“Zch@È÷Bt¢¹@ÈôuŽ#ý@Èñ¨•e«é@ÈîÛ£v@È´´É‘!@ȱESAî@È®xøL=Ç@È«¬£èiK@ȨàVY~@ȦÕ÷7@È£GÎ'+M@È {” Þ˜@ȯ`}ú@Èšã3ƒft@Ș  ³@È•JíAÕª@È’~Óúª/@ȲÁDs@@Ȍ浳@ÈŠ¯Š†„@ȇN°†¢B@È„‚¸V2@ȶÆ0Šã@È~êÚÞ)t@È|ö¾@ÈySêGs@Èv‡@H˜Ú@Ès»o6÷~@Èp蘆L_@Èn#àÀv@ÈkX#a|›@ÈhŒl)§@ÈeÀ¼Lp•@Èbõ™:b@È`)ouo¿@È]]Òàùª@ÈZ’<ÛÁB@ÈWÆ­e¯@ÈTû$~¬I@ÈR/¢&¡¯@ÈOd&]xj@ÈL˜±# @ÈIÍBwl«@ÈGÚZ\N@ÈD6xËУ@ÈAk˲Í@È>ŸÉYëÆ@È;Ô{vdA@È9 4!<@È6=óY·±@È3r¹ d@È0§…tôØ@È-ÜXWQ]@È+1Çc(@È(FÅ@È%zøPJ@È"¯åhñ0@ÈäÙñ7@ÈÓB3)@ÈNÔ @ȃÛP ¹@ȸé*ž,@Èíý’y@È#†3R@È X:Ú@È b§ @È®ºâ@È÷ÅÕA@È-ˆ"ß@ÇþbCÇHþ@Çû—Œ’œ³@ÇøÌÛê±@Çö1Íp@Çó7Ž<ÁÁ@Çðlñ7äÌ@Çí¢Z¾Â@Çê×ÊÑBŠ@Çè AoOY@ÇåB¾˜Ñ2@ÇâxBM±~@Çß­ÌØË@ÇÜã]Y0:@ÇÚô¯ ë@Ç×N’‘¶@ÇÔ„6ýq˜@Çѹáô£Œ@ÇÎï“v’Ž@ÇÌ%Kƒ'ã@ÇÉ[ L@ÇÆÏ;èz@ÇÃÆšçåü@ÇÀüm-x@Ǿ2EÞ¨5@Ç»h%)>ä@Ǹž ýÚÌ@ǵÓ÷\dÃ@dz êDÅë@ǰ?ã¶ç@Ç­uã²±r@Ǫ«ê8 î@ǧá÷Få°@Ç¥ ß!Ž@Ç¢N%ªª@”ñIÿU @”ñbÿU¡@”ñ{ÿU @”ñ”ÿU @”ñ­ÿU @”ñÆÿU¡@”ñßÿU @”ñøÿU @”òÿU @”ò*ÿUŸ@”òCÿU @”ò\ÿU @”òuÿU @”òŽÿU @”ò§ÿU @”òÀÿU¡@”òÙÿU @”òòÿU @”ó ÿU¡@”ó$ÿU @”ó=ÿUŸ@”óVÿU @”óoÿU¡@”óˆÿU @”ó¡ÿU @”óºÿU @”óÓÿU¡@”óìÿU @”ôÿU @”ôÿU @”ô7ÿU @”ôPÿU @”ôiÿU @”ô‚ÿU @”ô›ÿU¡@”ô´ÿU @”ôÍÿU¡@”ôæÿU @”ôÿÿU @”õÿU @”õ1ÿU¡@”õJÿUŸ@”õcÿU @”õ|ÿU @”õ•ÿU¡@”õ®ÿU @”õÇÿU @”õàÿU @”õùÿU @”öÿU @”ö+ÿU @”öDÿU @”ö]ÿU¡@”övÿU @”öÿU @”ö¨ÿUŸ@”öÁÿUŸ@”öÚÿU¡@”öóÿU @”÷ ÿU¡@”÷%ÿU @”÷>ÿU @”÷WÿU @”÷pÿU @”÷‰ÿU @”÷¢ÿU @”÷»ÿU @”÷ÔÿUŸ@”÷íÿU¡@”øÿU @”øÿU @”ø8ÿU @”øQÿUŸ@”øjÿU @”øƒÿU @”øœÿU @”øµÿU¡@”øÎÿU @”øçÿU @”ùÿU @”ùÿUŸ@”ù2ÿU @”ùKÿUŸ@”ùdÿU @”ù}ÿUŸ@”ù–ÿU @”ù¯ÿU @”ùÈÿU @”ùáÿU @”ùúÿU @”úÿU @”ú,ÿU @”úEÿU¡@”ú^ÿU @”úwÿU @”úÿU @”ú©ÿU @”úÂÿU @”úÛÿU @”úôÿU @”û ÿU @”û&ÿUŸ@”û?ÿU @”ûXÿU @”ûqÿU @”ûŠÿU @”û£ÿU @”û¼ÿU @”ûÕÿUŸ@”ûîÿU @”üÿU @”ü ÿU @”ü9ÿU @”üRÿU @”ükÿU @”ü„ÿU @”üÿU¡@”ü¶ÿU @”üÏÿU @”üèÿU @”ýÿU @”ýÿU @”ý3ÿU @”ýLÿU @”ýeÿU @”ý~ÿU @”ý—ÿU @”ý°ÿU @”ýÉÿU @”ýâÿU @”ýûÿU @”þÿU @”þ-ÿU¡@”þFÿUŸ@”þ_ÿU @”þxÿU @”þ‘ÿU @”þªÿU @”þÃÿUŸ@”þÜÿU @”þõÿU @”ÿÿU @”ÿ'ÿU @”ÿ@ÿUŸ@”ÿYÿU @”ÿrÿU @”ÿ‹ÿUŸ@”ÿ¤ÿUŸ@”ÿ½ÿU¡@”ÿÖÿU @”ÿïÿU @•ÿU @•!ÿUŸ@•:ÿU @•SÿU @•lÿU @•…ÿUŸ@•žÿU @•·ÿU @•ÐÿU @•éÿU @•ÿU @•ÿU @•4ÿU @•MÿU @•fÿU @•ÿU @•˜ÿU @•±ÿU @•ÊÿU @•ãÿU @•üÿU @•ÿU @•.ÿUŸ@•GÿU @•`ÿU @•yÿUŸ@•’ÿU @•«ÿU @•ÄÿU @•ÝÿU @•öÿU @•ÿU @•(ÿU @•AÿU @•ZÿU¡@•sÿU @•ŒÿU @•¥ÿU @•¾ÿU @•×ÿU @•ðÿU @• ÿU @•"ÿU @•;ÿU @•TÿU @•mÿU @•†ÿU @•ŸÿU @•¸ÿU @•ÑÿU @•êÿU @•ÿU @•ÿUŸ@•5ÿU @•NÿU @•gÿU @•€ÿU @•™ÿU @•²ÿU @•ËÿU @•äÿU @•ýÿU @•ÿU @•/ÿU @•HÿU @•aÿU @•zÿUŸ@•“ÿU¡@•¬ÿU @•ÅÿU @•ÞÿU¡@•÷ÿU @•ÿU @•)ÿUŸ@•BÿU @•[ÿU¡@•tÿU @•ÿU @•¦ÿU @•¿ÿU @•ØÿU @•ñÿU @• ÿU @•#ÿU @•<ÿUŸ@•UÿU @•nÿU @•‡ÿU @• ÿU¡@•¹ÿU @•ÒÿU @•ëÿU @• ÿU @• ÿU @• 6ÿU¡@• OÿU @• hÿUŸ@• ÿU @• šÿU¡@• ³ÿUŸ@• ÌÿU¡@• åÿU @• þÿU @• ÿU¡@• 0ÿU @• IÿU @• bÿU¡@• {ÿU @• ”ÿU @• ­ÿU @• ÆÿU @• ßÿU @• øÿU @• ÿU @• *ÿUŸ@• CÿU @• \ÿU @• uÿU @• ŽÿU @• §ÿU @• ÀÿU @• ÙÿU @• òÿU @• ÿU¡@• $ÿU¡@• =ÿU¡@• VÿU @• oÿU @• ˆÿU @• ¡ÿU¡@• ºÿU @• ÓÿU @• ìÿUŸ@• ÿUŸ@• ÿU @• 7ÿU @• PÿU¡@• iÿU @• ‚ÿUŸ@• ›ÿU @• ´ÿU¡@• ÍÿU @• æÿU @• ÿÿU @•ÿU @•1ÿU @•JÿU @•cÿU @•|ÿU @••ÿU @•®ÿU @•ÇÿU @•àÿU @•ùÿU @•ÿU @•+ÿU @•DÿUŸ@•]ÿU @•vÿU @•ÿU @•¨ÿU @•ÁÿU @•ÚÿU @•óÿU @• ÿU @•%ÿU @•>ÿU @•WÿU @•pÿU @•‰ÿU @•¢ÿU @•»ÿU @•ÔÿU @•íÿU @•ÿU @•ÿU¡@•8ÿUŸ@•QÿU @•jÿU @•ƒÿU @•œÿU @•µÿU @•ÎÿU @•çÿU @•ÿU¡@•ÿU @•2ÿUŸ@•KÿU¡@•dÿU @•}ÿU¡@•–ÿU @•¯ÿU @•ÈÿU @•áÿU @•úÿU @•ÿU @•,ÿUŸ@•EÿUŸ@•^ÿU @•wÿU @•ÿU @•©ÿU @•ÂÿU @•ÛÿU @•ôÿU @• ÿU @•&ÿUŸ@•?ÿU @•XÿU @•qÿU @•ŠÿU @•£ÿU @•¼ÿU @•ÕÿU @•îÿU @•ÿUŸ@• ÿU @•9ÿU¡@•RÿU¡@•kÿUŸ@•„ÿU @•ÿU @•¶ÿU @•ÏÿU @•èÿU @•ÿU @•ÿU @•3ÿU @•LÿUŸ@•eÿUŸ@•~ÿU @•—ÿU¡@•°ÿU @•ÉÿU @•âÿU @•ûÿU¡@•ÿUŸ@•-ÿU @•FÿU @•_ÿU @•xÿU @•‘ÿU @•ªÿU @•ÃÿU @•ÜÿU¡@•õÿU @•ÿU @•'ÿU @•@ÿU¡@•YÿU¡@•rÿU @•‹ÿU @•¤ÿU @•½ÿU @•ÖÿU @•ïÿU @•ÿU @•!ÿU @•:ÿU @•SÿU¡@•lÿU @•…ÿU @•žÿU¡@•·ÿU @•ÐÿU @•éÿU @•ÿU @•ÿU @•4ÿU @•MÿU @•fÿU @•ÿU @•˜ÿU¡@•±ÿUŸ@•ÊÿU @•ãÿU @•üÿU @•ÿU @•.ÿU @•GÿU @•`ÿUŸ@•yÿU¡@•’ÿU @•«ÿU @•ÄÿU @•ÝÿU @•öÿU @•ÿU @•(ÿU @•AÿU @•ZÿU @•sÿU @•ŒÿUŸ@•¥ÿU @•¾ÿU @•×ÿU @•ðÿU¡@• ÿU @•"ÿU¡@•;ÿU @•TÿU @•mÿU @•†ÿU¡@•ŸÿU @•¸ÿU @•ÑÿU @•êÿU @•ÿU @•ÿU @•5ÿU @•NÿU @•gÿU @•€ÿU @•™ÿU @•²ÿUŸ@•ËÿU @•äÿU @•ýÿU @•ÿU @•/ÿU @•HÿU @•aÿU¡@•zÿU @•“ÿU @•¬ÿU @•ÅÿU @•ÞÿU @•÷ÿU @• ÿUŸ@• )ÿU @• BÿU @• [ÿU @• tÿU¡@• ÿU @• ¦ÿUŸ@• ¿ÿU @• ØÿU @• ñÿU @•! ÿU @•!#ÿUŸ@•!<ÿU @•!UÿU @•!nÿU @•!‡ÿU @•! ÿU @•!¹ÿU @•!ÒÿU @•!ëÿU @•"ÿU @•"ÿU @•"6ÿU @•"OÿU @•"hÿU @•"ÿU¡@•"šÿU¡@•"³ÿU¡@•"ÌÿUŸ@•"åÿU @•"þÿU @•#ÿU¡@•#0ÿU @•#IÿUŸ@•#bÿUŸ@•#{ÿU @•#”ÿU @•#­ÿU @•#ÆÿUŸ@•#ßÿU @•#øÿU @•$ÿU @•$*ÿU @•$CÿU @•$\ÿU @•$uÿUŸ@•$ŽÿU @•$§ÿU @•$ÀÿU @•$ÙÿU¡@•$òÿU @•% ÿU @•%$ÿU @•%=ÿU @•%VÿU @•%oÿU @•%ˆÿU @•%¡ÿU @•%ºÿU @•%ÓÿU @•%ìÿU¡@•&ÿUŸ@•&ÿU @•&7ÿU @•&PÿU @•&iÿU @•&‚ÿU @•&›ÿU @•&´ÿU @•&ÍÿU @•&æÿU @•&ÿÿU @•'ÿUŸ@•'1ÿU @•'JÿU @•'cÿUŸ@•'|ÿU @•'•ÿU @•'®ÿU @•'ÇÿU @•'àÿU @•'ùÿU @•(ÿU @•(+ÿUŸ@•(DÿU @•(]ÿUŸ@•(vÿU @•(ÿU @•(¨ÿU @•(ÁÿUŸ@•(ÚÿU @•(óÿU @•) ÿU @•)%ÿU @•)>ÿU¡@•)WÿU @•)pÿU @•)‰ÿU @•)¢ÿU @•)»ÿU @•)ÔÿUŸ@•)íÿU @•*ÿU @•*ÿU @•*8ÿU @•*QÿU @•*jÿU¡@•*ƒÿU @•*œÿU @•*µÿU @•*ÎÿU @•*çÿU @•+ÿU @•+ÿU @•+2ÿU @•+KÿU @•+dÿU¡@•+}ÿU @•+–ÿU @•+¯ÿU @•+ÈÿU @•+áÿU @•+úÿU @•,ÿU @•,,ÿU @•,EÿU¡@•,^ÿUŸ@•,wÿU @•,ÿU @•,©ÿU @•,ÂÿU @•,ÛÿU @•,ôÿUŸ@•- ÿU @•-&ÿU @•-?ÿU @•-XÿU @•-qÿU @•-ŠÿU @•-£ÿU @•-¼ÿU @•-ÕÿU @•-îÿU @•.ÿU @•. ÿU @•.9ÿU @•.RÿU @•.kÿU @•.„ÿU @•.ÿUŸ@•.¶ÿU @•.ÏÿU @•.èÿU @•/ÿU @•/ÿU @•/3ÿU @•/LÿU @•/eÿU @•/~ÿU @•/—ÿU @•/°ÿU @•/ÉÿU @•/âÿUŸ@•/ûÿU @•0ÿU @•0-ÿU @•0FÿU @•0_ÿU @•0xÿU @•0‘ÿU @•0ªÿU @•0ÃÿU @•0ÜÿU @•0õÿU @•1ÿU @•1'ÿUŸ@•1@ÿU @•1YÿU @•1rÿU @•1‹ÿU @•1¤ÿU @•1½ÿU @•1ÖÿU¡@•1ïÿUŸ@•2ÿU @•2!ÿU @•2:ÿU @•2SÿU¡@•2lÿU @•2…ÿU @•2žÿU @•2·ÿU @•2ÐÿU @•2éÿU @•3ÿU @•3ÿU @•34ÿU @•3MÿU @•3fÿU @•3ÿU¡@•3˜ÿU @•3±ÿU @•3ÊÿU @•3ãÿU @•3üÿU @•4ÿU @•4.ÿU @•4GÿU¡@•4`ÿU @•4yÿU @•4’ÿU @•4«ÿU @•4ÄÿUŸ@•4ÝÿU @•4öÿU¡@•5ÿU @•5(ÿU @•5AÿU @•5ZÿU @•5sÿUŸ@•5ŒÿU @•5¥ÿUŸ@•5¾ÿU @•5×ÿU @•5ðÿU¡@•6 ÿU¡@•6"ÿU @•6;ÿU @•6TÿU @•6mÿU @•6†ÿU @•6ŸÿU @•6¸ÿU @•6ÑÿU @•6êÿU @•7ÿU @•7ÿU @•75ÿU @•7NÿU @•7gÿU @•7€ÿU¡@•7™ÿU @•7²ÿU @•7ËÿU @•7äÿU @•7ýÿU @•8ÿU @•8/ÿU @•8HÿU¡@•8aÿU @•8zÿU @•8“ÿU @•8¬ÿU @•8ÅÿU¡@•8ÞÿU @•8÷ÿU @•9ÿU @•9)ÿU @•9BÿU @•9[ÿU @•9tÿU @•9ÿU @•9¦ÿU @•9¿ÿU @•9ØÿU @•9ñÿUŸ@•: ÿU @•:#ÿU @•:<ÿU @•:UÿU @•:nÿUŸ@•:‡ÿU @•: ÿU @•:¹ÿU @•:ÒÿU @•:ëÿU @•;ÿU @•;ÿU @•;6ÿU @•;OÿU @•;hÿU @•;ÿU @•;šÿU¡@•;³ÿU @•;ÌÿUŸ@•;åÿUŸ@•;þÿU @•<ÿU @•<0ÿU @• ÿU @•>$ÿU¡@•>=ÿU @•>VÿU @•>oÿU @•>ˆÿU¡@•>¡ÿU @•>ºÿU @•>ÓÿU¡@•>ìÿU @•?ÿU @•?ÿU @•?7ÿU @•?PÿUŸ@•?iÿU @•?‚ÿU @•?›ÿU @•?´ÿUŸ@•?ÍÿUŸ@•?æÿU @•?ÿÿU @•@ÿU @•@1ÿU @•@JÿU @•@cÿUŸ@•@|ÿU @•@•ÿU¡@•@®ÿU @•@ÇÿU @•@àÿU @•@ùÿU @•AÿU @•A+ÿU @•ADÿU @•A]ÿU @•AvÿU @•AÿU @•A¨ÿU @•AÁÿU @•AÚÿU @•AóÿU¡@•B ÿU @•B%ÿU @•B>ÿU @•BWÿU @•BpÿU @•B‰ÿU @•B¢ÿU @•B»ÿU¡@•BÔÿU @•BíÿU @•CÿU @•CÿU @•C8ÿU @•CQÿU @•CjÿU @•CƒÿU @•CœÿU @•CµÿU @•CÎÿUŸ@•CçÿUŸ@•DÿU @•DÿU @•D2ÿUŸ@•DKÿU @•DdÿUŸ@•D}ÿU @•D–ÿU @•D¯ÿU @•DÈÿU @•DáÿU¡@•DúÿU @•EÿU @•E,ÿU @•EEÿU @•E^ÿU @•EwÿU @•EÿU @•E©ÿU @•EÂÿU @•EÛÿU @•EôÿU @•F ÿU¡@•F&ÿU @•F?ÿU @•FXÿU @•FqÿU @•FŠÿU @•F£ÿU @•F¼ÿU @•FÕÿU @•FîÿU @•GÿU¡@•G ÿU @•G9ÿU @•GRÿU @•GkÿU @•G„ÿU @•GÿU @•G¶ÿU¡@•GÏÿU @•GèÿU @•HÿU @•HÿUŸ@•H3ÿU @•HLÿU @•HeÿU @•H~ÿU @•H—ÿU¡@•H°ÿU @•HÉÿU @•HâÿU @•HûÿU @•IÿU @•I-ÿU @•IFÿU @•I_ÿU @•IxÿU @•I‘ÿU @•IªÿU @•IÃÿU @•IÜÿU @•IõÿU¡@•JÿU @•J'ÿU¡@•J@ÿUŸ@•JYÿU @•JrÿU @•J‹ÿU @•J¤ÿU¡@•J½ÿU @•JÖÿU @•JïÿU @•KÿUŸ@•K!ÿUŸ@•K:ÿU¡@•KSÿU @•KlÿU @•K…ÿUŸ@•KžÿU¡@•K·ÿU @•KÐÿU @•KéÿU¡@•LÿU @•LÿU @•L4ÿU @•LMÿU @•LfÿUŸ@•LÿU @•L˜ÿU @•L±ÿU @•LÊÿU @•LãÿU¡@•LüÿU¡@•MÿU @•M.ÿU @•MGÿU @•M`ÿU @•MyÿU @•M’ÿU @•M«ÿU¡@•MÄÿUŸ@•MÝÿUŸ@•MöÿU @•NÿU @•N(ÿUŸ@•NAÿU @•NZÿU @•NsÿUŸ@•NŒÿU @•N¥ÿU @•N¾ÿUŸ@•N×ÿU @•NðÿU @•O ÿU¡@•O"ÿUŸ@•O;ÿU @•OTÿU @•OmÿU @•O†ÿU @•OŸÿU @•O¸ÿUŸ@•OÑÿUŸ@•OêÿU @•PÿU @•PÿU @•P5ÿU @•PNÿU @•PgÿU @•P€ÿU @•P™ÿU @•P²ÿU @•PËÿU @•PäÿU @•PýÿU @•QÿU @•Q/ÿU @•QHÿU @•QaÿU @•QzÿU¡@•Q“ÿU @•Q¬ÿUŸ@•QÅÿU @•QÞÿU @•Q÷ÿU @•RÿU @•R)ÿU @•RBÿUŸ@•R[ÿU @•RtÿUŸ@•RÿUŸ@•R¦ÿU @•R¿ÿU @•RØÿU¡@•RñÿUŸ@•S ÿU @•S#ÿU @•S<ÿU @•SUÿUŸ@•SnÿUŸ@•S‡ÿU @•S ÿU¡@•S¹ÿUŸ@•SÒÿU @•SëÿU @•TÿU @•TÿU¡@•T6ÿU @•TOÿU @•ThÿU @•TÿU @•TšÿU @•T³ÿU @•TÌÿU @•TåÿU @•TþÿU @•UÿU @•U0ÿU À¼á“]À#“•Íaìh@¥Û”ö/@L €0Dº@®WKFÇÄ?ü§_H¬SX¿²L:Žx(r¿òÆÙCBÚÀ è[À¾À È5«àò"¿èññzoi¿ûUZŒlGÀUNp©òäÀµ -âPí@òÌ2 ¡@òtº-?ö™Kµð¨%¿ì?‘`ÀWÞÄž£À¶•`ň?ÖЋ.~B?ûä­Lž R@›UÑ<¿â¢§fº¿ú ØðA@ý¿ñ“›Cÿ¶9¿¿l¥+¨=@,ÃïêjÖ@\ó0™N@ (ãy˜@Ì­L?"Í@Dà6©ˆ¿þ8É×î<Àv~ÿ£ÀÂ6x€dÀ[(ŒÕX}¿öƒÙ¿ZQ@Ìj/Uú¤@ô *.O@T¶¹Aƒå@ ›dO8ê@)ÐXx#@°nd0½?ú0bKŸl¤À : Ù!@TÀ’õÓŒu@%:È5÷¿éÈ3Ál½z¿ñAî¼+Ö~?í¦¦z¨ñ¿Òc)4émÀÓà|JêXÀ÷L¢(ÀäØBÙŒ˜?ò²8é%@öòš@ {ŒU°@«ûuBÒ?áþ­Àå¡zY?ê_“E EÊ@(„1`µ®@?Ê9U ¿ðïg¹ääÙÀÉRê•7?Ï*>MI™ß'J}ÀÝ“žÎ¢¿ö‚¢¯"‰c?êµjU(?ìâÉ)K]‘?Ñ\QÛ¨×ê¿åùîƒÖ7t¿÷\æe±8K¿ð‹pgSA&¿Ü^6~|J@ ÐŒ”·œ@š©¼n»@ §ßŸè}ÀKÇ@«ÍÀ,äïÌŒ?Èw‚X U @h‹«+^:?€N¡©Û#¿û‘×)¿ï_ žJd¿³ÊCTy1?×Å$æ¾M?æÞvÁ4~?äןo¿×?ºD d½Àº…¡‰j¢ÀkÍòî[¶¿ô²\/ëˆ$?ü¼Ô‹;Žù@ …Ýpˆ?üÚc è@„?ûŠùgû®?ÿwp1;¿ìÊ{î?€ÀSE®‰~9ÀŠ1¬J¤ÀE6ßE|ÀpÏuÏýêÀªí°\?ðsÇa §<í™AŽ¿æþHƒ’À)­œ¿óEšÝdÒ?Û^ê/‘c?ø `"So@ 6â#lê@šŸR.Ob¿ÍØP³êRêÀÔŸ7ãWÀ°mÈjÀøf ͆ÂÀuì §F2¿áêÎ/ð¦?ü"Hò¼Úã?ÛV;I‡7Ÿ¿üoþmÁÀq ˆ&΄@‡r•;de@"Ð|<P¿ÿ "æ?窽vŸ[@ÓSë=Í@4ÖtµÂä?ÒžiæšÄÀ ˜p  ÀÆ—û1¿ð0DãúÆ‚?äH­‡ÈŽ?åÁ0sñµ¿àò°p_£Â¿óî)bÜ?æN¼= "@ ‚SpË@Ó6RNMT?Ö‡ú—ÑýÀ§·z§¾ÀemÄo3«¿í‘ !|~?ñBž{€ÙŸ¿æží-âu¿ìE†) ²?ô ^M™þé@ '³u/šD@ € ËZ‹Ú?þß_æ‘?â—7 .v?­q@ŒŸ'?úõAVÅG@¬­–š5À@^â¶`ó/@¹{½é.@žiÏÝÁk?õwã¤ì)ÅÀ’=½Bú¿áÖæó>?÷àƒ¿w†Ž¿éB ¥H¡XÀ,Îí…[À `ÎQ•ÌPÀ ‡õ]ïÀN#»ÇÀ ¨>¯fG¿ö¢ih2?ÿ¾\TnÎC@ < dÁá?ûÅWr–Y¿Þå™îjM™?å[ÂŒÀåã@ÀÑ'Éj?ÿ *+‹ž\?øæ'E´?õ2ˆ<­v‘?ò_ÝüNA@ 74Ý™Û@К¸é@õau'p†@ röòwV±@Lè p46@ JVgÉ:?×í¶ßñÀ/Eýã×ÀTÙ1åQ”Àa»k$h¿ù-Um l¿ázܽ:줿햦EE´.À$KÜÊ¿ûC¶Ðç7æ?l›¸_âÚG¿äû%´ð鳿â$wk` c@謘¾þ?@ ~•|z©C?ÇgÑ`×qÀ˾hã¤YÀˆ!“! Ÿ¿þŽïœš-²@ :¥WÄí@Ðq½y@F™Ç Ö@—èK“€x@âå ùWË?ù–G—‘ô#¿Ñù¼K–bæ@im)gœ@æ››/ ?õîÆlû°?úxŸø€?þ.7Jp?ð&÷3YY?ýä¤Ó½Ô@Ã)ìõ¿ô-”¢É)À8}ÚGÀbGJ#†ÀÇôé,+ÀŒð‡˜LÖ?›ÿÏÀG:¨¿ü³Á>À'‹Ö2?Ìøl2Ýì¶@¡ëæ’ò?þ<)Œó0«À”DÊ£íh¿ù?i°û Ù?Ùàçñ+ÿ*?Ògy@ ®¡?åûħÂ@šfö÷´‚@Ï;™}[?òáÕípšk¿¤.¹vÆJ@â8zÈ¥@<L&üË@ ß÷€ïi@ Œ)$¿@âÈDǽ?Ô¬Ò:W(›Àé½…ÐÏ¥À!œþß`À‹pÝY¢/@Hq¤! @GªŠßK@ V'žÄ·–@ Ç (?G=@Ž©’lÙà¿Ò“Ç8„ØŽ¿ú—Çht›ÝÀýô4‹¡À"(›/ïjüÀƒ{¡¦»?óW,Ù½ã@ P©{0û@'0¢1s@ Ú›lí@KÔhóF‰¿üŠ„¦¹·À;ïZ )ÀÍý³È{À$ÄKÙZL¿úºg‘y N¿º6Ío±;hÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿøÿø@ <™ýz»I@ Yw)9ì¬@ @VA‰ãŠ@ —š™|æ@ýTx˜Í@-ˆú‹Ádø@žÐË/þÀ¹ >ÈôÀ¶ÅôÍ@²ÚY—·Ü@¨ Öïw¬@ôø¨O@z@ר+?óšY fG@ ãKðƉ@âf¿É Î«BÖ?æ)&P0È;?ù˜H3(|?ÔéiûT”ý?ÛËPò\íÒ@ î_Θ@ù‡»<¯?ú<Í„kÓ¿¶íÔÃ1~@©q§nJn@QŽ×Æð¿Ânâ9px?óÞÒ*Ü´ÀJ1ö[€ÀÞvo¿ø¿ù©šÓcÀé£ =a•?÷Âgîˆ ?ÿü9 @Ì@ :Etí@—$á%?LÿrDšÀƒ€þB„¤ÀºsFbè?ì3ÑÊd–º¿ã4Ÿ!ä®À¼;²vfÀó†@[ÀË Ši&ÓÀóQyZ¿óúF˜ƒ»?ã7Q¾V ¥@ Ì8ù$@xŽæõë[@è½”é[@ Uö½"ðÍÀÞúùAJ¶Àî0 !À ½OÀ -wú·À·2ÝQ4CÀœÚë¿—$¿ü\#_Ê ÀŽâGÂý.ÀY5—C Àæ…[VWÀNþõªÀÅùƒ1UÀ{§~DÀ'_·¬L@:À»””g@Õ·»™‹@™£¼¶d@[µün´ÀÀã‚ÓÅÀ†oCIý ?ñ' &‰8@2'Ð!¹@ÍÊm¤Èò@! ˜iã@^©ÁXü@GØzlf¨@â[@ DéZH­È?à5PÌ ?üÚº6›ÜÁ@ ÕŒU^3 ?ÝÚêI$®À…Âôüè¤?þ-Ÿ £·@ƒx߃JQ@ )·P{ú—¿új©,Š¿é®à B?ô9¾?ûã\9 O?ð‹òSWúÀ!Z[öõ3À Å7‚ÓjÀgæº>5•¿ÕO¼#$øy?ú ™5?ø[r_kH¿Óu4Í(߿˕d¯šý?þÒ¢ôbE?üŒ óFÌ]Àuµ&ÎfÀ D&…€u˜¿òén² ¦Z?­¥¢µÂl_@­ªÑ ¹@…%¬E9¿ö}YŠðÀaë?p4 ¿ð6 Ð ¿ûpd‰æÞ'¿õ%bêé•¿åŽÉ¨‰Lä¿ð™cÙ>•Àñ1ê8„²À@¯ñ3ëÀç<.ƒ?á4×ói@céB?ë?âß#…¾>¿ï$$,ác!À·/31¹”Àÿç`¦Ï?¯ÖÂ¨Ž¹?þÃ{^?cò?ñŽç—XX"?È}I²9’?äŒ$pñ< ¿Ã}ëð8SÅ¿ÿí¹[Éï¿þÛæå8úÀåÂföz¿ò©¥òß»'?ñ q¹„ñ?óú>Fš,¿Ý+.^ʈs¿ã¾ìž˜?õb…ô|¦â?û ;crpË?˜òFvÞ¿ów®O‰¿õóTî3œ?ïø@’Qd?ú‚ã6rß³?ôb“Ó÷x?³F,0¾¥À†ê[ÜĦÀÔì z@ E\¤¦a@‚ 5H›ö@<¯ý¼i¹@-„Äîä,?ú´°ß7ä?ã¾eØäÙè¿åÊJi&`ÀÛV˺T¿ú~¦ƒ×µ¿Ã©@âA¡?àe %ú¹°?É/õLF©?ë8*N'?×oª<ÿÑ¿üdPǯ»©Àûîè²Å¿ôFmx\-£ÀMZèø¥ˆÀ–›¢‹pÀ³¸¡ÜÂYÀßEY~À"…\ƒ?Ô¬û™(8þ@‚½ŒÂ@ëŠvÆÌ?øY“=S`¿åL”ß“?ñÕ?óž@âð]¶M?û~Ç Dv?ÿÐæ"Ά²@ ŸÓ!F ¦@´C«.#Ì?Ý­RjÞ±¿ðly(]¦-¿ï¥ÏS ¿R@Ô2æ òÄ@ Ax@?ØE°!‘º¿õ‰¡¹* ¿§Ü‚¼sBó?ºË Ò¦>?Ù™L–C«?÷±1g¨í?û²Ällqv?úþhhw‚?í³Z9ЦW?ÍÇ4Õ¢ñ²?üA3ïkŠ@ìýçÌ@qÞPº ?çÑf¤bc?ñöðÒsÉ»?פûÙóÀlT~†mÀ$Ǭb¿ôêS ¼~q?¤S‡˜µ0 ¿XJÓ‚½a¿ì(Ì¢uƒÀ¿ÊY(‚ÝÃ@¹ê¯!@+ÃsyŸ@ZÐeiä@¼U«î¹¿@v½±¬c?á/´¿âmŽ?Üj÷S'?ø¡“ë—x™@¨Gÿ~q§@Æ 9±Ø¿õd¬;i÷cÀ ´…#õ¿úh†Œœ@ `b˜Ú÷k@ _6laè@"£¾ƒK@ªˆõÚl?æ=»pv¿¿ÁÃc#v³ýÀ >”ì¹»¨À (fýZ:¿ñk“%ñø¿Ý=¼ê.¶¸¿Â÷e;˜E÷¿êëSïŒñÀ ˆR <À À {û¿å½µƒÊ?ýÂ((„d?Î&$p›¶˜À+˜ÍQ ô¿û!¹7‘?þY‡¾^s@ÒæW)tj?ûÊBïá@°ÕK;~Â@{=ñ@1@2ë·ah?ú~©YÒyº?÷ßj”-©¿ÃÎ ·ÄÀ^ÏmƒÈ?Ä?Ñ„qÑ @÷w”|û?ðî-Kæ´¿ídÉØÕ ÁÀšöþœ¿À©Â\¼•꿾Q\ºôGw@ )t™W’¿ÇºªGxWšÀ¾¶3o6?æã—wŸ?óPEL J?õvì)éu@£À8ÔDB@ÜéV´r˜?÷õþÒÛA?ò‚‰¢†É¿Ù¸«~·M¿ú3; cŸj¿ùûUêhj¿ø±È{?Ì”Ó v‹@ÒÊšÔ@ ÓÝDb£q@в`>@ÀQ»ÎÈ@óÍîÞƒ.@„.Pî&@4Î2½@½A-´-ñ@4?*ç›@˜„Çäg¥?óPCX]U:@ ØÞ‚Ìî@Á—ß0–@jRüJ?õRøO\?üáJ'û/^@U¥ö Y@HrʰI`@&¤Iè‡~@!ñ÷*…@Zø=©C9@›Ýœ¼9Ò@·Q´dM@ëNTÁ@èR¡ÝŸh@?øÄV(@ I@î@¾¤ {v?ÑD†\w@Š-˜?îŽÜ$™i¿ÿ_'6žÅ?®§å²ÕX@ÅAQà Ó@Z€Á’@ %“Yüƒ×@´æ÷Ÿ@Êúé!}@ -—nóî@M¹G­y)?ð&š‡ãúQ@êÉÍÄþ@6.óŽ@=R[Ì /@ Pî™4wŽ@ /Ožm†œ?ÿ‚Ôÿ„/?Ñv¾ãDó?ðë\©ü?óŠ{Ó8{Ž¿ó[O<¶BA?ÊmâÒ™ªK@ÒŽ¿û/ÑÐâƒ@J͑ӈ@&Wš=ô¿Ü,—¿ãÿú4¾z &¿äŽCÊ q@ö߈·G™@‚Ü:Û‘å@cõ‹°š@/àñÓ@ ÁÎWkƒ@ÐA¬ž ?ø†»Ž´Ï¿î©YÓÚw¿éG“9ÆY?ãøøÖ^^@$nóJ?ç¶k¡£“¿ò…~¨§­?ß qWÌ@ ‘* w@s¸¨1N@luÏ)‚?ïw¸e5È?äÔü¤Øé¿”½}¿à ¿ûL!iWW?ô*ýª€êØ@ ƒšG'kj?ñxݯ>µ¤?ªÒªwpc%?ðØÄ2S[èÀ8ñµÒÀðSصfØÀ©ÌV‡zóÀ÷M ¿Ü°`Ü  @ @n¹«ô@ÊùiECì@ êãŠ)tÐ@ 0Ê-–@Š?ù"Ž3Ë¿ïÂQV¢ìi¿ó:D”r0‘?Õ “Üì?üÞo{p„2@,ŽüÑ †@ _PÉŽ‹Ó@”©µXä@à]K.G?×»,JHr¿¸ëK8&?öºRwÐÿ?óugð¿íô]îÁ+¿ÿ”ÎßSÔ¿ò%X$3i•¿ë ðÃHn¿ç8Á¼G¸¿è† x·OÀô½L?<§À[e²naµÀ¿»8o‹Ù¿ñŽÓü‚À¨½š!ÀZ,à((Àƒ#~ F0ÀNÊ,Æ·u¿ù{ëGx,ÀØ$ŠZ ¿úÌJ‘q?ód÷(vÚc@Ò£¸ @­±ÚR8Ñ@˜ TNP?çwÂдNÀæiË/|¿×ïIjo?ôä™É-•?ñÚk„lV@àµOW þ?îw t#ÀÑò3+õÀ¸›—õv¿ö;Ûó$‰b¿ôæ°,¥¿þ±Ì¢óqò¿õ²å‰}Ùþ¿ñ(ÜÍ¿û×x¥õ1k¿ãj¥ædJ?âvCG52¿Ô»G ÔÔÀMÞ÷6ÀÞ5.4‰ÀÑ—Þ}\ ÀCn_áåÀ Sk†‰ æÀ4‹{w`¿þóº29_¾À›o¶`À …a Ð[¿ò—[žKÜü?óC5´_9?ã–FÛ&l?䮨û`¸?ïÓìƒÅŽ?É+âO¯œ ¿è8Ø?ù4=¿â=Ãíœû¿õ”Nëa!¿÷¸sÐb97?ø¶Té6{@ 'HÅøóÐ?ññÞˆÓ?Á¡g'E›?ôpÿ¸¥Ñ‹¿¼ø`‚áY¿ñ|'ªÙÄA?þLIÕxaI?øžÔ¡¤Ð[¿óf>\¡ì¿æÔõøl¿Â*K ¯¥¿óF·[‡Vs¿òËþÊ,=¿÷²üü0G¿ðZ0[®¶©?ðzïœÆyÅ?öJÀ÷D×?æ¼tŠ:Û?ðÉçØiß@yx•|qM@s@›yp&?úÌ%Vço?ì‘ßk®¿¶5š&&£?üÒ“cpÇ›@(¦¸F²Í@0Niw@š@Xåaj@¶aà0¹@\sO;W?ûjð .?ø»9g¿õÍ‘ê'‰Ê¿õ¸Ì<ŸD¿æëá̪b=À<¿gÀ|l«µTÀ½Þk¢ Ü¿úx“cjÆ@$ÚPP@gtß¡@û°»ê,?Ý ;sDsÀ"M&2å¿×)Ä‹~ÒÜ@ 9v~v?üÒê<É]?óßÉOÅ.†?óú>0•>¿¤»_ =(¢¿Ø{|ÝPq/?ôëéß ?òvó@Î?ñ¿«®‰ºÆªk?ô(t¦~ý½?éGÁ(Bµt¿ê"¤é¥ª¿÷—N蜕+¿öÐY´b¿æJŠÓY»¿ô“ÚÄhýòÀ½¿¥7º¿ý§§‰!w¿÷‹\Zaã¿ÙŒxü²Ö¿ÝøšÍž@vÀ¡À6zC¶À ?ÐK§÷À~3›.¿øŠ#ÂÑ\;¿êh <'¦`¿éªq‚$å©@ž$ ªKy@\5Þ ? @ÌЀšP@ÙèKL(Œ@™‡¶ÿ’÷@Yª|w`S@PÛõ@Ûw¹¡“ @!ˆZ@_KOœGb@!ö55Ú@å öÞ@¨ÊZÐÖ@lòÐþ‘­@1™^b_?ÿízÛ|îK?ÿx¼Ø…¹Z?ÿ÷‹þú€?þ’)ÏVA”?þ R|Ù±?ý¯pnKÉ1?ý?‚»Ñ¯?üЇŒ­p?üb~q„Ü^?ûõf > ?û‰=7l§¸?ûÔ<D?ú³µÀo•Ó?úJTÛaëÉ?ùáß¼Ï?ùzSå_Ï?ù°"æð?ø­ô¢xœ?øIÒ6’‚?÷å0yGƒŽ?÷‚%{+ñð?÷ý»ü˜?ö¾¸ ië¸?ö^S¼Å?õþÎéÓn?õ )&‰.?õBaÅ̺?ôåušX ?ô‰e¸\?ô.0Jèh'?óÓÔ<+{)?ózPuëIa?ó!£âÅ™ ?òÉÍmïë®?òrÌ7~?òžH?ñÇCþIý/?ñr»>¦ È?ñ>A±?ðÌëà—î?ðz6ÞšÍ?ð(µ/Ø?ï°jʹǼ?ïU%Ó?îs. è8ž?íÖí’Ô‘7?í<=¯7I?ì£{¨ú?ì …MlÚï?ëuyÝå8]?êàöv¢ò?êMùwârÙ?é¼€ZvÔ?é,‰2;ô?èžR?肱¿Ë?ç…šÝ2éF?æû–ñûB?æs µ_Ã?åëôÇNÎ?åfQt‘ù?ä⮼"‹?ä_]ËipU?ãÞ lwa¥?ã^ S\?âß¡)ŽÌ?âb‰?yûÏ?áæÖÍŒ¼È?ál‡Ó®’—?àóšR÷*?à| M­¨½?àÛÇH§i?ß" ˆÜo?Þ;•çÁ?ÝVÎý@¯?Üu2"ÅÖå?Û–<ÅÉY”?Ú¹êÁ?Ùà8.»/?Ù !&«?Ø4¡Ä;¿b?×b¶'ÕÑ?Ö“ZqãDR?ÕÆŠÅÄj?ÔüCI8€”?Ô4€$]²Æ?Óo=±ï?Ò¬wޏ.?Ñì*x±‚°?Ñ.Rs3W£?Ðrë±N?ÏsäÔ,}Ö?ÎÅ« aw?Ìžr]áØ?Ë:ãg˜âE?ÉÜG×ZÃ?Èôƒö@?Ç,…¢;Cl?ÅÛ½3c«)?Ä“ÉpC?ÃHú¸¯„?Âd[_ü?ÀƇ¦ÙRŽ?¿ Ïdq?¼®&¢÷?ºL& N&?·òÔÀe©?µ¢_ã&??³Z¥àêz?±•µ§:5?­ÊFî à]?©nȇ?¥#¹:^>Ö? éÖ˜ûD*?™v•¼zµ?‘P•“íp{?‚¢Œ®­ ?UËn0¿yñM!&Ø¿ŒT \Ê¿•·² ºÎ¿%ÇÌÌî¿¢9f¸õ¦c¿¥ÐzƈN¿©Wágü%¦¿¬Ï¶e·Þ¿° º”¾æ¿±Èdÿ³mp ç"¿µ ÁƒÎŠå¿¶ ŽüuZ¿¸.æ5ML^¿¹µÔÐ'¥t¿»5heYôD¿¼­®ƒ¾e¿¾´°²-D¿¿ˆˆh±à¿Àu›Ž,0´¿Á#g.#h¿ÁÍ­ŠÉÜ•¿Âtu‡ù-¸¿ÃŸø ò¿Ã·¤¿Dš»¿ÄT7Ÿk¿Äí)º í!¿Å‚ÜÙÉ«G¿Æ9%eӿƤE&¤Û¿Ç0b”(þ¿Ç¸†Y€š¿È=Ȇ÷óü¿È¿ÔaÍ0÷¿É>°\g˜¿Éºbã V¬¿Ê2ò_‹ã¿Ê¨e50˜¿ËÁÃ)$ݿˊcÕaœ¿ËöQlÕJ…¿Ì_‘/ ‚@¿ÌÅÓöœÑR¿Í) ð&>¿Í‰{®®•¨¿ÍæíÃYÍ¿ÎAz—[ӿΙ*Iç‡í¿Îîg$¬¿Ï@ á{œ¿ÏDˆy„Ü¿ÏÛºÔX^޿й &¿¿Ð689 Ýp¿ÐX]÷—›—¿Ðy-P¼4¿Ð˜©G-­;¿Ð¶Ôßšï«¿ÐÓ³nm¿ÐïFòkËŠ¿Ñ “eùÅÈ¿Ñ"›mÓ ¿Ñ:aþ‚Ó>¿ÑPên¹'¿Ñf6ŽÌж¿ÑzJo'`Š¿Ñ(œ«fš¿ÑžÔ%ÛŠ¿Ñ¯Oˆ¿Ñ¾žXkõ¿ÑÌŠÐcοÑٿ̾ƒl¿Ñ嘹hZ¿ÑðP,hÃB¿ÑùéíWµ¿Òfxüv¿Ò Ê*‚šÒ¿Ò("/f¿ÒRØÉÇ¿Ò}¨Œd¿Ò™…䬨¿Ò«asf¿Ò´Š\;®¿Ò¸³sø¿Òº欿Ò»³M6¿ÒÀ3)ð¿ÒÊQî.¿ÒÜÆFg,¿Ò úICuL¿Ò%ŽP Ô¿ÑüaGS0Ú¿Ñó°#Ôý²¿ÑêÐþžˆ¿Ñß‘ùšR•¿ÑÔ*Fkð¿ÑÇà\vOʿѺ¶àpvF¿Ñ¬°sPjj¿ÑÏ´Ê]¿ÑŽ?!G¿Ñ}‰®Ô¤°¿Ñl)šòº¿ÑYù˜ïqm¿ÑFü;ßÇ„¿Ñ34yÌr¿Ñ£±¢ú¿Ñ M¨¿Ðó4cί™¿ÐÜZŠÁŠq¿ÐÄ—\€u¿Ð¬o ƒ¿Ð“biØE¿ÐyŸ, v–¿Ð_'Ѓ©-¿ÐCþÏH=Ë¿Ð(&ŸD¿Ð ¡´#¿ÏÜå¬Ûä¿Ï¡6æ|4¿Ïd=óöi\¿Ï%þþª9:¿Îæ~×h44¿Î¥ÂJC%†¿ÎcÎþ0¿Î §åÕ¿ÍÜQñçt¿Í–ÓfS˜ ¿ÍP0*äoÚ¿Ílîpп̿Ž[Øv¨¿Ìu™AuJ¿Ì*‘È:,¿ËÞ}ð ,¿Ë‘_gÈX¿ËC=ƒÆ°Z¿ÊôçYÍ®¿Ê£ÿ2Ž<¿ÊRë§CöÜ¿ÊæÃ1ü¿É­ò¼'è¿ÉZ8*†Ì¿ÉTîdzˆ¿È¯³M<×Ä¿ÈY5¼ Ü¿ÈàžðΘ¿Ç©¸TõãÌ¿ÇPÁ8_tØ¿Æöÿž¶€¿ÆœwØÄ2¬¿ÆA.2–Ñ`¿Åå&ó|М¿Åˆf^H ¿Å*ð° u”¿ÄÌÊ"˜¼ð¿Ämöê ¨(¿Ä{5þæä¿Ã®[1KN\¿ÃM›Û¿Âì>ɬ­¬¿ÂŠJ¤Ä`¿Â'«:j¤¿ÁĪð6U\¿Áa‚ ˆœ¿ÀüÜj£ãT¿À˜-®­k¿À2ÿNlK¿¿šªŠ£©€¿¾Îg"ý°¿¾<AÎ8¿½31€o À¿¼dO G@¿»”œKà ¿ºÄ!ÀnÔð¿¹òæV‰Ü€¿¹ ñü¡÷¨¿¸NLT@u@¿·züõrí¿¶§ nËF°¿µÒE_²x¿´ý_ôÊ­è¿´'´ï+˜¿³Q…#Ű¿²zÙ]ÜXX¿±£·‡fø¿°Ì'd¿ë`¿¯è`sžU ¿®7²~ÍiÀ¿¬†SJ†ÌпªÔQ#LÒ0¿©!ºBªa ¿§nœÏ2ü`¿¥»Ü‚º ¿¤k>Là¿¢R©iü€¿ ý°¶¨€¿Ò"Ï•@¿šgâRÚâ¿–ýWb.‰¿“’œ_{€¿'ÌB‚ À¿‰zº,‚¤¯¶8¯€¿wŸ£ #¤¿cîw›È?M{kßx?qSð0Ì ?~õäèþ(?†Jr42½?DÈK?‘ò‹²W?•W J…2?˜ºÕLÑ?œdáh€?Ÿ~ŸÊ$º€?¡o6ˆ_  ?£Z1‚`?¤Ì®= ?¦z&îŽÒ€?¨&¸¡ ?©ÒUž+ÍÀ?«|ó®-?­&†d€q ?®ÏùŠÀ?°;-\=¢?±BÝ÷ ?±àº @¦?²²ÿ>à?³ƒ¼é7 ?´T;²tÿ?µ$¹ÉÏð?µóg?ß?¶Ák,]Bp?·Žù„#Ç?¸[½óê?¹'³ß°?¹òÓW¿?º½…æ•0?»†€;ÿ?€?¼O-ñ’€?½š!Eà?½ÝBÄmÄÀ?¾¢÷20?¿g±¦EZà?À¶Ìüç@?Àwäâ¨?À×ê“}˜À?Á8;[+Ú ?Á˜¿ºU8?Á÷>J‡Žè?ÂU뉯ç€?´ ˜ð?Ñu8¸p?Ãn…U‡40?ÃÊáR Õ?Ä&£›<@?ÄÈ;Áæà?ÄÜN‚Î,?Å63™Ë<À?Åu9‚" ?ÅèyÂ?Æ@ öÛ?Æ—NËü ?Æíì%Iµ@?ÇCÚê^5À?Ç™ðu®?Çí¤Š!P?ÈAz,Sg€?È”™$G7à?Èæþá™ °?É8©Q:‹?ɉ–dÚ¹ ?ÉÙÄæÊÐ?Ê)0V‰µ?ÊwÙ/¬J ?Êż¢õ5P?ËعÈû@?Ë_+‚Iü?˪³Xr0?Ëõmx’nÀ?Ì?XÚSá0?̈sU¶`?Ìл’?Í.5|Ð?Í^ÊóÇÐ?ͤ†@?Íéz†vÀ?Î-ˆçU¥P?ÎpºC>_?γ lI<`?Îô}®<®ð?Ï5 YÀ?Ït¶Ã¬]P?ϳ{Fj¿À?ÏñX@–P?Ð& Ôï?Ð5*–ïíà?ÐR¸û²È?ÐoÐp&ßP?ÐŒp1W(?Ш—|@“È?ÐÄEÚÿx?Ðßy±|™P?Ðú3"Ú£x?Ñq, Mx?Ñ.3{³h?ÑGx.ÞÈ?Ñ`?ÀÒÅÈ?Ñx‰xLH?ÑSœãAØ?ѧžŽad¨?ѾiKŸ^h?ÑÔ³.¨ÇX?Ñê{“è#€?ÑÿÁÚ&ä°?Ò…bhè?Ò(Å¢ü0?Ò<ÊMÖØ?ÒO¹wÓ°?ÒblÖæ?Òt˜Û\,¸?Ò†?mÄß0?Ò—_,Ñ×H?Ò§÷Œ¢Ûø?Ò¸¶ p?ÒÇ êÅà?ÒÖ{Ù€?Òå¹V€?Òòð]¤`?ÓQJÀ?Ó 'ÍôP?Ór£ÿfÐ?Ó%1›y‹°?Ó0d?Zl@?Ó; Õýð?ÓE"Ç#à?ÓN­ÏG® ?ÓWªÊ€YÐ?Ó`PØÐp?Ógøü_©?ÓoIi‚i0?Óv 7 à?Ó|;,LP?ÓÛzi`?Ó†ë9­@?Ó‹iì@ƒ ?ÓW<ÊVð?Ó’²ØPšP?Ó•|n89€?Ó—³°E 0?Ó™XR™Ûð?Óšj ¸Yp?Óšè”%0?ÓšÓ¨3Íp?Óš+nË?Ó˜îi/‡?Ó—˜ÒUð?Ó”¸Xwp?Ó‘¾n °?ÓŽ/¤2\ ?ÓŠ ÆcD0?Ó…R¢ÓÆð?Ó€ È?ÓzÏ*?Ós¥ÇXn@?Ól•ÊWz@?Ódï²8Ð?Ó\³[lôà?ÓSà¤ÃWÀ?ÓJwojVà?Ó@wžï<ð?Ó5á>A ?Ó*³Æ¢‰ ?Óï‘Æ& ?Ó”g²@?Ó¢7ÎHð?Òøóá’Ð?Òéøº ?ÒÛAãs€?ÒËòE:^?Ò¼ RY°?Ò«'àæÀ?ÒšzÅÒf@?ÒˆÏ.ŒØ?ÒvŒfÎ~p?Òc²u´† ?ÒPAd» ?Ò<9?½°?Ò'šô™ð?Òcôúz0?Ñü–òÆ…À?Ñæ3#¯xÀ?ÑÏ8Ÿjü ?Ñ·§€ §?ÑŸâ ûÀ?цÁä5j0?Ñmm§¾P@?ÑSƒP5ø`?Ñ9‹™0?Ñìê Wà?ÑA.hD?Ðåÿý¨^Ð?ÐÉ)‡8‘?Ы½üâ´p?н’ÏŽ?Ðo(†ÏÐ?ÐOþûïP?Ð0ACMù`?Ðï“Gæ`?ÏÞWÀ@?Ï›"žòãÀ?ÏW …©HÀ?ÏÌš$À?ÎËioaŽ€?΃á³@?Î;5¿ÒsÀ?Íñfx·€?ͦtm¨€?ÍZ`I§4€?Í *»Öƒ@?̾ÔxÁ€?Ìo^8õÀ?Ìȹ±þ@?Ë;N–?ËzC ŒP?Ë&TsO—@?ÊÑIÀ:¸À?Ê{#É­Ó€?Ê#ãiÆã@?Éˉa¾?ÉrîÀ?ÉŒžAo@?È»ë|ó2À?È_4|Ÿ?Èh‘úÉ?Ç¢ˆº0¥@?ÇB•ô®ÿ€?Æá‘F@}@?Æ{¸mŸ€?ÆVY|¿À?Ÿ"¿¿±R†o`¿²G#\®É€¿³|D _–¿´²°V ¿µêcx²¹¿·#Xù]ŒAÎ…¿¹˜ø®êF¿ºÕ™–]z€¿¼jCÈ6€¿½ReùNÓ¿¾’‡ï™ñ€¿¿ÓËUÖ‡¿À‹¨Ú怿Á,Ѷ§€¿ÁϸÛr€¿ÂqâØèU¿Ã3_¾ƒ€¿Ã¹È`€¿Ä]W‰–j€¿Å&¥I¿Å§nÖ—Ì¿ÆM/7™è¿Æód›´¿Çš _Çt€¿ÈA#ß•Œ€¿Èè¨o¸‡€¿É—`§¿Ê8íþ¿Êá© †¿ËŠÇU»€¿Ì4D¦S¿ÌÞuŽs¿ÍˆR;wm€¿Î2ݧ€¿Îݼ¥€¿ÏˆìŽ;®¿Ð5¾»z@¿ÐpÒŸÀ¿ÐÆ$¥+…€¿ÑQ)/xÀ¿ÑrŸèÝ¿ÑÉ ö(À¿Ò™EÊãÀ¿ÒvB‡-ª@¿ÒÍ7º+€¿Ó#åÒ &€¿ÓzÜаr¿ÓÑê¨\õ¿Ô) ͸©€¿Ô€D²w€¿Ô×Åîñ€¿Õ.çuØ@¿Õ†P*€˜€¿ÕÝÆNjŒ€¿Ö5HF¬€¿ÖŒÔv¿Ñ@¿Öäi?Á4¿×<l퀿ד¦ µ€¿×ëJ×ÛW@¿ØBñ <±¿Øš˜Ã…´€¿Øò>”˜eÀ¿ÙIác÷ÛÀ¿Ù¡È?À¿Ùù3ÎЀ¿ÚP¦ÉqÝÀ¿Ú¨,‡¸É@¿Úÿ¦³L ¿ÛWŽu*@¿Û®qYÄÀ¿Ü¾PÔˆ¿Ü\ø°Ã7¿Ü´±¸¦€¿Ý .Š#¿¿Ýb&nyÀ¿Ý¹;äÀ¿ÞÇì$@¿ÞflDg€¿Þ¼ò/Tø¿ßW×-À¿ßi˜ðuyÀ¿ß¿¶§V€¿à ÖB¬à¿à5½8d“à¿à`Žöæ½`¿à‹J‹GÀ¿àµïS÷à¿àà{c¬p@¿á ü`¿á5HÎ¥`¿á_†lé@¿á‰¨Òð2 ¿á³®H•Ü¿áÝ•Ñ\2`¿â^o•ðÀ¿â1$f[ ¿âZŽïÁ@¿âƒôÐjö`¿â­7Ãøa ¿âÖVÆÎéà¿âÿPÔ$…`¿ã($åÿ° ¿ãPÑõ7rÀ¿ãyVùs] ¿ã¡²é+‰€¿ãÉ乨šà¿ãñë_¿€¿äÅÌ&­@¿äAròˤ€¿ähñÃ}nÀ¿äA-—_ ¿ä·`ER¿äÞM…ƒ®@¿åLb@¿å+]µç ¿åQᣵ@À¿åwþ[ú¿åãl¹(€¿åü¬k¿åéÚåêÀ¿æ>ªæY€¿æ3=þò ¿æWþèQy ¿æ|ƒÐ?@¿æ Èy>À¿æÄÍí.lÀ¿æè’O à¿ç yö«`¿ç/SH €¿çRM’à¿çu/°ê¿ç—o÷e@¿ç¹•¾ro ¿çÛrXðŸÀ¿çý™ÇÞ¿èKR°ì@¿è?ET5€¿è_ñm®%À¿è€NmF@¿è [ù ¿èÀQ‘5À¿èß~̪ø€¿èþ“Z²ÕÀ¿éRÃåÛ¿é;»ÏQ›€¿éYÍBÔ9@¿éw…ã[€¿é”äs©5¿é±ç¶Ê€À¿éÎŽm „€¿éê×X@¿êÁ4þx@¿ê"JÁÙ À¿ê=r»õÀ¿êX7ÛÔj@¿êr˜Þ*|€¿êŒ”zæ4À¿ê¦)i¬$¿ê¿V`ñd€¿êØûš€¿êðs<àó@¿ë`ˆˆ&@¿ëનs¿ë6òSɤÀ¿ëM”3DÀ¿ëcÄ÷@€¿ëyƒL¸‡@¿ëŽÍßuí¿ë££Z7€¿ë¸eûiÀ¿ëËé«j¿ëßWÑkA@¿ëòK}Ûœ@¿ìÃUhI€¿ì½ûŽû€¿ì(:î@¿ì96;³ç@¿ìI±À5@¿ìY©B‚±@¿ìi\‹»€¿ìx ÉÓ¢¿âöaüäK¿â¬ÉÒ™¼€¿âaþ°­Ð€¿âþ´ªê¿áÈÇúëó¿ázXžœc¿á*®¹¸9¿àÙÈe þ¿à‡£¸4¿à4>É $¿ß¿/]Œ¿ßXö±¿Þdöƒä%¿Ý´)õl¿Ý~ D¿ÜJ`@qá¿Û‘¦ëÁt¿ÚÖN%¤¿ÚRöR¿ÙW®†x¿Ø”`Ž¿×ÎbIuQ¿×±zEP¿Ö:I¢¨W¿Õl&Ë鸿ԛDüõÙ¿ÓÇ :Z6¿Òñ4†E\¿Òýà†ê¿Ñ;øF•¿Ð]³q ¿Îöà?¼Æ¿Í-ËVš¿Ë^÷œ™¶¿ÉŠ]ë²@¿Ç¯õÐz¿ÅÏ·#^Ü¿Ã険•ø¿Áý•e芿À ¡ðÍt¿¼'nCûp¿¸+™vé¿´#´ôÞp¿°°.Úx¿§ÞõÀ迟 ­ß€¿ŒQÑdÀ?g^A'€?”2G?4à?¢Õk÷H?«ªÞ¼°È?²LÎÒIH?¶Ðå;û ?»aÉEˆ?¿ÿz±x¸?ÂU Ú±f?İÛϦr?Ç/Á}ö?É|>Ø@?Ëë‹Ûz?Îa¥.K ?Ðo3j­I?Ѱì¸ì?ÒöÕ Å?Ô>z™D?ÕŠVÏz ?ÖÙ_öì?Ø,R"¶!?Ù‚yv½)?ÚܽpY?Ü91Z’ø?ݙʴG3?Þýè3$?à2Ç ãì€?àè`¦Ù¤?áŸÂã7+?âXðúê?ãêdR¿€?ãдœ€?äOzc}?åO¾µes€?æž?æÖ!Å÷,€?çœìÅ?ècïUè„€?é-£´“þ€?éù9}È<?êÆ²÷½€?ë–iy€?ìgZÛÝ€?í:ŒVbÍ?î«fw¢?îæ¹—.?5Q¶€?ðMVGÈ~À?ð»Êú©?ñ+;Û¤@?ñ›ª¬F€?ò ÌI¶€?òƒ/×À?òòðhakÀ?óg_¡äñÀ?óÜÒ¡?ôSHÇdo?ôÊÅ ø Àastroquery-0.2.4/astroquery/alfalfa/tests/setup_package.py0000644000077000000240000000037312464716555024131 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import os def get_package_data(): paths = [os.path.join('data', '*.txt'), os.path.join('data', '*.fits'), ] return {'astroquery.alfalfa.tests': paths} astroquery-0.2.4/astroquery/alfalfa/tests/test_alfalfa.py0000644000077000000240000000424412505065036023727 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst from contextlib import contextmanager import os import requests from astropy import coordinates from astropy.tests.helper import pytest from ...utils import commons from ...utils.testing_tools import MockResponse from ... import alfalfa DATA_FILES = {'catalog':'alfalfa_cat_small.txt', 'spectrum':'alfalfa_sp.fits'} class MockResponseAlfalfa(MockResponse): def __init__(self, content, **kwargs): super(MockResponseAlfalfa, self).__init__(content, **kwargs) def iter_lines(self): for l in self.text.split("\n"): yield l def close(self): pass @pytest.fixture def patch_get(request): mp = request.getfuncargvalue("monkeypatch") mp.setattr(requests, 'get', get_mockreturn) return mp @pytest.fixture def patch_get_readable_fileobj(request): @contextmanager def get_readable_fileobj_mockreturn(filename, **kwargs): file_obj = data_path(DATA_FILES['spectrum']) # TODO: add images option yield open(file_obj, 'rb') # read as bytes, assuming FITS mp = request.getfuncargvalue("monkeypatch") mp.setattr(commons, 'get_readable_fileobj', get_readable_fileobj_mockreturn) return mp def get_mockreturn(url, params=None, timeout=10): filename = data_path(DATA_FILES['catalog']) content = open(filename, 'rb').read() return MockResponseAlfalfa(content) def data_path(filename): data_dir = os.path.join(os.path.dirname(__file__), 'data') return os.path.join(data_dir, filename) # Test Case: A Seyfert 1 galaxy coords = coordinates.SkyCoord('0h8m05.63s +14d50m23.3s') ALFALFA = alfalfa.core.Alfalfa() def test_alfalfa_catalog(patch_get, patch_get_readable_fileobj, coords=coords): cat = ALFALFA.get_catalog() assert len(cat) > 0 def test_alfalfa_crossID(patch_get, patch_get_readable_fileobj, coords=coords): agc = ALFALFA.query_region(coords, optical_counterpart=True) assert agc == 100051 def test_alfalfa_spectrum(patch_get, patch_get_readable_fileobj, coords=coords): agc = ALFALFA.query_region(coords, optical_counterpart=True) sp = ALFALFA.get_spectrum(agc) assert len(sp) == 3 astroquery-0.2.4/astroquery/alma/0000755000077000000240000000000012505171566017114 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alma/__init__.py0000644000077000000240000000164012464716555021235 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst """ ALMA Archive service. """ from astropy import config as _config class Conf(_config.ConfigNamespace): """ Configuration parameters for `astroquery.alma`. """ timeout = _config.ConfigItem(60, "Timeout in seconds") archive_url = _config.ConfigItem(['http://almascience.org', 'http://almascience.eso.org', 'http://almascience.nrao.edu', 'http://almascience.nao.ac.jp', 'http://beta.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/aq', # the beta server (for testing) ], 'The ALMA Archive mirror to use') conf = Conf() from .core import Alma, AlmaClass __all__ = ['Alma', 'AlmaClass', 'Conf', 'conf', ] astroquery-0.2.4/astroquery/alma/core.py0000644000077000000240000011307412505170701020412 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst from __future__ import print_function import time import sys import os.path import webbrowser import getpass import warnings import keyring import numpy as np import re import tarfile import string from bs4 import BeautifulSoup from astropy.extern.six.moves.urllib_parse import urljoin from astropy.extern.six import BytesIO,iteritems from astropy.extern import six from astropy.table import Table, Column from astropy import log from astropy.utils.console import ProgressBar from astropy import units as u import astropy.io.votable as votable from ..exceptions import (LoginError, RemoteServiceError, TableParseError, InvalidQueryError) from ..utils import schema, system_tools from ..utils import commons from ..utils.process_asyncs import async_to_sync from ..query import BaseQuery, QueryWithLogin, suspend_cache from . import conf __doctest_skip__ = ['AlmaClass.*'] @async_to_sync class AlmaClass(QueryWithLogin): TIMEOUT = conf.timeout archive_url = conf.archive_url def __init__(self): super(AlmaClass, self).__init__() def query_object_async(self, object_name, cache=True, public=True, science=True, payload=None, **kwargs): """ Query the archive with a source name Parameters ---------- object_name : str The object name. Will be parsed by SESAME on the ALMA servers. cache : bool Cache the query? public : bool Return only publicly available datasets? science : bool Return only data marked as "science" in the archive? payload : dict Dictionary of additional keywords. See `help`. kwargs : dict Passed to `query_async` """ if payload is None: payload = {} payload.update({'source_name_resolver': object_name,}) return self.query_async(payload, cache=cache, public=public, science=science, **kwargs) def query_region_async(self, coordinate, radius, cache=True, public=True, science=True, payload=None, **kwargs): """ Query the ALMA archive with a source name and radius Parameters ---------- coordinates : str / `astropy.coordinates` the identifier or coordinates around which to query. radius : str / `~astropy.units.Quantity`, optional the radius of the region cache : bool Cache the query? public : bool Return only publicly available datasets? science : bool Return only data marked as "science" in the archive? payload : dict Dictionary of additional keywords. See `help`. kwargs : dict Passed to `query_async` """ coordinate = commons.parse_coordinates(coordinate) cstr = coordinate.fk5.to_string(style='hmsdms', sep=':') rdc = "{cstr}, {rad}".format(cstr=cstr, rad=radius.to(u.deg).value) if payload is None: payload = {} payload.update({'ra_dec': rdc}) return self.query_async(payload, cache=cache, public=public, science=science, **kwargs) def query_async(self, payload, cache=True, public=True, science=True): """ Perform a generic query with user-specified payload Parameters ---------- payload : dict A dictionary of payload keywords that are accepted by the ALMA archive system. You can look these up by examining the forms at http://almascience.org/aq or using the `help` method cache : bool Cache the query? public : bool Return only publicly available datasets? science : bool Return only data marked as "science" in the archive? """ url = urljoin(self._get_dataarchive_url(), 'aq/') payload.update({'result_view':'raw', 'format':'VOTABLE', 'download':'true'}) if public: payload['public_data'] = 'public' if science: payload['science_observations'] = '=%TARGET%' self.validate_query(payload) response = self._request('GET', url, params=payload, timeout=self.TIMEOUT, cache=cache) response.raise_for_status() return response def validate_query(self, payload, cache=True): """ Use the ALMA query validator service to check whether the keywords are valid """ # Check that the keywords specified are allowed self._validate_payload(payload) vurl = self._get_dataarchive_url() + '/aq/validate' bad_kws = {} for kw in payload: vpayload = {'field':kw, kw: payload[kw]} response = self._request('GET', vurl, params=vpayload, cache=cache, timeout=self.TIMEOUT) if response.content: bad_kws[kw] = response.content if bad_kws: raise InvalidQueryError("Invalid query parameters: " "{0}".format(bad_kws)) def _get_dataarchive_url(self): """ If the generic ALMA URL is used, query it to determine which mirror to access for querying data """ if not hasattr(self, 'dataarchive_url'): if self.archive_url == 'http://almascience.org': response = self._request('GET', self.archive_url+"/aq", cache=False) response.raise_for_status() self.dataarchive_url = response.url.replace("/aq/","") else: self.dataarchive_url = self.archive_url return self.dataarchive_url def stage_data(self, uids): """ Stage ALMA data Parameters ---------- uids : list or str A list of valid UIDs or a single UID. UIDs should have the form: 'uid://A002/X391d0b/X7b' cache : True This is *forced* true, because the ALMA servers don't support repeats of the same request. Whether to cache the staging process. This should generally be left as False when used interactively. Returns ------- data_file_table : Table A table containing 3 columns: the UID, the file URL (for future downloading), and the file size """ """ With log.set_level(10) INFO: Staging files... [astroquery.alma.core] DEBUG: First request URL: https://almascience.eso.org/rh/submission [astroquery.alma.core] DEBUG: First request payload: {'dataset': [u'ALMA+uid___A002_X3b3400_X90f']} [astroquery.alma.core] DEBUG: First response URL: https://almascience.eso.org/rh/checkAuthenticationStatus/3f98de33-197e-4692-9afa-496842032ea9/submission [astroquery.alma.core] DEBUG: Request ID: 3f98de33-197e-4692-9afa-496842032ea9 [astroquery.alma.core] DEBUG: Submission URL: https://almascience.eso.org/rh/submission/3f98de33-197e-4692-9afa-496842032ea9 [astroquery.alma.core] .DEBUG: Data list URL: https://almascience.eso.org/rh/requests/anonymous/786823226 [astroquery.alma.core] """ if isinstance(uids, six.string_types): uids = [uids] if not isinstance(uids, (list, tuple, np.ndarray)): raise TypeError("Datasets must be given as a list of strings.") log.info("Staging files...") self._get_dataarchive_url() url = urljoin(self.dataarchive_url, 'rh/submission') log.debug("First request URL: {0}".format(url)) #'ALMA+uid___A002_X391d0b_X7b' #payload = [('dataset','ALMA+'+clean_uid(uid)) for uid in uids] payload = {'dataset':['ALMA+'+clean_uid(uid) for uid in uids]} log.debug("First request payload: {0}".format(payload)) self._staging_log = {'first_post_url':url} # Request staging for the UIDs # This component cannot be cached, since the returned data can change # if new data are uploaded response = self._request('POST', url, data=payload, timeout=self.TIMEOUT, cache=False) self._staging_log['initial_response'] = response log.debug("First response URL: {0}".format(response.url)) response.raise_for_status() if 'j_spring_cas_security_check' in response.url: time.sleep(1) # CANNOT cache this stage: it not a real data page! results in # infinite loops response = self._request('POST', url, data=payload, timeout=self.TIMEOUT, cache=False) self._staging_log['initial_response'] = response if 'j_spring_cas_security_check' in response.url: log.warn("Staging request was not successful. Try again?") response.raise_for_status() request_id = response.url.split("/")[-2] assert len(request_id) == 36 self._staging_log['request_id'] = request_id log.debug("Request ID: {0}".format(request_id)) # Submit a request for the specific request ID identified above submission_url = urljoin(self.dataarchive_url, os.path.join('rh/submission', request_id)) log.debug("Submission URL: {0}".format(submission_url)) self._staging_log['submission_url'] = submission_url has_completed = False staging_submission = self._request('GET', submission_url, cache=True) self._staging_log['staging_submission'] = staging_submission staging_submission.raise_for_status() data_page_url = staging_submission.url dpid = data_page_url.split("/")[-1] assert len(dpid) == 9 self._staging_log['staging_page_id'] = dpid while not has_completed: time.sleep(1) # CANNOT cache this step: please_wait will happen infinitely data_page = self._request('GET', data_page_url, cache=False) if 'Please wait' not in data_page.text: has_completed = True print(".",end='') self._staging_log['data_page'] = data_page data_page.raise_for_status() staging_root = BeautifulSoup(data_page.content) downloadFileURL = staging_root.find('form').attrs['action'] data_list_url = os.path.split(downloadFileURL)[0] # Old version, unreliable: data_list_url = staging_submission.url log.debug("Data list URL: {0}".format(data_list_url)) self._staging_log['data_list_url'] = data_list_url time.sleep(1) data_list_page = self._request('GET', data_list_url, cache=True) self._staging_log['data_list_page'] = data_list_page data_list_page.raise_for_status() if 'Error' in data_list_page.text: errormessage = root.find('div', id='errorContent').string.strip() raise RemoteServiceError(errormessage) tbl = self._parse_staging_request_page(data_list_page) return tbl def _HEADER_data_size(self, files): """ Given a list of file URLs, return the data size. This is useful for assessing how much data you might be downloading! (This is discouraged by the ALMA archive, as it puts unnecessary load on their system) """ totalsize = 0*u.B data_sizes = {} pb = ProgressBar(len(files)) for ii,fileLink in enumerate(files): response = self._request('HEAD', fileLink, stream=False, cache=False, timeout=self.TIMEOUT) filesize = (int(response.headers['content-length'])*u.B).to(u.GB) totalsize += filesize data_sizes[fileLink] = filesize log.debug("File {0}: size {1}".format(fileLink, filesize)) pb.update(ii+1) response.raise_for_status() return data_sizes,totalsize.to(u.GB) def download_files(self, files, cache=True): """ Given a list of file URLs, download them Note: Given a list with repeated URLs, each will only be downloaded once, so the return may have a different length than the input list """ downloaded_files = [] for fileLink in unique(files): filename = self._request("GET", fileLink, save=True, timeout=self.TIMEOUT) downloaded_files.append(filename) return downloaded_files def retrieve_data_from_uid(self, uids, cache=True): """ Stage & Download ALMA data. Will print out the expected file size before attempting the download. Parameters ---------- uids : list or str A list of valid UIDs or a single UID. UIDs should have the form: 'uid://A002/X391d0b/X7b' cache : bool Whether to cache the downloads. Returns ------- downloaded_files : list A list of the downloaded file paths """ if isinstance(uids, six.string_types): uids = [uids] if not isinstance(uids, (list, tuple, np.ndarray)): raise TypeError("Datasets must be given as a list of strings.") files = self.stage_data(uids, cache=cache) file_urls = files['URL'] totalsize = files['size'].sum()*files['size'].unit #log.info("Determining download size for {0} files...".format(len(files))) #each_size,totalsize = self.data_size(files) log.info("Downloading files of size {0}...".format(totalsize.to(u.GB))) # TODO: Add cache=cache keyword here. Currently would have no effect. downloaded_files = self.download_files(file_urls) return downloaded_files def _parse_result(self, response, verbose=False): """ Parse a VOtable response """ if not verbose: commons.suppress_vo_warnings() tf = six.BytesIO(response.content) vo_tree = votable.parse(tf, pedantic=False, invalid='mask') first_table = vo_tree.get_first_table() table = first_table.to_table(use_names_over_ids=True) return table def _login(self, username, store_password=False): # Check if already logged in loginpage = self._request("GET", "https://asa.alma.cl/cas/login", cache=False) root = BeautifulSoup(loginpage.content, 'html5lib') if root.find('div', class_='success'): log.info("Already logged in.") return True # Get password from keyring or prompt password_from_keyring = keyring.get_password("astroquery:asa.alma.cl", username) if password_from_keyring is None: if system_tools.in_ipynb(): log.warn("You may be using an ipython notebook:" " the password form will appear in your terminal.") password = getpass.getpass("{0}, enter your ALMA password:" "\n".format(username)) else: password = password_from_keyring # Authenticate log.info("Authenticating {0} on asa.alma.cl ...".format(username)) # Do not cache pieces of the login process data = {kw:root.find('input', {'name':kw})['value'] for kw in ('lt','_eventId','execution')} data['username'] = username data['password'] = password login_response = self._request("POST", "https://asa.alma.cl/cas/login", params={'service': urljoin(self.archive_url, 'rh/login')}, data=data, cache=False) authenticated = ('You have successfully logged in' in login_response.content) if authenticated: log.info("Authentication successful!") else: log.exception("Authentication failed!") # When authenticated, save password in keyring if needed if authenticated and password_from_keyring is None and store_password: keyring.set_password("astroquery:asa.alma.cl", username, password) return authenticated def get_cycle0_uid_contents(self, uid): """ List the file contents of a UID from Cycle 0. Will raise an error if the UID is from cycle 1+, since those data have been released in a different and more consistent format. See http://almascience.org/documents-and-tools/cycle-2/ALMAQA2Productsv1.01.pdf for details. """ # First, check if UID is in the Cycle 0 listing if uid in self.cycle0_table['uid']: cycle0id = self.cycle0_table[self.cycle0_table['uid'] == uid][0]['ID'] contents = [row['Files'] for row in self._cycle0_tarfile_content if cycle0id in row['ID']] return contents else: info_url = urljoin(self._get_dataarchive_url(), 'documents-and-tools/cycle-2/ALMAQA2Productsv1.01.pdf') raise ValueError("Not a Cycle 0 UID. See {0} for details about" " cycle 1+ data release formats.".format(info_url)) @property def _cycle0_tarfile_content(self): """ In principle, this is a static file, but we'll retrieve it just in case """ if not hasattr(self, '_cycle0_tarfile_content_table'): url = urljoin(self._get_dataarchive_url(), 'alma-data/archive/cycle-0-tarfile-content') response = self._request('GET', url, cache=True) # html.parser is needed because some 's have form: # which the default parser does not pick up root = BeautifulSoup(response.content, 'html.parser') html_table = root.find('table',class_='grid listing') data = list(zip(*[(x.findAll('td')[0].text, x.findAll('td')[1].text) for x in html_table.findAll('tr')])) columns = [Column(data=data[0], name='ID'), Column(data=data[1], name='Files')] tbl = Table(columns) assert len(tbl) == response.text.count(' 0: raise InvalidQueryError("The following parameters are not accepted " "by the ALMA query service:" " {0}".format(invalid_params)) def _parse_staging_request_page(self, data_list_page): """ Parse pages like this one: https://almascience.eso.org/rh/requests/anonymous/786572566 that include links to data sets that have been requested and staged Parameters ---------- data_list_page : requests.Response object """ root = BeautifulSoup(data_list_page.content, 'html5lib') #for link in root.findAll('a'): # if 'script.sh' in link.text: # download_script_url = urljoin(self.dataarchive_url, # link['href']) #if 'download_script_url' not in locals(): # raise RemoteServiceError("No download links were found.") #download_script = self._request('GET', download_script_url, # cache=False) #download_script_target_urls = [] #for line in download_script.text.split('\n'): # if line and line.split() and line.split()[0] == 'wget': # download_script_target_urls.append(line.split()[1].strip('"')) #if len(download_script_target_urls) == 0: # raise RemoteServiceError("There was an error parsing the download " # "script; it is empty. " # "You can access the download script " # "directly from this URL: " # "{0}".format(download_script_url)) data_table = root.findAll('table', class_='list', id='report')[0] columns = {'uid':[], 'URL':[], 'size':[]} for tr in data_table.findAll('tr'): tds = tr.findAll('td') # Cannot check class if it is not defined cl = 'class' in tr.attrs if len(tds) > 1 and 'uid' in tds[0].text and (cl and 'Level' in tr['class'][0]): # New Style text = tds[0].text.strip().split() if text[0] in ('Asdm', 'Member'): uid = text[-1] elif len(tds) > 1 and 'uid' in tds[1].text: # Old Style uid = tds[1].text.strip() elif cl and tr['class'] == 'Level_1': raise ValueError("A heading was found when parsing the download page but " "it was not parsed correctly") if len(tds) > 3 and (cl and tr['class'][0] == 'fileRow'): # New Style size,unit = re.search('(-|[0-9\.]*)([A-Za-z]*)', tds[2].text).groups() href = tds[1].find('a') if size == '': # this is a header row continue authorized = ('access_authorized.png' in tds[3].findChild('img')['src']) if authorized: columns['uid'].append(uid) if href and 'href' in href.attrs: columns['URL'].append(href.attrs['href']) else: columns['URL'].append('None_Found') unit = (u.Unit(unit) if unit in ('GB','MB') else u.Unit('kB') if 'kb' in unit.lower() else 1) try: columns['size'].append(float(size)*u.Unit(unit)) except ValueError: # size is probably a string? columns['size'].append(-1*u.byte) log.log(level=5, msg="Found a new-style entry. " "size={0} uid={1} url={2}".format(size, uid, columns['URL'][-1])) else: log.warn("Access to {0} is not authorized.".format(uid)) elif len(tds) > 3 and tds[2].find('a'): # Old Style href = tds[2].find('a') size,unit = re.search('([0-9\.]*)([A-Za-z]*)', tds[3].text).groups() columns['uid'].append(uid) columns['URL'].append(href.attrs['href']) unit = (u.Unit(unit) if unit in ('GB','MB') else u.Unit('kB') if 'kb' in unit.lower() else 1) columns['size'].append(float(size)*u.Unit(unit)) log.log(level=5, msg="Found an old-style entry. " "size={0} uid={1} url={2}".format(size, uid, columns['URL'][-1])) columns['size'] = u.Quantity(columns['size'], u.Gbyte) if len(columns['uid']) == 0: raise RemoteServiceError("No valid UIDs were found in the staged " "data table. Please include {0} " "in a bug report." .format(self._staging_log['data_list_url'])) #if len(download_script_target_urls) != len(columns['URL']): # log.warn("There was an error parsing the data staging page. " # "The results from the page and the download script " # "differ. You can access the download script directly " # "from this URL: {0}".format(download_script_url)) #else: # bad_urls = [] # for (rurl,url) in (zip(columns['URL'], # download_script_target_urls)): # if rurl == 'None_Found': # url_uid = os.path.split(url)[-1] # ind = np.where(np.array(columns['uid']) == url_uid)[0][0] # columns['URL'][ind] = url # elif rurl != url: # bad_urls.append((rurl, url)) # if bad_urls: # log.warn("There were mismatches between the parsed URLs " # "from the staging page ({0}) and the download " # "script ({1})." # .format(self._staging_log['data_list_url'], # download_script_url)) tbl = Table([Column(name=k, data=v) for k,v in iteritems(columns)]) return tbl Alma = AlmaClass() def clean_uid(uid): """ Return a uid with all unacceptable characters replaced with underscores """ try: return uid.decode('utf-8').replace(u"/",u"_").replace(u":",u"_") except AttributeError: return uid.replace("/","_").replace(":","_") def reform_uid(uid): """ Convert a uid with underscores to the original format """ return uid[:3]+"://" + "/".join(uid[6:].split("_")) def unique(seq): """ Return unique elements of a list, preserving order """ seen = set() seen_add = seen.add return [x for x in seq if not (x in seen or seen_add(x))] def filter_printable(s): """ extract printable characters from a string """ return filter(lambda x: x in string.printable, s) def parse_frequency_support(frequency_support_str): """ ALMA "Frequency Support" strings have the form: [100.63..101.57GHz,488.28kHz, XX YY] U [102.43..103.37GHz,488.28kHz, XX YY] U [112.74..113.68GHz,488.28kHz, XX YY] U [114.45..115.38GHz,488.28kHz, XX YY] at least, as far as we have seen. The "U" is meant to be the Union symbol. This function will parse such a string into a list of pairs of astropy Quantities representing the frequency range. It will ignore the resolution and polarizations. """ supports = frequency_support_str.split("U") freq_ranges = [(float(sup.strip('[] ').split("..")[0]), float(sup.strip('[] ').split("..")[1].split(',')[0].strip(string.letters))) *u.Unit(sup.strip('[] ').split("..")[1].split(',')[0].strip(string.punctuation+string.digits)) for sup in supports] return freq_ranges def approximate_primary_beam_sizes(frequency_support_str, dish_diameter=12*u.m, first_null=1.220): """ Using parse_frequency_support, determine the mean primary beam size in each observed band Parameters ---------- frequency_support_str : str The frequency support string, see `parse_frequency_support` dish_diameter : `~astropy.units.Quantity` Meter-equivalent unit. The diameter of the dish. first_null : float The position of the first null of an Airy. Used to compute resolution as :math:`R = 1.22 \lambda/D` """ freq_ranges = parse_frequency_support(frequency_support_str) beam_sizes = [(first_null*fr.mean().to(u.m, u.spectral())/(dish_diameter)).to(u.arcsec, u.dimensionless_angles()) for fr in freq_ranges] return beam_sizes astroquery-0.2.4/astroquery/alma/data/0000755000077000000240000000000012505171566020025 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alma/data/cycle0_delivery_asdm_mapping.txt0000644000077000000240000010724112464716555026403 0ustar adamstaff000000000000002011.0.00170.S_2013-07-22 uid://A002/X5784d5/X15c 2011.0.00629.S_2013-02-21 uid://A002/X51d696/X315 2011.0.00170.S_2013-03-01 uid://A002/X5578f1/X1b8 2011.0.00175.S_2013-03-05 uid://A002/X40e374/X6cb 2011.0.00020.S_2012-12-01 uid://A002/X518d2b/Xbde 2011.0.00199.S_2013-03-01 uid://A002/X590461/X620 2011.0.00611.S_2013-03-01 uid://A002/X36a70f/X4ce 2011.0.00611.S_2013-03-01 uid://A002/X36a70f/X77a 2011.0.00611.S_2013-03-01 uid://A002/X535168/X435 2011.0.00611.S_2013-03-01 uid://A002/X535168/X66e 2011.0.00611.S_2013-03-01 uid://A002/X537777/X326 2011.0.00777.S_2013-03-01 uid://A002/X590461/Xc05 2011.0.00210.S_2013-02-27 uid://A002/X537777/X1de 2011.0.00210.S_2013-02-27 uid://A002/X537777/X426 2011.0.00772.S_2012-12-01 uid://A002/X4b29af/X24c 2011.0.00772.S_2012-12-01 uid://A002/X4b29af/X5c 2011.0.00175.S_2013-03-05 uid://A002/X40e374/X88e 2011.0.00232.S_2013-02-28 uid://A002/X54face/X1b5 2011.0.00735.S_2012-01-13 uid://A002/X36e26f/X22 2011.0.00647.S_2013-02-11 uid://A002/X52f1e2/X4af 2011.0.00367.S_2013-02-28 uid://A002/X54face/X623 2011.0.00367.S_2013-02-28 uid://A002/X5552a3/X7d0 2011.0.00367.S_2013-02-28 uid://A002/X56a957/Xa82 2011.0.00367.S_2013-02-28 uid://A002/X574c40/X263 2011.0.00367.S_2013-02-28 uid://A002/X579ce0/X36 2011.0.00367.S_2013-02-28 uid://A002/X383b50/X7b4 2011.0.00469.S_2013-02-28 uid://A002/X2eea47/X464 2011.0.00469.S_2013-02-28 uid://A002/X307fb7/X343 2011.0.00469.S_2013-02-28 uid://A002/X307fb7/X4a9 2011.0.00469.S_2013-02-28 uid://A002/X307fb7/X60f 2011.0.00469.S_2013-02-28 uid://A002/X4ba082/X36f 2011.0.00469.S_2013-02-28 uid://A002/X535168/X166 2011.0.00469.S_2013-02-28 uid://A002/X54d35d/X1f7 2011.0.00469.S_2013-02-28 uid://A002/X54d35d/X3be 2011.0.00469.S_2013-02-28 uid://A002/X2eea47/X322 2011.0.00629.S_2013-02-21 uid://A002/X51d696/Xef 2011.0.00170.S_2013-03-16 uid://A002/X56a957/X25b 2011.0.00777.S_2012-03-11 uid://A002/X590461/Xda3 2011.0.00808.S_2012-03-12 uid://A002/X36ffba/X1bb 2011.0.00131.S_2012-01-23 uid://A002/X2c75ca/X7ce 2011.0.00175.S_2013-03-05 uid://A002/X41e287/X591 2011.0.00020.S_2013-03-06 uid://A002/X32d5f1/X832 2011.0.00020.S_2013-03-06 uid://A002/X41ac1f/X21f 2011.0.00020.S_2013-03-06 uid://A002/X518d2b/X36e 2011.0.00020.S_2013-03-06 uid://A002/X535168/Xb6c 2011.0.00020.S_2013-03-06 uid://A002/X539bb9/X99 2011.0.00419.S_2013-03-06 uid://A002/X3dc0e7/Xbbc 2011.0.00419.S_2013-03-06 uid://A002/X4b1170/X226 2011.0.00419.S_2013-02-28 uid://A002/X3fa880/X52d 2011.0.00419.S_2013-02-28 uid://A002/X3fbe56/Xa24 2011.0.00419.S_2013-02-28 uid://A002/X40f691/X70e 2011.0.00419.S_2013-02-28 uid://A002/X4b1170/X57 2011.0.00319.S_2012-08-30 uid://A002/X435875/X371 2011.0.00131.S_2011-12-06 uid://A002/X2eaf7f/X43 2011.0.00647.S_2013-01-02 uid://A002/X52f1e2/X309 2011.0.00647.S_2013-01-02 uid://A002/X532128/X214 2011.0.00647.S_2013-01-02 uid://A002/X52f1e2/X182 2011.0.00647.S_2013-01-02 uid://A002/X532128/X8d 2011.0.00150.S_2013-03-21 uid://A002/X54d35d/X761 2011.0.00526.S_2012-09-14 uid://A002/X4b483b/X1ce 2011.0.00399.S_2012-12-17 uid://A002/X40e374/X366 2011.0.00399.S_2012-12-17 uid://A002/X5552a3/X9ef 2011.0.00150.S_2013-01-26 uid://A002/X54face/X434 2011.0.00150.S_2013-01-26 uid://A002/X3df8fa/Xf6 2011.0.00199.S_2013-04-05 uid://A002/X4fed6b/X1 2011.0.00199.S_2013-04-01 uid://A002/X518d2b/X8c8 2011.0.00199.S_2013-04-02 uid://A002/X4afc39/Xac8 2011.0.00199.S_2013-04-04 uid://A002/X460fc9/Xb16 2011.0.00199.S_2013-04-03 uid://A002/X463144/Xb67 2011.0.00780.S_2011-12-19 uid://A002/X305ca0/X637 2011.0.00780.S_2011-12-19 uid://A002/X305ca0/X33b 2011.0.00780.S_2011-12-19 uid://A002/X305ca0/X4b9 2011.0.00780.S_2011-12-19 uid://A002/X307fb7/X7a7 2011.0.00780.S_2011-12-19 uid://A002/X307fb7/X925 2011.0.00780.S_2011-12-19 uid://A002/X307fb7/Xa8b 2011.0.00780.S_2011-12-19 uid://A002/X307fb7/Xc2f 2011.0.00780.S_2011-12-19 uid://A002/X307fb7/Xd62 2011.0.00780.S_2011-12-19 uid://A002/X2f146f/X700 2011.0.00526.S_2013-02-14 uid://A002/X4b483b/X1ce 2011.0.00034.S_2013-05-06 uid://A002/X57d273/X230 2011.0.00034.S_2013-05-06 uid://A002/X57d273/X8e 2011.0.00034.S_2013-05-06 uid://A002/X590461/X11e1 2011.0.00064.S_2013-01-29 uid://A002/X3fa880/X4f 2011.0.00064.S_2013-01-29 uid://A002/X3cb0a0/X56e 2011.0.00064.S_2013-01-29 uid://A002/X40cb9e/X58 2011.0.00064.S_2013-01-29 uid://A002/X3cb0a0/X867 2011.0.00064.S_2013-01-29 uid://A002/X3e007f/X1f8 2011.0.00957.S_2012-03-12 uid://A002/X32041d/X30d 2011.0.00727.S_2013-05-03 uid://A002/X4320bd/X4b2 2011.0.00727.S_2013-05-03 uid://A002/X433c46/X19c 2011.0.00727.S_2013-05-03 uid://A002/X4785e0/X284 2011.0.00727.S_2013-05-03 uid://A002/X4b483b/X5c 2011.0.00656.S_2013-05-03 uid://A002/X497d07/X354 2011.0.00656.S_2013-05-03 uid://A002/X49b5dd/X23d 2011.0.00064.S_2013-01-29 uid://A002/X3df8fa/X30e 2011.0.00470.S_2013-06-17 uid://A002/X5784d5/X4f9 2011.0.00470.S_2013-06-17 uid://A002/X36a70f/Xab6 2011.0.00470.S_2013-06-17 uid://A002/X388522/X341 2011.0.00470.S_2013-06-17 uid://A002/X388522/X483 2011.0.00470.S_2013-06-17 uid://A002/X590461/X1853 2011.0.00863.S_2013-05-24 uid://A002/X574c40/X58c 2011.0.00863.S_2013-05-24 uid://A002/X574c40/X6f2 2011.0.00661.S_2013-06-13 uid://A002/X579ce0/X23b 2011.0.00820.S_2013-06-24 uid://A002/X590461/X1b27 2011.0.00777.S_2013-08-06 uid://A002/X579ce0/X4ba 2011.0.00777.S_2013-08-06 uid://A002/X57b9e2/X609 2011.0.00777.S_2013-08-06 uid://A002/X57b9e2/X739 2011.0.00767.S_2013-02-07 uid://A002/X43036c/X20a 2011.0.00767.S_2013-02-07 uid://A002/X460fc9/X113 2011.0.00767.S_2013-02-07 uid://A002/X479db5/X64 2011.0.00767.S_2013-02-07 uid://A002/X5673e2/X4f 2011.0.00320.S_2013-05-02 uid://A002/X496ee3/X4be 2011.0.00320.S_2013-05-02 uid://A002/X49be16/X3d1 2011.0.00320.S_2013-05-02 uid://A002/X515b5c/X616 2011.0.00524.S_2012-05-30 uid://A002/X36bf6c/X70e 2011.0.00273.S_2012-05-30 uid://A002/X3c7a84/X1c 2011.0.00467.S_2012-05-29 uid://A002/X30cca6/X254 2011.0.00229.S_2012-06-10 uid://A002/X3c9295/X1e0 2011.0.00229.S_2012-06-10 uid://A002/X3c9295/X8c 2011.0.00229.S_2012-06-10 uid://A002/X3ca066/X549 2011.0.00229.S_2012-06-10 uid://A002/X3ca066/X67f 2011.0.00229.S_2012-06-10 uid://A002/X3ca066/X7dc 2011.0.00229.S_2012-06-10 uid://A002/X3dc0e7/X3f2 2011.0.00229.S_2012-06-10 uid://A002/X3dc0e7/X528 2011.0.00229.S_2012-06-10 uid://A002/X3df8fa/X20b 2011.0.00229.S_2012-06-10 uid://A002/X3e007f/X54 2011.0.00531.S_2012-06-22 uid://A002/X3f6a86/X5da 2011.0.00531.S_2012-06-22 uid://A002/X3b3400/Xcd7 2011.0.00206.S_2012-06-22 uid://A002/X411025/X6d7 2011.0.00958.S_2012-06-21 uid://A002/X411025/X568 2011.0.00097.S_2012-06-05 uid://A002/X3dc0e7/X6ce 2011.0.00097.S_2012-06-05 uid://A002/X3ddbb0/X54 2011.0.00097.S_2012-06-05 uid://A002/X3ddbb0/Xc2 2011.0.00097.S_2012-06-05 uid://A002/X3ddbb0/X2e3 2011.0.00750.S_2012-06-05 uid://A002/X3c9295/X40f 2011.0.00750.S_2012-06-05 uid://A002/X3c9295/X539 2011.0.00750.S_2012-06-05 uid://A002/X3c9295/X820 2011.0.00750.S_2012-06-05 uid://A002/X3daf0c/X541 2011.0.00957.S_2012-06-28 uid://A002/X36e957/X604 2011.0.00259.S_2012-06-18 uid://A002/X307fb7/X224 2011.0.00259.S_2012-06-18 uid://A002/X3fce56/X626 2011.0.00259.S_2012-06-18 uid://A002/X4122f3/X258 2011.0.00628.S_2012-06-29 uid://A002/X3f6a86/Xb99 2011.0.00628.S_2012-06-29 uid://A002/X3fa880/X9aa 2011.0.00628.S_2012-06-29 uid://A002/X3fdb4f/X91c 2011.0.00628.S_2012-06-29 uid://A002/X3fdb4f/Xae8 2011.0.00628.S_2012-06-29 uid://A002/X3fdb4f/Xcb4 2011.0.00010.S_2012-05-07 uid://A002/X3fbe56/X48f 2011.0.00010.S_2012-05-07 uid://A002/X3fce56/X69 2011.0.00010.S_2012-06-28 uid://A002/X3fce56/X1e1 2011.0.00010.S_2012-06-28 uid://A002/X3fce56/X4ba 2011.0.00465.S_2012-06-28 uid://A002/X41c27b/X2fc 2011.0.00061.S_2012-03-12 uid://A002/X32d5f1/X937 2011.0.00061.S_2012-03-12 uid://A002/X32f7a3/X34 2011.0.00061.S_2012-03-12 uid://A002/X369097/X1e9 2011.0.00061.S_2012-03-12 uid://A002/X369097/X419 2011.0.00061.S_2012-03-12 uid://A002/X3302c8/Xe 2011.0.00099.S_2012-02-24 uid://A002/X30cca6/Xc0 2011.0.00099.S_2012-02-24 uid://A002/X305ca0/X792 2011.0.00099.S_2012-05-16 uid://A002/X3c7a84/X164 2011.0.00101.S_2012-04-17 uid://A002/X31d189/Xa50 2011.0.00101.S_2012-04-17 uid://A002/X36bf6c/X58a 2011.0.00108.S_2012-04-17 uid://A002/X30a93d/Xba7 2011.0.00108.S_2012-04-17 uid://A002/X30cca6/X342 2011.0.00525.S_2012-04-17 uid://A002/X35be16/Xeb 2011.0.00525.S_2012-04-17 uid://A002/X35e007/Xfd 2011.0.00525.S_2012-04-17 uid://A002/X388522/X1f3 2011.0.00525.S_2012-04-17 uid://A002/X388522/Xa5 2011.0.00525.S_2012-04-17 uid://A002/X383b50/Xdb7 2011.0.00199.S_2012-06-15 uid://A002/X3ca066/X114 2011.0.00206.S_2012-07-30 uid://A002/X41f8d2/X9e9 2011.0.00476.S_2012-07-30 uid://A002/X3e007f/X3ab 2011.0.00465.S_2012-08-03 uid://A002/X3daf0c/X34c 2011.0.00465.S_2012-08-03 uid://A002/X43036c/X410 2011.0.00275.S_2012-07-13 uid://A002/X3fce56/X7b5 2011.0.00275.S_2012-07-13 uid://A002/X40e374/Xa31 2011.0.00275.S_2012-07-13 uid://A002/X41065b/X1c2 2011.0.00275.S_2012-07-13 uid://A002/X41065b/X50 2011.0.00275.S_2012-07-13 uid://A002/X41c27b/X622 2011.0.00275.S_2012-07-13 uid://A002/X41d520/X97a 2011.0.00511.S_2013-01-03 uid://A002/X436934/X48c 2011.0.00511.S_2013-01-03 uid://A002/X4785e0/Xab0 2011.0.00010.S_2012-08-17 uid://A002/X3fce56/X34d 2011.0.00010.S_2012-08-17 uid://A002/X3fdb4f/X2f7 2011.0.00121.S_2012-07-30 uid://A002/X41e287/Xd1 2011.0.00121.S_2012-08-16 uid://A002/X41e287/X1da 2011.0.00467.S_2012-08-24 uid://A002/X44a295/X888 2011.0.00099.S_2012-08-23 uid://A002/X3f99b1/X3ec 2011.0.00958.S_2012-08-27 uid://A002/X43036c/X9c6 2011.0.00172.S_2013-01-14 uid://A002/X449249/X247 2011.0.00172.S_2013-01-14 uid://A002/X44a295/X94f 2011.0.00172.S_2013-01-14 uid://A002/X3fbe56/Xece 2011.0.00772.S_2012-09-12 uid://A002/X3fbe56/X607 2011.0.00772.S_2012-09-12 uid://A002/X3b3400/X90f 2011.0.00772.S_2012-09-12 uid://A002/X3b3400/Xaf3 2011.0.00539.S_2012-08-31 uid://A002/X45c06b/Xabf 2011.0.00175.S_2012-09-06 uid://A002/X460fc9/X2ef 2011.0.00175.S_2012-09-06 uid://A002/X44c3c1/X2b4 2011.0.00175.S_2012-09-06 uid://A002/X4320bd/X621 2011.0.00175.S_2012-09-06 uid://A002/X3ddbb0/X866 2011.0.00217.S_2012-09-06 uid://A002/X47aefc/X369 2011.0.00217.S_2012-09-06 uid://A002/X47bd4d/X4c7 2011.0.00217.S_2012-09-06 uid://A002/X47d651/X15d 2011.0.00217.S_2012-09-06 uid://A002/X47d651/X2fc 2011.0.00217.S_2012-09-06 uid://A002/X47ed8e/X533 2011.0.00217.S_2012-09-06 uid://A002/X47ed8e/X6c 2011.0.00273.S_2012-09-07 uid://A002/X3c8f66/X352 2011.0.00273.S_2012-09-07 uid://A002/X494155/X8be 2011.0.00273.S_2012-09-07 uid://A002/X45f1dd/Xd13 2011.0.00958.S_2012-09-10 uid://A002/X49990a/X1f 2011.0.00243.S_2012-09-12 uid://A002/X44f2b6/X201 2011.0.00243.S_2012-09-12 uid://A002/X45c06b/X78b 2011.0.00243.S_2012-09-12 uid://A002/X494155/X674 2011.0.00243.S_2012-09-18 uid://A002/X44f2b6/X4c 2011.0.00243.S_2012-09-18 uid://A002/X44c3c1/X85c 2011.0.00243.S_2012-09-18 uid://A002/X4320bd/Xc78 2011.0.00010.S_2012-09-20 uid://A002/X3c7a84/X866 2011.0.00010.S_2012-09-20 uid://A002/X3c7a84/X9de 2011.0.00539.S_2012-09-20 uid://A002/X41d520/Xb0b 2011.0.00319.S_2012-08-30 uid://A002/X435875/X204 2011.0.00319.S_2012-08-30 uid://A002/X435875/X9d 2011.0.00319.S_2012-08-30 uid://A002/X44ddb2/X238 2011.0.00319.S_2012-08-30 uid://A002/X44ddb2/Xdb 2011.0.00133.S_2012-07-31 uid://A002/X3dc0e7/X2b5 2011.0.00133.S_2012-07-31 uid://A002/X3ddbb0/X195 2011.0.00133.S_2012-07-31 uid://A002/X4210d0/X136 2011.0.00307.S_2012-09-27 uid://A002/X45f1dd/X1ce 2011.0.00887.S_2012-09-22 uid://A002/X40d164/X1b3 2011.0.00887.S_2012-09-22 uid://A002/X40d164/X32 2011.0.00887.S_2012-09-22 uid://A002/X40d164/X334 2011.0.00887.S_2012-09-22 uid://A002/X40d164/X4b5 2011.0.00727.S_2012-09-24 uid://A002/X4320bd/X19d 2011.0.00727.S_2012-09-24 uid://A002/X4320bd/X346 2011.0.00208.S_2012-09-03 uid://A002/X41d520/Xd2d 2011.0.00208.S_2012-09-03 uid://A002/X45e2af/X139 2011.0.00208.S_2012-09-03 uid://A002/X45e2af/X2b1 2011.0.00724.S_2012-10-01 uid://A002/X41f8d2/X50f 2011.0.00405.S_2012-06-29 uid://A002/X4122f3/X133 2011.0.00405.S_2012-06-29 uid://A002/X412638/X12d 2011.0.00405.S_2012-06-29 uid://A002/X412638/X9 2011.0.00405.S_2012-06-29 uid://A002/X41e287/X788 2011.0.00405.S_2012-06-29 uid://A002/X41e287/X8ac 2011.0.00652.S_2012-10-04 uid://A002/X3fdb4f/X463 2011.0.00652.S_2012-10-04 uid://A002/X47bd4d/X37c 2011.0.00142.S_2012-10-04 uid://A002/X4320bd/X77f 2011.0.00142.S_2012-10-04 uid://A002/X3e007f/X53b 2011.0.00142.S_2012-10-04 uid://A002/X3e007f/X9c2 2011.0.00142.S_2012-10-04 uid://A002/X3e17df/Xa88 2011.0.00099.S_2012-10-03 uid://A002/X44c3c1/Xafb 2011.0.00467.S_2012-09-12 uid://A002/X30a93d/X772 2011.0.00467.S_2012-09-12 uid://A002/X30a93d/Xa32 2011.0.00467.S_2012-09-12 uid://A002/X30a93d/X603 2011.0.00467.S_2012-09-12 uid://A002/X41c27b/X838 2011.0.00467.S_2012-09-12 uid://A002/X41d520/Xbf0 2011.0.00467.S_2012-09-12 uid://A002/X41b513/X24e 2011.0.00083.S_2012-09-19 uid://A002/X4320bd/Xf38 2011.0.00083.S_2012-09-19 uid://A002/X433c46/X96b 2011.0.00083.S_2012-09-19 uid://A002/X4b29af/X8b8 2011.0.00083.S_2012-09-19 uid://A002/X4b71b4/X25a 2011.0.00476.S_2012-06-20 uid://A002/X3fdb4f/X78c 2011.0.00476.S_2012-06-20 uid://A002/X47aefc/X109 2011.0.00724.S_2012-10-10 uid://A002/X46457e/X2ec 2011.0.00124.S_2012-10-10 uid://A002/X46457e/X979 2011.0.00124.S_2012-10-10 uid://A002/X46457e/Xadc 2011.0.00124.S_2012-10-10 uid://A002/X4785e0/X7e1 2011.0.00124.S_2012-10-10 uid://A002/X4785e0/X953 2011.0.00099.S_2012-10-11 uid://A002/X44f2b6/X398 2011.0.00099.S_2012-10-10 uid://A002/X47bd4d/X1e8 2011.0.00307.S_2012-10-03 uid://A002/X4b29af/X5fc 2011.0.00307.S_2012-10-03 uid://A002/X4b29af/X6ba 2011.0.00768.S_2012-10-10 uid://A002/X47d651/Xa81 2011.0.00768.S_2012-10-10 uid://A002/X49a70a/X782 2011.0.00768.S_2012-10-10 uid://A002/X49a70a/X9a7 2011.0.00645.S_2012-10-15 uid://A002/X3da7b0/X1a5 2011.0.00645.S_2012-10-15 uid://A002/X3da7b0/X6c 2011.0.00645.S_2012-10-15 uid://A002/X44c3c1/X9f2 2011.0.00397.S_2012-10-17 uid://A002/X4b6a0b/X12f 2011.0.00405.S_2012-10-18 uid://A002/X3ca066/Xa6f 2011.0.00405.S_2012-10-18 uid://A002/X3ca066/Xb94 2011.0.00405.S_2012-10-18 uid://A002/X4122f3/Xf 2011.0.00405.S_2012-10-18 uid://A002/X43036c/X5f1 2011.0.00747.S_2012-10-18 uid://A002/X4b58a4/X31 2011.0.00612.S_2012-11-07 uid://A002/X460fc9/X7a8 2011.0.00612.S_2012-11-07 uid://A002/X463144/X609 2011.0.00612.S_2012-11-07 uid://A002/X4b483b/X5c3 2011.0.00511.S_2012-10-18 uid://A002/X4b1170/X8bf 2011.0.00511.S_2012-10-19 uid://A002/X4ae797/X8e2 2011.0.00733.S_2012-10-17 uid://A002/X44ddb2/X3df 2011.0.00733.S_2012-10-17 uid://A002/X44a295/X5b8 2011.0.00733.S_2012-10-17 uid://A002/X435875/X4df 2011.0.00733.S_2012-10-17 uid://A002/X44c3c1/X460 2011.0.00733.S_2012-10-18 uid://A002/X433c46/X4d2 2011.0.00318.S_2012-10-18 uid://A002/X41c27b/X53 2011.0.00318.S_2012-10-18 uid://A002/X41ac1f/X4b0 2011.0.00318.S_2012-10-18 uid://A002/X496160/X60 2011.0.00318.S_2012-10-18 uid://A002/X47d651/X4ba 2011.0.00318.S_2012-10-18 uid://A002/X4785e0/X3cc 2011.0.00318.S_2012-10-18 uid://A002/X433c46/X348 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X18c 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X21d 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X2cd 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X36d 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X5c 2011.0.00754.S_2012-10-25 uid://A002/X41d520/Xf3 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X401 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X4a7 2011.0.00754.S_2012-10-25 uid://A002/X41d520/X541 2011.0.00182.S_2012-10-29 uid://A002/X40e374/Xba3 2011.0.00182.S_2012-10-29 uid://A002/X40e374/Xd36 2011.0.00182.S_2012-10-29 uid://A002/X40e374/Xec9 2011.0.00182.S_2012-10-29 uid://A002/X41065b/X334 2011.0.00182.S_2012-10-29 uid://A002/X41065b/X4c7 2011.0.00182.S_2012-10-29 uid://A002/X4afc39/X43b 2011.0.00039.S_2012-10-20 uid://A002/X47bd4d/Xbd4 2011.0.00039.S_2012-10-20 uid://A002/X47bd4d/Xd2c 2011.0.00039.S_2012-10-20 uid://A002/X47ed8e/X804 2011.0.00039.S_2012-10-20 uid://A002/X497d07/X538 2011.0.00039.S_2012-10-20 uid://A002/X49990a/X197 2011.0.00039.S_2012-10-20 uid://A002/X49a70a/X5c0 2011.0.00957.S_2012-03-12 uid://A002/X30cca6/X9b4 2011.0.00957.S_2012-03-12 uid://A002/X32041d/X1bb 2011.0.00957.S_2012-03-12 uid://A002/X32041d/X451 2011.0.00957.S_2012-03-12 uid://A002/X32041d/X589 2011.0.00957.S_2012-03-12 uid://A002/X32041d/X671 2011.0.00957.S_2012-03-12 uid://A002/X32041d/X759 2011.0.00957.S_2012-03-12 uid://A002/X321719/X1e8 2011.0.00957.S_2012-03-12 uid://A002/X321719/X2c1 2011.0.00957.S_2012-03-12 uid://A002/X321719/X424 2011.0.00957.S_2012-03-12 uid://A002/X321719/X4fd 2011.0.00957.S_2012-03-12 uid://A002/X321719/X600 2011.0.00957.S_2012-03-12 uid://A002/X321719/X723 2011.0.00957.S_2012-03-12 uid://A002/X321719/X826 2011.0.00957.S_2012-03-12 uid://A002/X321719/X929 2011.0.00957.S_2012-03-12 uid://A002/X321719/Xa2c 2011.0.00957.S_2012-03-12 uid://A002/X321719/Xb2f 2011.0.00957.S_2012-03-12 uid://A002/X321719/Xc32 2011.0.00957.S_2012-03-12 uid://A002/X321719/Xe5 2011.0.00957.S_2012-03-12 uid://A002/X369097/X316 2011.0.00957.S_2012-03-12 uid://A002/X36d011/X29b 2011.0.00957.S_2012-03-12 uid://A002/X36d011/X393 2011.0.00957.S_2012-03-12 uid://A002/X36e957/X316 2011.0.00957.S_2012-03-12 uid://A002/X36e957/X419 2011.0.00957.S_2012-03-12 uid://A002/X36e957/X501 2011.0.00957.S_2012-03-12 uid://A002/X3854ab/Xaa 2011.0.00808.S_2012-03-12 uid://A002/X368c03/X12 2011.0.00808.S_2012-03-12 uid://A002/X36ffba/X1f 2011.0.00808.S_2012-03-12 uid://A002/X37f559/X764 2011.0.00635.S_2012-10-05 uid://A002/X4210d0/X4e0 2011.0.00635.S_2012-10-05 uid://A002/X460fc9/X4ce 2011.0.00635.S_2012-10-05 uid://A002/X463144/X307 2011.0.00635.S_2012-10-05 uid://A002/X463144/X473 2011.0.00405.S_2012-10-05 uid://A002/X411025/X441 2011.0.00405.S_2012-10-05 uid://A002/X41e287/X9d0 2011.0.00405.S_2012-10-05 uid://A002/X43036c/X734 2011.0.00121.S_2012-11-02 uid://A002/X41ac1f/X3f8 2011.0.00121.S_2012-11-02 uid://A002/X41c27b/X9c5 2011.0.00121.S_2012-11-02 uid://A002/X41d520/X800 2011.0.00121.S_2012-11-02 uid://A002/X41e287/Xc94 2011.0.00121.S_2012-11-02 uid://A002/X4210d0/Xb31 2011.0.00902.S_2012-05-15 uid://A002/X3c9295/X2eb 2011.0.00307.S_2012-11-06 uid://A002/X31ab3d/X404 2011.0.00307.S_2012-11-06 uid://A002/X31ab3d/X555 2011.0.00307.S_2012-11-06 uid://A002/X4ae797/X465 2011.0.00525.S_2012-10-31 uid://A002/X47aefc/X18 2011.0.00525.S_2012-10-31 uid://A002/X3b3400/X395 2011.0.00083.S_2012-10-30 uid://A002/X460fc9/X8cc 2011.0.00083.S_2012-10-30 uid://A002/X463144/X7f5 2011.0.00083.S_2012-10-30 uid://A002/X463144/X922 2011.0.00083.S_2012-10-30 uid://A002/X4b71b4/X616 2011.0.00210.S_2012-11-05 uid://A002/X4b1170/Xa3a 2011.0.00273.S_2012-11-05 uid://A002/X4ae797/X776 2011.0.00273.S_2012-11-05 uid://A002/X45e2af/X458 2011.0.00208.S_2012-11-12 uid://A002/X51ac2a/X35f 2011.0.00208.S_2012-11-12 uid://A002/X51ac2a/X4dc 2011.0.00539.S_2012-11-11 uid://A002/X47bd4d/X98b 2011.0.00539.S_2012-11-11 uid://A002/X496ee3/X28f 2011.0.00121.S_2012-11-06 uid://A002/X41f8d2/Xbf5 2011.0.00121.S_2012-11-06 uid://A002/X4ae797/X5ca 2011.0.00656.S_2012-11-06 uid://A002/X496160/X2d4 2011.0.00656.S_2012-11-06 uid://A002/X4b1170/X447 2011.0.00210.S_2012-11-15 uid://A002/X4927e8/X455 2011.0.00210.S_2012-11-15 uid://A002/X4927e8/X634 2011.0.00511.S_2012-11-06 uid://A002/X4b29af/X818 2011.0.00097.S_2012-11-14 uid://A002/X52f1e2/X6cd 2011.0.00136.S_2012-11-06 uid://A002/X31ab3d/X257 2011.0.00136.S_2012-11-06 uid://A002/X31ceee/Xe8 2011.0.00136.S_2012-11-06 uid://A002/X32d5f1/X2f0 2011.0.00136.S_2012-11-06 uid://A002/X32f196/X170 2011.0.00259.S_2012-11-06 uid://A002/X4b29af/Xab7 2011.0.00017.S_2012-11-20 uid://A002/X44ddb2/X64a 2011.0.00017.S_2012-11-20 uid://A002/X47ed8e/X3cd 2011.0.00017.S_2012-11-20 uid://A002/X494155/X23a 2011.0.00017.S_2012-11-20 uid://A002/X4b29af/X403 2011.0.00396.S_2012-11-20 uid://A002/X497d07/X1b2 2011.0.00396.S_2012-11-20 uid://A002/X4afc39/X72 2011.0.00396.S_2012-11-20 uid://A002/X4afc39/X25f 2011.0.00097.S_2012-11-18 uid://A002/X517008/X438 2011.0.00223.S_2012-11-22 uid://A002/X518d2b/X71a 2011.0.00223.S_2012-11-22 uid://A002/X51ac2a/X62a 2011.0.00097.S_2012-11-19 uid://A002/X517008/X617 2011.0.00097.S_2012-11-20 uid://A002/X51ac2a/Xb0f 2011.0.00525.S_2012-10-03 uid://A002/X41f8d2/X4f 2011.0.00525.S_2012-10-03 uid://A002/X40f691/X4e6 2011.0.00108.S_2012-11-28 uid://A002/X47b743/X130 2011.0.00108.S_2012-11-28 uid://A002/X515b5c/X279 2011.0.00120.S_2012-11-21 uid://A002/X4ae797/X90 2011.0.00120.S_2012-11-21 uid://A002/X4b483b/X3c1 2011.0.00120.S_2012-11-21 uid://A002/X4b71b4/X1f 2011.0.00120.S_2012-11-21 uid://A002/X4ba082/X18a 2011.0.00716.S_2012-11-28 uid://A002/X518d2b/X4b7 2011.0.00199.S_2012-11-20 uid://A002/X460fc9/Xa91 2011.0.00199.S_2012-11-20 uid://A002/X4afc39/Xa3a 2011.0.00199.S_2012-11-20 uid://A002/X518d2b/Xb3a 2011.0.00648.S_2012-11-28 uid://A002/X4927e8/X2da 2011.0.00648.S_2012-11-28 uid://A002/X496ee3/X5 2011.0.00648.S_2012-11-28 uid://A002/X49be16/X9c 2011.0.00648.S_2012-11-28 uid://A002/X4b1170/X584 2011.0.00539.S_2012-12-03 uid://A002/X535168/Xa18 2011.0.00017.S_2012-12-03 uid://A002/X4210d0/X815 2011.0.00017.S_2012-12-03 uid://A002/X436934/X28 2011.0.00259.S_2012-12-04 uid://A002/X552607/X24d 2011.0.00656.S_2012-12-01 uid://A002/X496160/X410 2011.0.00656.S_2012-12-01 uid://A002/X49b5dd/X39d 2011.0.00340.S_2012-12-05 uid://A002/X554543/X207 2011.0.00340.S_2012-12-05 uid://A002/X554543/X3d0 2011.0.00340.S_2012-12-05 uid://A002/X554543/X667 2011.0.00150.S_2012-12-05 uid://A002/X54d35d/X664 2011.0.00175.S_2012-12-07 uid://A002/X411025/X53 2011.0.00175.S_2012-12-07 uid://A002/X3fdb4f/X5e4 2011.0.00175.S_2012-12-07 uid://A002/X3ddbb0/X6be 2011.0.00175.S_2012-12-07 uid://A002/X49b5dd/Xfd 2011.0.00150.S_2012-12-06 uid://A002/X54d35d/X567 2011.0.00820.S_2012-12-01 uid://A002/X4bb4dd/X5d 2011.0.00725.S_2012-12-09 uid://A002/X5552a3/X159 2011.0.00511.S_2012-12-10 uid://A002/X518d2b/X571 2011.0.00511.S_2012-12-10 uid://A002/X51ac2a/X851 2011.0.00017.S_2012-12-10 uid://A002/X41f8d2/X8e0 2011.0.00017.S_2012-12-10 uid://A002/X449249/Xde 2011.0.00017.S_2012-12-10 uid://A002/X44c3c1/X6cc 2011.0.00150.S_2012-12-12 uid://A002/X54face/X340 2011.0.00175.S_2012-12-17 uid://A002/X46457e/X71 2011.0.00259.S_2012-12-19 uid://A002/X554543/Xdd 2011.0.00259.S_2012-12-19 uid://A002/X5552a3/X695 2011.0.00182.S_2012-12-20 uid://A002/X49990a/X505 2011.0.00182.S_2012-12-20 uid://A002/X4b58a4/X1ee 2011.0.00223.S_2012-12-20 uid://A002/X532128/X39b 2011.0.00223.S_2012-12-20 uid://A002/X533e2c/X288 2011.0.00223.S_2012-12-20 uid://A002/X533e2c/X39a 2011.0.00223.S_2012-12-20 uid://A002/X533e2c/X9a 2011.0.00921.S_2012-12-17 uid://A002/X44a295/X62 2011.0.00921.S_2012-12-17 uid://A002/X4785e0/X61 2011.0.00921.S_2012-12-17 uid://A002/X532128/X610 2011.0.00820.S_2012-12-21 uid://A002/X5552a3/Xd88 2011.0.00820.S_2012-12-21 uid://A002/X5552a3/Xdfb 2011.0.00820.S_2012-12-21 uid://A002/X5578f1/X878 2011.0.00820.S_2012-12-21 uid://A002/X5578f1/X958 2011.0.00876.S_2012-12-28 uid://A002/X3dc0e7/X7ae 2011.0.00876.S_2012-12-28 uid://A002/X3dc0e7/X983 2011.0.00876.S_2012-12-28 uid://A002/X3ddbb0/X447 2011.0.00876.S_2012-12-28 uid://A002/X3f8662/X1e7 2011.0.00876.S_2012-12-28 uid://A002/X3fa880/X1cd 2011.0.00876.S_2012-12-28 uid://A002/X44875a/X2c4 2011.0.00876.S_2012-12-28 uid://A002/X44a295/X261 2011.0.00876.S_2012-12-28 uid://A002/X44c3c1/Xdf 2011.0.00876.S_2012-12-28 uid://A002/X537777/X7f5 2011.0.00876.S_2012-12-28 uid://A002/X53a723/X20d 2011.0.00028.S_2013-01-02 uid://A002/X51ee7e/X44 2011.0.00028.S_2013-01-02 uid://A002/X51ee7e/X1c2 2011.0.00028.S_2013-01-02 uid://A002/X51ee7e/X35f 2011.0.00028.S_2013-01-02 uid://A002/X51ee7e/X4dd 2011.0.00028.S_2013-01-02 uid://A002/X51ee7e/X67a 2011.0.00150.S_2012-12-19 uid://A002/X54face/X434 2011.0.00150.S_2012-12-19 uid://A002/X3df8fa/Xf6 2011.0.00150.S_2012-12-20 uid://A002/X54face/X528 2011.0.00061.S_2012-12-25 uid://A002/X494155/X4e9 2011.0.00061.S_2012-12-25 uid://A002/X496160/X56e 2011.0.00526.S_2012-01-04 uid://A002/X5784d5/X7ae 2011.0.00724.S_2013-01-02 uid://A002/X4b58a4/X373 2011.0.00724.S_2013-01-04 uid://A002/X49a70a/Xd6 2011.0.00733.S_2013-01-10 uid://A002/X47ed8e/X311 2011.0.00307.S_2012-12-19 uid://A002/X31bf7f/X7a 2011.0.00307.S_2012-12-19 uid://A002/X54d35d/Xb61 2011.0.00497.S_2012-12-20 uid://A002/X535168/Xd17 2011.0.00097.S_2012-11-15 uid://A002/X52f1e2/X7a9 2011.0.00097.S_2012-11-16 uid://A002/X532128/X56a 2011.0.00348.S_2013-01-09 uid://A002/X3f837d/Xbe 2011.0.00348.S_2013-01-09 uid://A002/X3f8662/Xa8 2011.0.00348.S_2013-01-09 uid://A002/X3fbe56/X211 2011.0.00348.S_2013-01-09 uid://A002/X3fbe56/X350 2011.0.00348.S_2013-01-09 uid://A002/X5552a3/Xbd6 2011.0.00348.S_2013-01-09 uid://A002/X5784d5/X32d 2011.0.00348.S_2013-01-09 uid://A002/X57b9e2/X22a 2011.0.00777.S_2012-12-01 uid://A002/X32d5f1/X18c 2011.0.00777.S_2012-12-01 uid://A002/X388522/X5c5 2011.0.00777.S_2012-12-01 uid://A002/X4bb4dd/X16d 2011.0.00604.S_2012-11-20 uid://A002/X494155/Xa21 2011.0.00604.S_2012-11-20 uid://A002/X4b1170/Xbaf 2011.0.00020.S_2012-10-03 uid://A002/X32d5f1/X570 2011.0.00020.S_2012-10-03 uid://A002/X331413/X60 2011.0.00020.S_2012-10-03 uid://A002/X36a70f/X1c7 2011.0.00020.S_2012-10-03 uid://A002/X36e957/X1b8 2011.0.00020.S_2012-10-03 uid://A002/X41b513/X121 2011.0.00020.S_2012-10-03 uid://A002/X41c27b/X4f5 2011.0.00020.S_2012-10-03 uid://A002/X47701c/X166 2011.0.00020.S_2012-10-03 uid://A002/X47701c/X29c 2011.0.00652.S_2013-01-15 uid://A002/X383b50/X1007 2011.0.00652.S_2013-01-15 uid://A002/X5784d5/X689 2011.0.00863.S_2013-01-15 uid://A002/X552607/X95a 2011.0.00863.S_2013-01-15 uid://A002/X552607/Xa39 2011.0.00820.S_2013-01-18 uid://A002/X590461/X1b94 2011.0.00820.S_2013-01-17 uid://A002/X590461/X17e6 2011.0.00628.S_2012-09-30 uid://A002/X3b55d6/Xbbc 2011.0.00628.S_2012-09-30 uid://A002/X3c9295/X663 2011.0.00628.S_2012-09-30 uid://A002/X3ca066/Xcb8 2011.0.00628.S_2012-09-30 uid://A002/X3cb0a0/Xd10 2011.0.00628.S_2012-09-30 uid://A002/X44875a/X499 2011.0.00229.S_2013-01-18 uid://A002/X40e374/X62 2011.0.00403.S_2013-01-23 uid://A002/X590461/X9db 2011.0.00403.S_2013-01-23 uid://A002/X590461/Xb0a 2011.0.00199.S_2013-01-23 uid://A002/X51d696/X64 2011.0.00319.S_2013-01-20 uid://A002/X45f1dd/X7a 2011.0.00319.S_2013-01-20 uid://A002/X479db5/X21e 2011.0.00319.S_2013-01-20 uid://A002/X494155/X40 2011.0.00319.S_2013-01-20 uid://A002/X590461/X19b4 2011.0.00497.S_2013-01-29 uid://A002/X533e2c/X648 2011.0.00497.S_2013-01-29 uid://A002/X533e2c/X785 2011.0.00059.S_2013-01-23 uid://A002/X49990a/X32a 2011.0.00020.S_2013-01-23 uid://A002/X32d5f1/X832 2011.0.00020.S_2013-01-23 uid://A002/X41ac1f/X21f 2011.0.00020.S_2013-01-23 uid://A002/X518d2b/X36e 2011.0.00020.S_2013-01-23 uid://A002/X535168/Xb6c 2011.0.00020.S_2013-01-23 uid://A002/X539bb9/X99 2011.0.00307.S_2012-09-27 uid://A002/X45c06b/X3c4 2011.0.00307.S_2012-04-17 uid://A002/X31bf7f/X2d7 2011.0.00307.S_2012-04-17 uid://A002/X31bf7f/X1f8 2011.0.00467.S_2012-05-10 uid://A002/X3b55d6/Xa0 2011.0.00733.S_2012-02-07 uid://A002/X47ed8e/X20b 2011.0.00087.S_2013-01-23 uid://A002/X54d35d/X868 2011.0.00087.S_2013-01-23 uid://A002/X54d35d/X9d4 2011.0.00273.S_2013-02-05 uid://A002/X4b29af/Xd21 2011.0.00273.S_2013-02-05 uid://A002/X4afc39/X8ce 2011.0.00273.S_2013-02-05 uid://A002/X535168/X796 2011.0.00206.S_2013-02-07 uid://A002/X518d2b/X170 2011.0.00206.S_2013-02-07 uid://A002/X3f6a86/X9cd 2011.0.00206.S_2013-02-07 uid://A002/X3ca066/Xe84 2011.0.00099.S_2013-02-08 uid://A002/X3cb0a0/X417 2011.0.00351.S_2013-01-23 uid://A002/X3c7a84/Xb56 2011.0.00351.S_2013-01-23 uid://A002/X45c06b/X49b 2011.0.00351.S_2013-01-23 uid://A002/X479db5/X586 2011.0.00351.S_2013-01-23 uid://A002/X47bd4d/X6a9 2011.0.00351.S_2013-01-23 uid://A002/X47d651/X5b1 2011.0.00747.S_2013-01-28 uid://A002/X41f8d2/X2ed 2011.0.00747.S_2013-01-28 uid://A002/X463144/Xda 2011.0.00747.S_2013-01-28 uid://A002/X58ec89/X25c 2011.0.00747.S_2013-01-28 uid://A002/X40e374/X53e 2011.0.00277.S_2012-02-07 uid://A002/X569422/X742 2011.0.00742.S_2013-02-08 uid://A002/X569422/X50d 2011.0.00779.S_2013-02-08 uid://A002/X513d18/X261 2011.0.00779.S_2013-02-08 uid://A002/X515b5c/X9b0 2011.0.00742.S_2013-02-11 uid://A002/X590461/X708 2011.0.00742.S_2013-02-11 uid://A002/X590461/X886 2011.0.00046.S_2013-02-11 uid://A002/X4bb4dd/X323 2011.0.00958.S_2012-09-11 uid://A002/X49a70a/X4d8 2011.0.00130.S_2013-02-11 uid://A002/X590461/X482 2011.0.00539.S_2013-02-15 uid://A002/X433c46/X7ab 2011.0.00526.S_2013-02-14 uid://A002/X2f0ad3/X71 2011.0.00131.S_2011-12-06 uid://A002/X2cbea7/X5ce 2011.0.00131.S_2011-12-06 uid://A002/X2cbea7/X733 2011.0.00131.S_2011-12-06 uid://A002/X2cd715/X7a 2011.0.00131.S_2011-12-06 uid://A002/X2ce37c/X12 2011.0.00131.S_2011-12-06 uid://A002/X2e7826/X3e6 2011.0.00131.S_2011-12-06 uid://A002/X2eaf7f/X167 2011.0.00191.S_2011-12-06 uid://A002/X2b8998/X192 2011.0.00191.S_2011-12-06 uid://A002/X2b8998/X2bf 2011.0.00191.S_2011-12-06 uid://A002/X2b8998/X65 2011.0.00191.S_2011-12-06 uid://A002/X2e7826/X576 2011.0.00191.S_2011-12-06 uid://A002/X2e7826/X6c8 2011.0.00191.S_2011-12-06 uid://A002/X2e7826/X7d4 2011.0.00397.S_2011-12-19 uid://A002/X31d189/X81d 2011.0.00397.S_2011-12-19 uid://A002/X31d189/X44e 2011.0.00510.S_2011-12-19 uid://A002/X3302c8/X436 2011.0.00020.S_2011-12-26 uid://A002/X31ab3d/X6a6 2011.0.00020.S_2011-12-26 uid://A002/X31ab3d/X7d3 2011.0.00236.S_2011-12-26 uid://A002/X2c75ca/X3ec 2011.0.00236.S_2011-12-26 uid://A002/X2c75ca/X5ec 2011.0.00236.S_2011-12-26 uid://A002/X2c75ca/X51c 2011.0.00236.S_2011-12-26 uid://A002/X30a93d/X6e 2011.0.00236.S_2011-12-26 uid://A002/X30a93d/X1b3 2011.0.00236.S_2011-12-26 uid://A002/X30a93d/X2f9 2011.0.00268.S_2012-02-02 uid://A002/X36a70f/X318 2011.0.00268.S_2012-02-02 uid://A002/X36d011/X4d5 2011.0.00268.S_2012-02-02 uid://A002/X36d011/X63b 2011.0.00958.S_2012-01-23 uid://A002/X31d189/X66a 2011.0.00958.S_2012-01-23 uid://A002/X3302c8/X17a 2011.0.00780.S_2012-01-23 uid://A002/X331413/X491 2011.0.00780.S_2012-01-23 uid://A002/X331413/X60f 2011.0.00780.S_2012-02-02 uid://A002/X35edea/X441 2011.0.00780.S_2012-02-02 uid://A002/X35edea/Xac 2011.0.00454.S_2012-02-08 uid://A002/X36a70f/Xc87 2011.0.00131.S_2012-01-23 uid://A002/X331413/X325 2011.0.00851.S_2012-02-08 uid://A002/X30cca6/X4a5 2011.0.00851.S_2012-02-08 uid://A002/X31ab3d/X121 2011.0.00851.S_2012-02-08 uid://A002/X31d189/X1ab 2011.0.00851.S_2012-02-08 uid://A002/X31d189/X2e1 2011.0.00851.S_2012-02-08 uid://A002/X31d189/X75 2011.0.00851.S_2012-02-08 uid://A002/X32041d/Xb5 2011.0.00851.S_2012-02-08 uid://A002/X32d5f1/X46a 2011.0.00474.S_2012-02-09 uid://A002/X2c1301/Xa2 2011.0.00474.S_2012-02-09 uid://A002/X2c54bd/X1cc 2011.0.00474.S_2012-02-09 uid://A002/X2c54bd/X3cb 2011.0.00474.S_2012-02-09 uid://A002/X2c54bd/X52b 2011.0.00474.S_2012-02-09 uid://A002/X2c54bd/X75 2011.0.00474.S_2012-02-09 uid://A002/X2c75ca/X20f 2011.0.00474.S_2012-02-09 uid://A002/X2c75ca/Xaf 2011.0.00474.S_2012-02-09 uid://A002/X3237b1/Xc9 2011.0.00294.S_2012-02-09 uid://A002/X2e7826/X95c 2011.0.00294.S_2012-02-09 uid://A002/X2e7826/Xbc4 2011.0.00294.S_2012-02-09 uid://A002/X2ec530/X9fe 2011.0.00294.S_2012-02-09 uid://A002/X2ec530/Xcc4 2011.0.00294.S_2012-02-09 uid://A002/X2ec530/Xf0b 2011.0.00294.S_2012-02-09 uid://A002/X2eea47/Xa3a 2011.0.00294.S_2012-02-09 uid://A002/X2eea47/Xcc9 2011.0.00294.S_2012-02-09 uid://A002/X305ca0/X8b 2011.0.00471.S_2012-02-24 uid://A002/X35edea/X228 2011.0.00471.S_2012-02-24 uid://A002/X35edea/X5ad 2011.0.00471.S_2012-02-24 uid://A002/X36a70f/X895 2011.0.00471.S_2012-02-24 uid://A002/X35edea/X77d 2011.0.00510.S_2012-02-24 uid://A002/X331413/X83f 2011.0.00510.S_2012-02-24 uid://A002/X35edea/X970 2011.0.00510.S_2012-02-24 uid://A002/X35edea/Xac4 2011.0.00131.S_2012-02-24 uid://A002/X38570d/X17b 2011.0.00131.S_2012-02-24 uid://A002/X383b50/X359 2011.0.00367.S_2012-03-12 uid://A002/X35abb2/X26f 2011.0.00367.S_2012-03-12 uid://A002/X35cca0/X3f5 2011.0.00367.S_2012-03-12 uid://A002/X369097/X584 2011.0.00367.S_2012-03-12 uid://A002/X369097/X780 2011.0.00367.S_2012-03-12 uid://A002/X369097/X9f0 2011.0.00367.S_2012-03-12 uid://A002/X369097/Xbfe 2011.0.00367.S_2012-03-12 uid://A002/X36bf6c/X2d0 2011.0.00367.S_2012-03-12 uid://A002/X36bf6c/X9e 2011.0.00367.S_2012-03-12 uid://A002/X36d011/X77d 2011.0.00367.S_2012-03-12 uid://A002/X36e957/X826 2011.0.00367.S_2012-03-12 uid://A002/X386355/X3ef 2011.0.00010.S_2012-04-13 uid://A002/X383b50/Xc45 2011.0.00307.S_2012-04-20 uid://A002/X36a70f/Xe0e 2011.0.00101.S_2011-12-06 uid://A002/X2f146f/X6f 2011.0.00101.S_2011-12-06 uid://A002/X30a93d/X43e 2011.0.00206.S_2012-05-14 uid://A002/X3b3400/X7df 2011.0.00206.S_2012-05-14 uid://A002/X3ca066/X93e 2011.0.00206.S_2012-05-14 uid://A002/X3daf0c/X1f8 2011.0.00206.S_2012-05-15 uid://A002/X3b55d6/X727 2011.0.00206.S_2012-05-15 uid://A002/X3e17df/X1cd 2011.0.00191.S_2012-05-15 uid://A002/X3dc0e7/Xf32 2011.0.00191.S_2012-05-15 uid://A002/X3dc0e7/Xdce 2011.0.00405.S_2012-05-15 uid://A002/X3cb0a0/Xb7d 2011.0.00405.S_2012-05-15 uid://A002/X3cb0a0/X9e8 2011.0.00958.S_2012-05-29 uid://A002/X3fa880/X8c2 2011.0.00471.S_2012-05-29 uid://A002/X3c7a84/X1fb 2011.0.00471.S_2012-05-29 uid://A002/X3c7a84/X31f 2011.0.00471.S_2012-05-29 uid://A002/X3c7a84/X443 2011.0.00020.S_2012-05-29 uid://A002/X331413/X1bc 2011.0.00020.S_2012-05-29 uid://A002/X36e957/X4f 2011.0.00020.S_2012-05-29 uid://A002/X383b50/X69 2011.0.00020.S_2012-05-29 uid://A002/X383b50/X1e1 2011.0.00374.S_2012-05-29 uid://A002/X3c7a84/X567 2011.0.00374.S_2012-05-29 uid://A002/X3b3400/X4e0 2011.0.00374.S_2012-05-29 uid://A002/X3b55d6/X4c6 2011.0.00374.S_2012-05-29 uid://A002/X3b55d6/X9ff 2011.0.00374.S_2012-05-29 uid://A002/X3b3400/X64c 2011.0.00374.S_2012-05-29 uid://A002/X3c7a84/X6d3 2011.0.00374.S_2012-05-29 uid://A002/X3b55d6/X875 2011.0.00374.S_2012-05-29 uid://A002/X3e17df/X3fd 2011.0.00064.S_2013-02-19 uid://A002/X55186e/X64 2011.0.00232.S_2013-02-16 uid://A002/X5578f1/X4f 2011.0.00232.S_2013-02-16 uid://A002/X56a957/X64 2011.0.00170.S_2013-02-19 uid://A002/X5578f1/X42a 2011.0.00170.S_2013-02-19 uid://A002/X5578f1/X5b4 2011.0.00429.S_2013-02-11 uid://A002/X54d35d/X64 2011.0.00526.S_2013-02-14 uid://A002/X4ae797/X247 2011.0.00526.S_2013-02-14 uid://A002/X2f0ad3/X279 2011.0.00539.S_2013-02-15 uid://A002/X436934/X2f9 2011.0.00539.S_2013-02-15 uid://A002/X449249/X3ce 2011.0.00539.S_2013-02-15 uid://A002/X44a295/Xaf5 2011.0.00539.S_2013-02-15 uid://A002/X590461/X5f 2011.0.00539.S_2013-02-15 uid://A002/X590461/X288 2011.0.00064.S_2013-02-19 uid://A002/X552607/X607 2011.0.00115.S_2013-02-19 uid://A002/X45f1dd/X9a2 2011.0.00115.S_2013-02-19 uid://A002/X45f1dd/Xb62 2011.0.00115.S_2013-02-19 uid://A002/X46457e/X6cd 2011.0.00115.S_2013-02-19 uid://A002/X479db5/X77f 2011.0.00115.S_2013-02-19 uid://A002/X479db5/X890 2011.0.00115.S_2013-02-19 uid://A002/X47d651/X7cd 2011.0.00397.S_2012-07-05 uid://A002/X411025/X1fb 2011.0.00397.S_2012-07-05 uid://A002/X411025/X301 2011.0.00548.S_2013-02-19 uid://A002/X56a957/X63a 2011.0.00465.S_2013-02-11 uid://A002/X41e287/X2f0 2011.0.00465.S_2013-02-11 uid://A002/X41d520/X5f7 2011.0.00259.S_2012-12-04 uid://A002/X3e33cb/X2fd 2011.0.00470.S_2013-02-26 uid://A002/X5784d5/X4f9 2011.0.00470.S_2013-02-26 uid://A002/X36a70f/Xab6 2011.0.00470.S_2013-02-26 uid://A002/X590461/X1853 2011.0.00820.S_2013-02-27 uid://A002/X5578f1/X8e8 2011.0.00497.S_2013-02-15 uid://A002/X533e2c/X53c 2011.0.00172.S_2013-02-11 uid://A002/X36a70f/X63 2011.0.00172.S_2013-02-11 uid://A002/X38570d/X10 2011.0.00172.S_2013-02-11 uid://A002/X35cca0/X27e 2011.0.00172.S_2013-02-11 uid://A002/X369097/X85 2011.0.00084.S_2013-02-28 uid://A002/X49a70a/X2de 2011.0.00084.S_2013-02-28 uid://A002/X2eea47/X1e0 2011.0.00820.S_2012-06-12 uid://A002/X3e3a61/X28d 2011.0.00820.S_2012-06-12 uid://A002/X3e3a61/Xce 2011.0.00958.S_2012-09-12 uid://A002/X41e287/Xb16 2011.0.00604.S_2013-02-11 uid://A002/X4b71b4/X459 2011.0.00604.S_2013-02-11 uid://A002/X515b5c/X459 2011.0.00619.S_2013-02-26 uid://A002/X552607/X4b 2011.0.00467.S_2012-06-28 uid://A002/X3f6a86/Xd65 2011.0.00099.S_2012-08-23 uid://A002/X3f6a86/X7fb 2011.0.00099.S_2012-08-24 uid://A002/X3f6a86/X7fb astroquery-0.2.4/astroquery/alma/setup_package.py0000644000077000000240000000034112464716555022306 0ustar adamstaff00000000000000# Licensed under a 3-clause BSD style license - see LICENSE.rst import os def get_package_data(): paths = [os.path.join('data', 'cycle0_delivery_asdm_mapping.txt'), ] return {'astroquery.alma': paths} astroquery-0.2.4/astroquery/alma/tests/0000755000077000000240000000000012505171566020256 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alma/tests/__init__.py0000644000077000000240000000000012464716555022364 0ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alma/tests/data/0000755000077000000240000000000012505171566021167 5ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alma/tests/data/data_list_page.html0000644000077000000240000002716312464716555025035 0ustar adamstaff00000000000000 Alma Request Handler - Request Details astroquery-0.2.4/astroquery/alma/tests/data/downloadRequest519752156script.sh0000644000077000000240000000064212475031770027061 0ustar adamstaff00000000000000#!/bin/bash #Please use the current script to download the whole content of request 519752156 wget "https://almascience.eso.org/dataPortal/requests/anonymous/519752156/ALMA/2011.0.00121.S_2012-07-30_001_of_002.tar/2011.0.00121.S_2012-07-30_001_of_002.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/519752156/ALMA/2011.0.00121.S_2012-07-30_002_of_002.tar/2011.0.00121.S_2012-07-30_002_of_002.tar" astroquery-0.2.4/astroquery/alma/tests/data/downloadRequest786572566script.sh0000644000077000000240000000057012475031770027074 0ustar adamstaff00000000000000#!/bin/bash #Please use the current script to download the whole content of request 786572566 wget "https://almascience.eso.org/dataPortal/requests/anonymous/786572566/ALMA/uid___A002_X3b3400_X90f/uid___A002_X3b3400_X90f.asdm.sdm.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786572566/ALMA/uid___A002_X3b3400_Xaf3/uid___A002_X3b3400_Xaf3.asdm.sdm.tar" astroquery-0.2.4/astroquery/alma/tests/data/downloadRequest786978956script.sh0000644000077000000240000001032212475031770027105 0ustar adamstaff00000000000000#!/bin/bash #Please use the current script to download the whole content of request 786978956 wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_006_of_011.tar/2011.0.00772.S_2012-12-01_006_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_011_of_015.tar/2011.0.00772.S_2012-09-12_011_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_010_of_015.tar/2011.0.00772.S_2012-09-12_010_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_008_of_015.tar/2011.0.00772.S_2012-09-12_008_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_002_of_015.tar/2011.0.00772.S_2012-09-12_002_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_007_of_011.tar/2011.0.00772.S_2012-12-01_007_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_007_of_015.tar/2011.0.00772.S_2012-09-12_007_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_013_of_015.tar/2011.0.00772.S_2012-09-12_013_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_008_of_011.tar/2011.0.00772.S_2012-12-01_008_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_010_of_011.tar/2011.0.00772.S_2012-12-01_010_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_014_of_015.tar/2011.0.00772.S_2012-09-12_014_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_003_of_015.tar/2011.0.00772.S_2012-09-12_003_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_006_of_015.tar/2011.0.00772.S_2012-09-12_006_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_012_of_015.tar/2011.0.00772.S_2012-09-12_012_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_015_of_015.tar/2011.0.00772.S_2012-09-12_015_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_001_of_011.tar/2011.0.00772.S_2012-12-01_001_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_005_of_011.tar/2011.0.00772.S_2012-12-01_005_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_001_of_015.tar/2011.0.00772.S_2012-09-12_001_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_004_of_015.tar/2011.0.00772.S_2012-09-12_004_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_011_of_011.tar/2011.0.00772.S_2012-12-01_011_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_002_of_011.tar/2011.0.00772.S_2012-12-01_002_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_005_of_015.tar/2011.0.00772.S_2012-09-12_005_of_015.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_009_of_011.tar/2011.0.00772.S_2012-12-01_009_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_004_of_011.tar/2011.0.00772.S_2012-12-01_004_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-12-01_003_of_011.tar/2011.0.00772.S_2012-12-01_003_of_011.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/786978956/ALMA/2011.0.00772.S_2012-09-12_009_of_015.tar/2011.0.00772.S_2012-09-12_009_of_015.tar" astroquery-0.2.4/astroquery/alma/tests/data/downloadRequest787632764script.sh0000644000077000000240000000517612475031770027101 0ustar adamstaff00000000000000#!/bin/bash #Please use the current script to download the whole content of request 787632764 wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-06_003_of_004.tar/2011.0.00121.S_2012-11-06_003_of_004.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_001_of_008.tar/2011.0.00121.S_2012-11-02_001_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-08-16_001_of_002.tar/2011.0.00121.S_2012-08-16_001_of_002.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_007_of_008.tar/2011.0.00121.S_2012-11-02_007_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-08-16_002_of_002.tar/2011.0.00121.S_2012-08-16_002_of_002.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_008_of_008.tar/2011.0.00121.S_2012-11-02_008_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-06_004_of_004.tar/2011.0.00121.S_2012-11-06_004_of_004.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_004_of_008.tar/2011.0.00121.S_2012-11-02_004_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_006_of_008.tar/2011.0.00121.S_2012-11-02_006_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-07-30_001_of_002.tar/2011.0.00121.S_2012-07-30_001_of_002.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_002_of_008.tar/2011.0.00121.S_2012-11-02_002_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_005_of_008.tar/2011.0.00121.S_2012-11-02_005_of_008.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-07-30_002_of_002.tar/2011.0.00121.S_2012-07-30_002_of_002.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-06_001_of_004.tar/2011.0.00121.S_2012-11-06_001_of_004.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-06_002_of_004.tar/2011.0.00121.S_2012-11-06_002_of_004.tar" wget "https://almascience.eso.org/dataPortal/requests/anonymous/787632764/ALMA/2011.0.00121.S_2012-11-02_003_of_008.tar/2011.0.00121.S_2012-11-02_003_of_008.tar" astroquery-0.2.4/astroquery/alma/tests/data/empty.html0000644000077000000240000000000012464716555023210 0ustar adamstaff00000000000000astroquery-0.2.4/astroquery/alma/tests/data/initial_response.html0000644000077000000240000000530712464716555025440 0ustar adamstaff00000000000000 Alma Request Handler - Logout


    Your request is being handled

    In a few seconds you will be redirected to the confirmation page.

    Please wait.....

    Request #519752156 by Anonymous User COMPLETE

    ALMA
    Include raw

    Requested Projects / OUSets / Executionblocks

    UNIX/Linux Shell script if you prefer command line download of complete request: downloadRequest519752156script.sh
    Data entities 1-1 of 1
    Select Project / OUSet / Executionblock File Size Access
    Data entities 1-1 of 1 4.9GB