SILENT KILLERPanel

Current Path: > > opt > cloudlinux > venv > lib64 > python3.11 > > > site-packages >


Operation   : Linux premium131.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64
Software     : Apache
Server IP    : 162.0.232.56 | Your IP: 216.73.216.111
Domains      : 1034 Domain(s)
Permission   : [ 0755 ]

Files and Folders in: //opt/cloudlinux/venv/lib64/python3.11///site-packages/

NameTypeSizeLast ModifiedActions
GitPython-3.1.32.dist-info Directory - -
Jinja2-3.0.3.dist-info Directory - -
Mako-1.2.4.dist-info Directory - -
MarkupSafe-2.1.3.dist-info Directory - -
PyJWT-2.8.0.dist-info Directory - -
PyMySQL-1.1.0.dist-info Directory - -
PyVirtualDisplay-3.0.dist-info Directory - -
PyYAML-6.0.1.dist-info Directory - -
__pycache__ Directory - -
_distutils_hack Directory - -
_pytest Directory - -
_yaml Directory - -
aiohttp Directory - -
aiohttp-3.9.2.dist-info Directory - -
aiohttp_jinja2 Directory - -
aiohttp_jinja2-1.5.dist-info Directory - -
aiohttp_security Directory - -
aiohttp_security-0.4.0.dist-info Directory - -
aiohttp_session Directory - -
aiohttp_session-2.9.0.dist-info Directory - -
aiosignal Directory - -
aiosignal-1.3.1.dist-info Directory - -
alembic Directory - -
alembic-1.11.1.dist-info Directory - -
annotated_types Directory - -
annotated_types-0.6.0.dist-info Directory - -
astroid Directory - -
astroid-2.15.6.dist-info Directory - -
attr Directory - -
attrs Directory - -
attrs-23.1.0.dist-info Directory - -
backports Directory - -
certifi Directory - -
certifi-2023.7.22.dist-info Directory - -
cffi Directory - -
cffi-1.15.1.dist-info Directory - -
chardet Directory - -
chardet-5.2.0.dist-info Directory - -
charset_normalizer Directory - -
charset_normalizer-2.1.1.dist-info Directory - -
cl_dom_collector Directory - -
clcagefslib Directory - -
clcommon Directory - -
clconfig Directory - -
clconfigure Directory - -
cldashboard Directory - -
clevents Directory - -
clflags Directory - -
cllicense Directory - -
cllimits Directory - -
cllimits_validator Directory - -
cllimitslib_v2 Directory - -
cllvectl Directory - -
clpackages Directory - -
clquota Directory - -
clselect Directory - -
clselector Directory - -
clsentry Directory - -
clsummary Directory - -
clveconfig Directory - -
clwizard Directory - -
configparser-5.0.2.dist-info Directory - -
contextlib2 Directory - -
contextlib2-21.6.0.dist-info Directory - -
coverage Directory - -
coverage-7.2.7.dist-info Directory - -
cryptography Directory - -
cryptography-41.0.2.dist-info Directory - -
ddt-1.4.4.dist-info Directory - -
dill Directory - -
dill-0.3.7.dist-info Directory - -
distlib Directory - -
distlib-0.3.8.dist-info Directory - -
docopt-0.6.2.dist-info Directory - -
dodgy Directory - -
dodgy-0.2.1.dist-info Directory - -
filelock Directory - -
filelock-3.13.1.dist-info Directory - -
flake8 Directory - -
flake8-5.0.4.dist-info Directory - -
flake8_polyfill Directory - -
flake8_polyfill-1.0.2.dist-info Directory - -
frozenlist Directory - -
frozenlist-1.4.0.dist-info Directory - -
future Directory - -
future-0.18.3.dist-info Directory - -
git Directory - -
gitdb Directory - -
gitdb-4.0.10.dist-info Directory - -
guppy Directory - -
guppy3-3.1.3.dist-info Directory - -
hc_json_rpc_client Directory - -
hc_json_rpc_client-1.0.1.dist-info Directory - -
idna Directory - -
idna-3.4.dist-info Directory - -
iniconfig Directory - -
iniconfig-2.0.0.dist-info Directory - -
isort Directory - -
isort-5.12.0.dist-info Directory - -
jinja2 Directory - -
jsonschema Directory - -
jsonschema-3.2.0.dist-info Directory - -
jwt Directory - -
lazy_object_proxy Directory - -
lazy_object_proxy-1.9.0.dist-info Directory - -
libfuturize Directory - -
libpasteurize Directory - -
lve_stats-2.0.dist-info Directory - -
lve_utils Directory - -
lvemanager Directory - -
lvestats Directory - -
lxml Directory - -
lxml-4.9.2.dist-info Directory - -
mako Directory - -
markupsafe Directory - -
mccabe-0.7.0.dist-info Directory - -
mock Directory - -
mock-5.1.0.dist-info Directory - -
multidict Directory - -
multidict-6.0.4.dist-info Directory - -
numpy Directory - -
numpy-1.25.1.dist-info Directory - -
numpy.libs Directory - -
packaging Directory - -
packaging-23.1.dist-info Directory - -
past Directory - -
pep8_naming-0.10.0.dist-info Directory - -
pip Directory - -
pip-25.0.1.dist-info Directory - -
pkg_resources Directory - -
platformdirs Directory - -
platformdirs-3.11.0.dist-info Directory - -
pluggy Directory - -
pluggy-1.2.0.dist-info Directory - -
prettytable Directory - -
prettytable-3.8.0.dist-info Directory - -
prometheus_client Directory - -
prometheus_client-0.8.0.dist-info Directory - -
prospector Directory - -
prospector-1.10.2.dist-info Directory - -
psutil Directory - -
psutil-5.9.5.dist-info Directory - -
psycopg2 Directory - -
psycopg2_binary-2.9.6.dist-info Directory - -
psycopg2_binary.libs Directory - -
pycodestyle-2.9.1.dist-info Directory - -
pycparser Directory - -
pycparser-2.21.dist-info Directory - -
pydantic Directory - -
pydantic-2.4.2.dist-info Directory - -
pydantic_core Directory - -
pydantic_core-2.10.1.dist-info Directory - -
pydocstyle Directory - -
pydocstyle-6.3.0.dist-info Directory - -
pyfakefs Directory - -
pyfakefs-5.2.3.dist-info Directory - -
pyflakes Directory - -
pyflakes-2.5.0.dist-info Directory - -
pylint Directory - -
pylint-2.17.4.dist-info Directory - -
pylint_celery Directory - -
pylint_celery-0.3.dist-info Directory - -
pylint_django Directory - -
pylint_django-2.5.3.dist-info Directory - -
pylint_flask Directory - -
pylint_flask-0.6.dist-info Directory - -
pylint_plugin_utils Directory - -
pylint_plugin_utils-0.7.dist-info Directory - -
pylve-2.1-py3.11.egg-info Directory - -
pymysql Directory - -
pyparsing Directory - -
pyparsing-3.0.9.dist-info Directory - -
pyrsistent Directory - -
pyrsistent-0.19.3.dist-info Directory - -
pytest Directory - -
pytest-7.4.0.dist-info Directory - -
pytest_check Directory - -
pytest_check-2.5.3.dist-info Directory - -
pytest_snapshot Directory - -
pytest_snapshot-0.9.0.dist-info Directory - -
pytest_subprocess Directory - -
pytest_subprocess-1.5.0.dist-info Directory - -
pytest_tap Directory - -
pytest_tap-3.5.dist-info Directory - -
python_pam-1.8.4.dist-info Directory - -
pyvirtualdisplay Directory - -
raven Directory - -
raven-6.10.0.dist-info Directory - -
requests Directory - -
requests-2.31.0.dist-info Directory - -
requirements_detector Directory - -
requirements_detector-1.2.2.dist-info Directory - -
schema-0.7.5.dist-info Directory - -
semver Directory - -
semver-3.0.1.dist-info Directory - -
sentry_sdk Directory - -
sentry_sdk-1.29.2.dist-info Directory - -
setoptconf Directory - -
setoptconf_tmp-0.3.1.dist-info Directory - -
setuptools Directory - -
setuptools-78.1.0.dist-info Directory - -
simplejson Directory - -
simplejson-3.19.1.dist-info Directory - -
six-1.16.0.dist-info Directory - -
smmap Directory - -
smmap-5.0.0.dist-info Directory - -
snowballstemmer Directory - -
snowballstemmer-2.2.0.dist-info Directory - -
sqlalchemy Directory - -
sqlalchemy-1.3.24.dist-info Directory - -
ssa Directory - -
svgwrite Directory - -
svgwrite-1.4.3.dist-info Directory - -
tap Directory - -
tap_py-3.2.1.dist-info Directory - -
testfixtures Directory - -
testfixtures-7.1.0.dist-info Directory - -
toml Directory - -
toml-0.10.2.dist-info Directory - -
tomlkit Directory - -
tomlkit-0.11.8.dist-info Directory - -
typing_extensions-4.8.0.dist-info Directory - -
unshare-0.22.dist-info Directory - -
urllib3 Directory - -
urllib3-2.0.4.dist-info Directory - -
vendors_api Directory - -
virtualenv Directory - -
virtualenv-20.21.1.dist-info Directory - -
wcwidth Directory - -
wcwidth-0.2.6.dist-info Directory - -
wmt Directory - -
wrapt Directory - -
wrapt-1.15.0.dist-info Directory - -
yaml Directory - -
yarl Directory - -
yarl-1.9.2.dist-info Directory - -
_cffi_backend.cpython-311-x86_64-linux-gnu.so File 274048 bytes April 17 2025 13:11:30.
_pyrsistent_version.py File 23 bytes April 17 2025 13:10:58.
cl_proc_hidepid.py File 4638 bytes June 05 2025 09:53:15.
clcontrollib.py File 52970 bytes June 05 2025 09:53:15.
cldetectlib.py File 18565 bytes June 05 2025 09:53:15.
cldiaglib.py File 46943 bytes June 05 2025 09:53:15.
clhooklib.py File 1296 bytes July 11 2025 17:46:23.
cli_utils.py File 1698 bytes June 05 2025 09:53:15.
cllicenselib.py File 9322 bytes June 05 2025 09:53:15.
clsetuplib.py File 4452 bytes June 05 2025 09:53:15.
clsudo.py File 14761 bytes June 23 2025 12:47:48.
configparser.py File 1546 bytes April 17 2025 13:10:58.
ddt.py File 12733 bytes April 17 2025 13:10:58.
distutils-precedence.pth File 151 bytes April 17 2025 13:10:58.
docopt.py File 19946 bytes April 17 2025 13:10:58.
hc_lve_profiler.py File 6353 bytes May 22 2025 11:14:48.
lveapi.py File 19994 bytes June 05 2025 09:53:15.
lvectllib.py File 105010 bytes June 05 2025 09:53:15.
lvestat.py File 6997 bytes June 23 2025 12:47:48.
mccabe.py File 10654 bytes April 17 2025 13:10:58.
pam.py File 7556 bytes April 17 2025 13:10:58.
pep8ext_naming.py File 19052 bytes April 17 2025 13:10:58.
py.py File 263 bytes April 17 2025 13:10:58.
pycodestyle.py File 103501 bytes April 17 2025 13:10:58.
pylve.cpython-311-x86_64-linux-gnu.so File 26088 bytes March 18 2025 16:24:34.
remove_ubc.py File 5864 bytes June 05 2025 09:53:15.
schema.py File 30221 bytes April 17 2025 13:10:58.
secureio.py File 19278 bytes June 23 2025 12:47:48.
simple_rpm.so File 11560 bytes June 23 2025 12:23:46.
six.py File 34549 bytes April 17 2025 13:10:58.
typing_extensions.py File 103397 bytes June 07 2025 10:31:54.
unshare.cpython-311-x86_64-linux-gnu.so File 8368 bytes April 17 2025 13:11:30.

Reading File: //opt/cloudlinux/venv/lib64/python3.11///site-packages//docopt.py

"""Pythonic command-line interface parser that will make you smile.

 * http://docopt.org
 * Repository and issue-tracker: https://github.com/docopt/docopt
 * Licensed under terms of MIT license (see LICENSE-MIT)
 * Copyright (c) 2013 Vladimir Keleshev, vladimir@keleshev.com

"""
import sys
import re


__all__ = ['docopt']
__version__ = '0.6.2'


class DocoptLanguageError(Exception):

    """Error in construction of usage-message by developer."""


class DocoptExit(SystemExit):

    """Exit in case user invoked program with incorrect arguments."""

    usage = ''

    def __init__(self, message=''):
        SystemExit.__init__(self, (message + '\n' + self.usage).strip())


class Pattern(object):

    def __eq__(self, other):
        return repr(self) == repr(other)

    def __hash__(self):
        return hash(repr(self))

    def fix(self):
        self.fix_identities()
        self.fix_repeating_arguments()
        return self

    def fix_identities(self, uniq=None):
        """Make pattern-tree tips point to same object if they are equal."""
        if not hasattr(self, 'children'):
            return self
        uniq = list(set(self.flat())) if uniq is None else uniq
        for i, c in enumerate(self.children):
            if not hasattr(c, 'children'):
                assert c in uniq
                self.children[i] = uniq[uniq.index(c)]
            else:
                c.fix_identities(uniq)

    def fix_repeating_arguments(self):
        """Fix elements that should accumulate/increment values."""
        either = [list(c.children) for c in self.either.children]
        for case in either:
            for e in [c for c in case if case.count(c) > 1]:
                if type(e) is Argument or type(e) is Option and e.argcount:
                    if e.value is None:
                        e.value = []
                    elif type(e.value) is not list:
                        e.value = e.value.split()
                if type(e) is Command or type(e) is Option and e.argcount == 0:
                    e.value = 0
        return self

    @property
    def either(self):
        """Transform pattern into an equivalent, with only top-level Either."""
        # Currently the pattern will not be equivalent, but more "narrow",
        # although good enough to reason about list arguments.
        ret = []
        groups = [[self]]
        while groups:
            children = groups.pop(0)
            types = [type(c) for c in children]
            if Either in types:
                either = [c for c in children if type(c) is Either][0]
                children.pop(children.index(either))
                for c in either.children:
                    groups.append([c] + children)
            elif Required in types:
                required = [c for c in children if type(c) is Required][0]
                children.pop(children.index(required))
                groups.append(list(required.children) + children)
            elif Optional in types:
                optional = [c for c in children if type(c) is Optional][0]
                children.pop(children.index(optional))
                groups.append(list(optional.children) + children)
            elif AnyOptions in types:
                optional = [c for c in children if type(c) is AnyOptions][0]
                children.pop(children.index(optional))
                groups.append(list(optional.children) + children)
            elif OneOrMore in types:
                oneormore = [c for c in children if type(c) is OneOrMore][0]
                children.pop(children.index(oneormore))
                groups.append(list(oneormore.children) * 2 + children)
            else:
                ret.append(children)
        return Either(*[Required(*e) for e in ret])


class ChildPattern(Pattern):

    def __init__(self, name, value=None):
        self.name = name
        self.value = value

    def __repr__(self):
        return '%s(%r, %r)' % (self.__class__.__name__, self.name, self.value)

    def flat(self, *types):
        return [self] if not types or type(self) in types else []

    def match(self, left, collected=None):
        collected = [] if collected is None else collected
        pos, match = self.single_match(left)
        if match is None:
            return False, left, collected
        left_ = left[:pos] + left[pos + 1:]
        same_name = [a for a in collected if a.name == self.name]
        if type(self.value) in (int, list):
            if type(self.value) is int:
                increment = 1
            else:
                increment = ([match.value] if type(match.value) is str
                             else match.value)
            if not same_name:
                match.value = increment
                return True, left_, collected + [match]
            same_name[0].value += increment
            return True, left_, collected
        return True, left_, collected + [match]


class ParentPattern(Pattern):

    def __init__(self, *children):
        self.children = list(children)

    def __repr__(self):
        return '%s(%s)' % (self.__class__.__name__,
                           ', '.join(repr(a) for a in self.children))

    def flat(self, *types):
        if type(self) in types:
            return [self]
        return sum([c.flat(*types) for c in self.children], [])


class Argument(ChildPattern):

    def single_match(self, left):
        for n, p in enumerate(left):
            if type(p) is Argument:
                return n, Argument(self.name, p.value)
        return None, None

    @classmethod
    def parse(class_, source):
        name = re.findall('(<\S*?>)', source)[0]
        value = re.findall('\[default: (.*)\]', source, flags=re.I)
        return class_(name, value[0] if value else None)


class Command(Argument):

    def __init__(self, name, value=False):
        self.name = name
        self.value = value

    def single_match(self, left):
        for n, p in enumerate(left):
            if type(p) is Argument:
                if p.value == self.name:
                    return n, Command(self.name, True)
                else:
                    break
        return None, None


class Option(ChildPattern):

    def __init__(self, short=None, long=None, argcount=0, value=False):
        assert argcount in (0, 1)
        self.short, self.long = short, long
        self.argcount, self.value = argcount, value
        self.value = None if value is False and argcount else value

    @classmethod
    def parse(class_, option_description):
        short, long, argcount, value = None, None, 0, False
        options, _, description = option_description.strip().partition('  ')
        options = options.replace(',', ' ').replace('=', ' ')
        for s in options.split():
            if s.startswith('--'):
                long = s
            elif s.startswith('-'):
                short = s
            else:
                argcount = 1
        if argcount:
            matched = re.findall('\[default: (.*)\]', description, flags=re.I)
            value = matched[0] if matched else None
        return class_(short, long, argcount, value)

    def single_match(self, left):
        for n, p in enumerate(left):
            if self.name == p.name:
                return n, p
        return None, None

    @property
    def name(self):
        return self.long or self.short

    def __repr__(self):
        return 'Option(%r, %r, %r, %r)' % (self.short, self.long,
                                           self.argcount, self.value)


class Required(ParentPattern):

    def match(self, left, collected=None):
        collected = [] if collected is None else collected
        l = left
        c = collected
        for p in self.children:
            matched, l, c = p.match(l, c)
            if not matched:
                return False, left, collected
        return True, l, c


class Optional(ParentPattern):

    def match(self, left, collected=None):
        collected = [] if collected is None else collected
        for p in self.children:
            m, left, collected = p.match(left, collected)
        return True, left, collected


class AnyOptions(Optional):

    """Marker/placeholder for [options] shortcut."""


class OneOrMore(ParentPattern):

    def match(self, left, collected=None):
        assert len(self.children) == 1
        collected = [] if collected is None else collected
        l = left
        c = collected
        l_ = None
        matched = True
        times = 0
        while matched:
            # could it be that something didn't match but changed l or c?
            matched, l, c = self.children[0].match(l, c)
            times += 1 if matched else 0
            if l_ == l:
                break
            l_ = l
        if times >= 1:
            return True, l, c
        return False, left, collected


class Either(ParentPattern):

    def match(self, left, collected=None):
        collected = [] if collected is None else collected
        outcomes = []
        for p in self.children:
            matched, _, _ = outcome = p.match(left, collected)
            if matched:
                outcomes.append(outcome)
        if outcomes:
            return min(outcomes, key=lambda outcome: len(outcome[1]))
        return False, left, collected


class TokenStream(list):

    def __init__(self, source, error):
        self += source.split() if hasattr(source, 'split') else source
        self.error = error

    def move(self):
        return self.pop(0) if len(self) else None

    def current(self):
        return self[0] if len(self) else None


def parse_long(tokens, options):
    """long ::= '--' chars [ ( ' ' | '=' ) chars ] ;"""
    long, eq, value = tokens.move().partition('=')
    assert long.startswith('--')
    value = None if eq == value == '' else value
    similar = [o for o in options if o.long == long]
    if tokens.error is DocoptExit and similar == []:  # if no exact match
        similar = [o for o in options if o.long and o.long.startswith(long)]
    if len(similar) > 1:  # might be simply specified ambiguously 2+ times?
        raise tokens.error('%s is not a unique prefix: %s?' %
                           (long, ', '.join(o.long for o in similar)))
    elif len(similar) < 1:
        argcount = 1 if eq == '=' else 0
        o = Option(None, long, argcount)
        options.append(o)
        if tokens.error is DocoptExit:
            o = Option(None, long, argcount, value if argcount else True)
    else:
        o = Option(similar[0].short, similar[0].long,
                   similar[0].argcount, similar[0].value)
        if o.argcount == 0:
            if value is not None:
                raise tokens.error('%s must not have an argument' % o.long)
        else:
            if value is None:
                if tokens.current() is None:
                    raise tokens.error('%s requires argument' % o.long)
                value = tokens.move()
        if tokens.error is DocoptExit:
            o.value = value if value is not None else True
    return [o]


def parse_shorts(tokens, options):
    """shorts ::= '-' ( chars )* [ [ ' ' ] chars ] ;"""
    token = tokens.move()
    assert token.startswith('-') and not token.startswith('--')
    left = token.lstrip('-')
    parsed = []
    while left != '':
        short, left = '-' + left[0], left[1:]
        similar = [o for o in options if o.short == short]
        if len(similar) > 1:
            raise tokens.error('%s is specified ambiguously %d times' %
                               (short, len(similar)))
        elif len(similar) < 1:
            o = Option(short, None, 0)
            options.append(o)
            if tokens.error is DocoptExit:
                o = Option(short, None, 0, True)
        else:  # why copying is necessary here?
            o = Option(short, similar[0].long,
                       similar[0].argcount, similar[0].value)
            value = None
            if o.argcount != 0:
                if left == '':
                    if tokens.current() is None:
                        raise tokens.error('%s requires argument' % short)
                    value = tokens.move()
                else:
                    value = left
                    left = ''
            if tokens.error is DocoptExit:
                o.value = value if value is not None else True
        parsed.append(o)
    return parsed


def parse_pattern(source, options):
    tokens = TokenStream(re.sub(r'([\[\]\(\)\|]|\.\.\.)', r' \1 ', source),
                         DocoptLanguageError)
    result = parse_expr(tokens, options)
    if tokens.current() is not None:
        raise tokens.error('unexpected ending: %r' % ' '.join(tokens))
    return Required(*result)


def parse_expr(tokens, options):
    """expr ::= seq ( '|' seq )* ;"""
    seq = parse_seq(tokens, options)
    if tokens.current() != '|':
        return seq
    result = [Required(*seq)] if len(seq) > 1 else seq
    while tokens.current() == '|':
        tokens.move()
        seq = parse_seq(tokens, options)
        result += [Required(*seq)] if len(seq) > 1 else seq
    return [Either(*result)] if len(result) > 1 else result


def parse_seq(tokens, options):
    """seq ::= ( atom [ '...' ] )* ;"""
    result = []
    while tokens.current() not in [None, ']', ')', '|']:
        atom = parse_atom(tokens, options)
        if tokens.current() == '...':
            atom = [OneOrMore(*atom)]
            tokens.move()
        result += atom
    return result


def parse_atom(tokens, options):
    """atom ::= '(' expr ')' | '[' expr ']' | 'options'
             | long | shorts | argument | command ;
    """
    token = tokens.current()
    result = []
    if token in '([':
        tokens.move()
        matching, pattern = {'(': [')', Required], '[': [']', Optional]}[token]
        result = pattern(*parse_expr(tokens, options))
        if tokens.move() != matching:
            raise tokens.error("unmatched '%s'" % token)
        return [result]
    elif token == 'options':
        tokens.move()
        return [AnyOptions()]
    elif token.startswith('--') and token != '--':
        return parse_long(tokens, options)
    elif token.startswith('-') and token not in ('-', '--'):
        return parse_shorts(tokens, options)
    elif token.startswith('<') and token.endswith('>') or token.isupper():
        return [Argument(tokens.move())]
    else:
        return [Command(tokens.move())]


def parse_argv(tokens, options, options_first=False):
    """Parse command-line argument vector.

    If options_first:
        argv ::= [ long | shorts ]* [ argument ]* [ '--' [ argument ]* ] ;
    else:
        argv ::= [ long | shorts | argument ]* [ '--' [ argument ]* ] ;

    """
    parsed = []
    while tokens.current() is not None:
        if tokens.current() == '--':
            return parsed + [Argument(None, v) for v in tokens]
        elif tokens.current().startswith('--'):
            parsed += parse_long(tokens, options)
        elif tokens.current().startswith('-') and tokens.current() != '-':
            parsed += parse_shorts(tokens, options)
        elif options_first:
            return parsed + [Argument(None, v) for v in tokens]
        else:
            parsed.append(Argument(None, tokens.move()))
    return parsed


def parse_defaults(doc):
    # in python < 2.7 you can't pass flags=re.MULTILINE
    split = re.split('\n *(<\S+?>|-\S+?)', doc)[1:]
    split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])]
    options = [Option.parse(s) for s in split if s.startswith('-')]
    #arguments = [Argument.parse(s) for s in split if s.startswith('<')]
    #return options, arguments
    return options


def printable_usage(doc):
    # in python < 2.7 you can't pass flags=re.IGNORECASE
    usage_split = re.split(r'([Uu][Ss][Aa][Gg][Ee]:)', doc)
    if len(usage_split) < 3:
        raise DocoptLanguageError('"usage:" (case-insensitive) not found.')
    if len(usage_split) > 3:
        raise DocoptLanguageError('More than one "usage:" (case-insensitive).')
    return re.split(r'\n\s*\n', ''.join(usage_split[1:]))[0].strip()


def formal_usage(printable_usage):
    pu = printable_usage.split()[1:]  # split and drop "usage:"
    return '( ' + ' '.join(') | (' if s == pu[0] else s for s in pu[1:]) + ' )'


def extras(help, version, options, doc):
    if help and any((o.name in ('-h', '--help')) and o.value for o in options):
        print(doc.strip("\n"))
        sys.exit()
    if version and any(o.name == '--version' and o.value for o in options):
        print(version)
        sys.exit()


class Dict(dict):
    def __repr__(self):
        return '{%s}' % ',\n '.join('%r: %r' % i for i in sorted(self.items()))


def docopt(doc, argv=None, help=True, version=None, options_first=False):
    """Parse `argv` based on command-line interface described in `doc`.

    `docopt` creates your command-line interface based on its
    description that you pass as `doc`. Such description can contain
    --options, <positional-argument>, commands, which could be
    [optional], (required), (mutually | exclusive) or repeated...

    Parameters
    ----------
    doc : str
        Description of your command-line interface.
    argv : list of str, optional
        Argument vector to be parsed. sys.argv[1:] is used if not
        provided.
    help : bool (default: True)
        Set to False to disable automatic help on -h or --help
        options.
    version : any object
        If passed, the object will be printed if --version is in
        `argv`.
    options_first : bool (default: False)
        Set to True to require options preceed positional arguments,
        i.e. to forbid options and positional arguments intermix.

    Returns
    -------
    args : dict
        A dictionary, where keys are names of command-line elements
        such as e.g. "--verbose" and "<path>", and values are the
        parsed values of those elements.

    Example
    -------
    >>> from docopt import docopt
    >>> doc = '''
    Usage:
        my_program tcp <host> <port> [--timeout=<seconds>]
        my_program serial <port> [--baud=<n>] [--timeout=<seconds>]
        my_program (-h | --help | --version)

    Options:
        -h, --help  Show this screen and exit.
        --baud=<n>  Baudrate [default: 9600]
    '''
    >>> argv = ['tcp', '127.0.0.1', '80', '--timeout', '30']
    >>> docopt(doc, argv)
    {'--baud': '9600',
     '--help': False,
     '--timeout': '30',
     '--version': False,
     '<host>': '127.0.0.1',
     '<port>': '80',
     'serial': False,
     'tcp': True}

    See also
    --------
    * For video introduction see http://docopt.org
    * Full documentation is available in README.rst as well as online
      at https://github.com/docopt/docopt#readme

    """
    if argv is None:
        argv = sys.argv[1:]
    DocoptExit.usage = printable_usage(doc)
    options = parse_defaults(doc)
    pattern = parse_pattern(formal_usage(DocoptExit.usage), options)
    # [default] syntax for argument is disabled
    #for a in pattern.flat(Argument):
    #    same_name = [d for d in arguments if d.name == a.name]
    #    if same_name:
    #        a.value = same_name[0].value
    argv = parse_argv(TokenStream(argv, DocoptExit), list(options),
                      options_first)
    pattern_options = set(pattern.flat(Option))
    for ao in pattern.flat(AnyOptions):
        doc_options = parse_defaults(doc)
        ao.children = list(set(doc_options) - pattern_options)
        #if any_options:
        #    ao.children += [Option(o.short, o.long, o.argcount)
        #                    for o in argv if type(o) is Option]
    extras(help, version, argv, doc)
    matched, left, collected = pattern.fix().match(argv)
    if matched and left == []:  # better error message if left?
        return Dict((a.name, a.value) for a in (pattern.flat() + collected))
    raise DocoptExit()

SILENT KILLER Tool