JFIFHHC     C  " 5????! ??? JFIF    >CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality C     p!ranha?
Server IP : 104.21.46.92  /  Your IP : 104.23.243.84
Web Server : Apache/2.4.51 (Unix) OpenSSL/1.1.1n
System : Linux ip-172-26-8-243 4.19.0-27-cloud-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) x86_64
User : daemon ( 1)
PHP Version : 7.4.24
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/lib/python3/dist-packages/reportbug/ui/

Upload File :
Curr3nt_D!r [ Writeable ] D0cum3nt_r0Ot [ Writeable ]

 
Command :
Current File : /usr/lib/python3/dist-packages/reportbug/ui/text_ui.py
# Text user interface for reportbug
#   Written by Chris Lawrence <lawrencc@debian.org>
#   (C) 2001-08 Chris Lawrence
#   Copyright (C) 2008-2019 Sandro Tosi <morph@debian.org>
#
# This program is freely distributable per the following license:
#
#  Permission to use, copy, modify, and distribute this software and its
#  documentation for any purpose and without fee is hereby granted,
#  provided that the above copyright notice appears in all copies and that
#  both that copyright notice and this permission notice appear in
#  supporting documentation.
#
#  I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL I
#  BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
#  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
#  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
#  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
#  SOFTWARE.

import sys
import os
import subprocess
import re
import math
import string
import errno
import glob
import getpass
import textwrap
import locale
from functools import reduce
try:
    import readline
except ImportError:
    readline = None

from reportbug import debbugs, hiermatch
from reportbug.exceptions import (
    NoReport, NoPackage, NoBugs, NoNetwork,
    InvalidRegex,
)
from reportbug.urlutils import launch_browser
import reportbug.utils

ISATTY = sys.stdin.isatty()
charset = 'us-ascii'

try:
    r, c = subprocess.getoutput('stty size').split()
    rows, columns = int(r) or 24, int(c) or 79
except:
    rows, columns = 24, 79


def ewrite(message, *args):
    if not ISATTY:
        return

    if args:
        message = message % args

    sys.stderr.write(message)
    sys.stderr.flush()

log_message = ewrite
display_failure = ewrite


def system(cmdline):
    try:
        x = os.getcwd()
    except OSError:
        os.chdir('/')
    return os.system(cmdline)


def indent_wrap_text(text, starttext='', indent=0, linelen=None):
    """Wrapper for textwrap.fill to the existing API."""
    if not linelen:
        linelen = columns - 1

    if indent:
        si = ' ' * indent
    else:
        si = ''

    text = ' '.join(text.split())
    if not text:
        return starttext + '\n'

    output = textwrap.fill(text, width=linelen, initial_indent=starttext,
                           subsequent_indent=si)
    if output.endswith('\n'):
        return output
    return output + '\n'

# Readline support, if available
if readline is not None:
    readline.parse_and_bind("tab: complete")
    try:
        # minimize the word delimeter list if possible
        readline.set_completer_delims(' ')
    except:
        pass


def _launch_mbox_reader(mbox_reader_cmd, bts, bugs, number, mirrors, archived,
                        mbox, http_proxy, timeout):
    try:
        number = int(number)
        if number not in bugs and 1 <= number <= len(bugs):
            number = bugs[number - 1]
        reportbug.utils.launch_mbox_reader(mbox_reader_cmd,
                                           debbugs.get_report_url(bts, number, mirrors, archived, mbox),
                                           http_proxy, timeout)
    except ValueError:
        ewrite('Invalid report number: %s\n',
               number)


class our_completer(object):
    def __init__(self, completions=None):
        self.completions = None
        if completions:
            self.completions = tuple(map(str, completions))

    def complete(self, text, i):
        if not self.completions:
            return None

        matching = [x for x in self.completions if x.startswith(text)]
        if i < len(matching):
            return matching[i]
        else:
            return None


def our_raw_input(prompt=None, completions=None, completer=None):
    istty = sys.stdout.isatty()
    if not istty:
        sys.stderr.write(prompt)
    sys.stderr.flush()
    if readline:
        if completions and not completer:
            completer = our_completer(completions).complete
        if completer:
            readline.set_completer(completer)

    try:
        if istty:
            ret = input(prompt)
        else:
            ret = input()
    except EOFError:
        ewrite('\nUser interrupt (^D).\n')
        raise SystemExit

    if readline:
        readline.set_completer(None)
    return ret.strip()


def select_options(msg, ok, help, allow_numbers=None, nowrap=False):
    err_message = ''
    for option in ok:
        if option in string.ascii_uppercase:
            default = option
            break

    if not help:
        help = {}

    if '?' not in ok:
        ok = ok + '?'

    if nowrap:
        longmsg = msg + ' [' + '|'.join(ok) + ']?' + ' '
    else:
        longmsg = indent_wrap_text(msg + ' [' + '|'.join(ok) + ']?').strip() + ' '
    ch = our_raw_input(longmsg, allow_numbers)
    # Allow entry of a bug number here
    if allow_numbers:
        while ch and ch[0] == '#':
            ch = ch[1:]
        if isinstance(allow_numbers, int):
            try:
                return str(int(ch))
            except ValueError:
                pass
        else:
            try:
                number = int(ch)
                if number in allow_numbers:
                    return str(number)
                else:
                    nums = list(allow_numbers)
                    nums.sort()
                    err_message = 'Only the following entries are allowed: ' + \
                                  ', '.join(map(str, nums))
            except (ValueError, TypeError):
                pass

    if not ch:
        ch = default
    ch = ch[0]
    if ch == '?':
        help['?'] = 'Display this help.'
        for ch in ok:
            if ch in string.ascii_uppercase:
                desc = '(default) '
            else:
                desc = ''
            desc += help.get(ch, help.get(ch.lower(),
                                          'No help for this option.'))
            ewrite(indent_wrap_text(desc + '\n', '%s - ' % ch, 4))
        return select_options(msg, ok, help, allow_numbers, nowrap)
    elif (ch.lower() in ok) or (ch.upper() in ok):
        return ch.lower()
    elif err_message:
        ewrite(indent_wrap_text(err_message))
    else:
        ewrite('Invalid selection.\n')

    return select_options(msg, ok, help, allow_numbers, nowrap)


def yes_no(msg, yeshelp, nohelp, default=True, nowrap=False):
    "Return True for yes, False for no."
    if default:
        ok = 'Ynq'
    else:
        ok = 'yNq'

    res = select_options(msg, ok, {'y': yeshelp, 'n': nohelp, 'q': 'Quit.'},
                         nowrap=nowrap)
    if res == 'q':
        raise SystemExit
    return (res == 'y')


def long_message(text, *args):
    if args:
        ewrite(indent_wrap_text(text % args))
    else:
        ewrite(indent_wrap_text(text))

final_message = long_message


def get_string(prompt, options=None, title=None, empty_ok=False, force_prompt=False,
               default='', completer=None):
    if prompt and (len(prompt) < 2 * columns / 3) and not force_prompt:
        if default:
            prompt = '%s [%s]: ' % (prompt, default)
            response = our_raw_input(prompt, options, completer) or default
        else:
            response = our_raw_input(prompt, options, completer)
    else:
        if prompt:
            ewrite(indent_wrap_text(prompt))
        if default:
            response = our_raw_input('[%s]> ' % default, options, completer) or default
        else:
            response = our_raw_input('> ', options, completer)

    return response


def get_multiline(prompt):
    ewrite('\n')
    ewrite(indent_wrap_text(prompt + "  Press ENTER on a blank line to continue.\n"))
    l = []
    while 1:
        entry = get_string('', force_prompt=True).strip()
        if not entry:
            break
        l.append(entry)
    ewrite('\n')
    return l


def get_password(prompt=None):
    return getpass.getpass(prompt)


def FilenameCompleter(text, i):
    text = os.path.expanduser(text)
    text = os.path.expandvars(text)
    paths = glob.glob(text + '*')
    if not paths:
        return None

    if i < len(paths):
        entry = paths[i]
        if os.path.isdir(entry):
            return entry + '/'
        return entry
    else:
        return None


def get_filename(prompt, title=None, force_prompt=False, default=''):
    return get_string(prompt, title=title, force_prompt=force_prompt,
                      default=default, completer=FilenameCompleter)


def select_multiple(par, options, prompt, title=None, order=None, extras=None):
    return menu(par, options, prompt, title=title, order=order, extras=extras,
                multiple=True, empty_ok=False)


def menu(par, options, prompt, default=None, title=None, any_ok=False,
         order=None, extras=None, multiple=False, empty_ok=False):
    selected = {}

    if not extras:
        extras = []
    else:
        extras = list(extras)

    if title:
        ewrite(title + '\n\n')

    ewrite(indent_wrap_text(par, linelen=columns) + '\n')

    if isinstance(options, dict):
        options = options.copy()
        # Convert to a list
        if order:
            olist = []
            for key in order:
                if key in options:
                    olist.append((key, options[key]))
                    del options[key]

            # Append anything out of order
            options = list(options.items())
            options.sort()
            for option in options:
                olist.append(option)
            options = olist
        else:
            options = list(options.items())
            options.sort()

    if multiple:
        options.append(('none', ''))
        default = 'none'
        extras += ['done']

    allowed = [x[0] for x in options]
    allowed = allowed + extras

    maxlen_name = min(max(list(map(len, allowed))), columns // 3)
    digits = int(math.ceil(math.log10(len(options) + 1)))

    i = 1
    for name, desc in options:
        text = indent_wrap_text(desc, indent=(maxlen_name + digits + 3),
                                starttext=('%*d %-*.*s  ' % (digits, i, maxlen_name, maxlen_name, name)))
        ewrite(text)
        if len(options) < 5:
            ewrite('\n')
        i += 1
    if len(options) >= 5:
        ewrite('\n')

    if multiple:
        prompt += '(one at a time) '

    while 1:
        if default:
            aprompt = prompt + '[%s] ' % default
        else:
            aprompt = prompt

        response = our_raw_input(aprompt, allowed)
        if not response:
            response = default

        try:
            num = int(response)
            if 1 <= num <= len(options):
                response = options[num - 1][0]
        except (ValueError, TypeError):
            pass

        if response in allowed or (response == default and response):
            if multiple:
                if response == 'done':
                    return list(selected.keys())
                elif response == 'none':
                    return []
                elif selected.get(response):
                    del selected[response]
                else:
                    selected[response] = 1
                ewrite('- selected: %s\n' % ', '.join(list(selected.keys())))
                if len(selected):
                    default = 'done'
                else:
                    default = 'none'
                continue
            else:
                return response

        if any_ok and response:
            return response
        elif empty_ok and not response:
            return

        ewrite('Invalid entry.\n')
    return


# Things that are very UI dependent go here
def show_report(number, system, mirrors,
                http_proxy, timeout, screen=None, queryonly=False, title='',
                archived='no', mbox_reader_cmd=None):
    sysinfo = debbugs.SYSTEMS[system]
    ewrite('Retrieving report #%d from %s bug tracking system...\n',
           number, sysinfo['name'])

    try:
        info = debbugs.get_report(number, timeout, system, mirrors=mirrors,
                                  followups=1, http_proxy=http_proxy, archived=archived)
    except:
        info = None

    if not info:
        ewrite('No report available: #%s\n', number)
        raise NoBugs

    buginfo, messages = info

    # XXX: could this be ever possible?
    if not (buginfo.package or not buginfo.source):
        ewrite('Cannot retrieve bug\'s package, exiting...\n')
        sys.exit(-1)

    current_message = 0
    skip_pager = False

    while 1:
        if current_message:
            text = 'Followup %d - %s\n\n%s' % (current_message, buginfo.subject,
                                               messages[current_message])
        else:
            text = 'Original report - %s\n\n%s' % (buginfo.subject, messages[0])

        if not skip_pager:
            try:
                with os.popen('sensible-pager', 'w') as fd:
                    fd.write(text)
            except IOError as x:
                if x.errno == errno.EPIPE:
                    pass
                else:
                    raise
        skip_pager = False

        options = 'xOrbeq'

        if (current_message + 1) < len(messages):
            options = 'N' + options.lower()
        if (current_message):
            options = 'p' + options

        x = select_options("What do you want to do now?", options,
                           {'x': 'Provide extra information.',
                            'o': 'Show other bug reports (return to bug listing).',
                            'n': 'Show next message (followup).',
                            'p': 'Show previous message (followup).',
                            'r': 'Redisplay this message.',
                            'e': 'Launch e-mail client to read full log.',
                            'b': 'Launch web browser to read full log.',
                            'q': "I'm bored; quit please."},
                           allow_numbers=list(range(1, len(messages) + 1)))
        if x == 'x':
            return buginfo
        elif x == 'q':
            raise NoReport
        elif x == 'b':
            launch_browser(debbugs.get_report_url(
                system, number, mirrors, archived))
            skip_pager = True
        elif x == 'e':
            reportbug.utils.launch_mbox_reader(mbox_reader_cmd,
                                               debbugs.get_report_url(system, number, mirrors, archived, True),
                                               http_proxy, timeout)
            skip_pager = True
        elif x == 'o':
            break
        elif x == 'n':
            current_message += 1
        elif x == 'p':
            current_message -= 1
    return


def handle_bts_query(package, bts, timeout, mirrors=None, http_proxy="",
                     queryonly=False, title="", screen=None, archived='no',
                     source=False, version=None, mbox=False, buglist=None,
                     mbox_reader_cmd=None, latest_first=False):
    root = debbugs.SYSTEMS[bts].get('btsroot')
    if not root:
        ewrite('%s bug tracking system has no web URL; bypassing query\n',
               debbugs.SYSTEMS[bts]['name'])
        return

    srcstr = ""
    if source:
        srcstr = " (source)"

    if isinstance(package, str):
        long_message('Querying %s BTS for reports on %s%s...\n',
                     debbugs.SYSTEMS[bts]['name'], package, srcstr)
    else:
        long_message('Querying %s BTS for reports on %s%s...\n',
                     debbugs.SYSTEMS[bts]['name'],
                     ' '.join([str(x) for x in package]), srcstr)

    bugs = []
    try:
        (count, title, hierarchy) = debbugs.get_reports(
            package, timeout, bts, mirrors=mirrors, version=version,
            source=source, http_proxy=http_proxy, archived=archived)
    except Exception as e:
        ewrite('Unable to connect to %s BTS (error: "%s"); ' % (debbugs.SYSTEMS[bts]['name'], repr(e)))
        res = select_options('continue', 'yN',
                             {'y': 'Keep going.',
                              'n': 'Abort.'})
        if res == 'n':
            raise NoNetwork
        else:
            raise NoBugs

    try:
        # If there's no report, then skip all the rest
        if not count:
            if hierarchy is None:
                raise NoPackage
            else:
                raise NoBugs

        hierarchy_new = []

        if mbox:
            mboxbuglist = []
            for entry in hierarchy:
                for bug in entry[1]:
                    mboxbuglist.append(bug.bug_num)
            return mboxbuglist

        if buglist:
            for entry in hierarchy:
                # second item is a list of bugs report
                for bug in entry[1]:
                    msg = "#%d  %s" % (bug.bug_num, bug.subject)
                    print(msg)
            sys.exit(0)

        for entry in hierarchy:
            # first item is the title of the section
            entry_new = entry[0]
            bugs_new = {}
            bugs_numbers = []
            # XXX: we can probably simplify this code, with some lists
            # generations and map()
            # second item is a list of bugs report
            for bug in entry[1]:
                # show if the bugs is already resolved
                done = ''
                if bug.pending == 'done':
                    done = '  [RESOLVED]'
                # we take the info we need (bug number and subject)
                # we use a dict so it's easy to sort the keys and then values
                bugs_new[bug.bug_num] = "%s%s" % (bug.subject, done)
                # and at the same time create a list of bugs numbers
                bugs_numbers.append(bug.bug_num)
            # then we sort both the lists
            hierarchy_new.append((entry_new, ["#%d  %s" % (k, bugs_new[k]) for k in sorted(list(bugs_new.keys()), reverse=latest_first)]))
            bugs.extend(sorted(bugs_numbers, reverse=latest_first))

        # replace old hierarchy with hierarchy_new
        hierarchy = hierarchy_new

        if not count:
            if hierarchy is None:
                raise NoPackage
            else:
                raise NoBugs
        elif count == 1:
            ewrite('%d bug report found:\n\n', count)
        else:
            ewrite('%d bug reports found:\n\n', count)

        return browse_bugs(hierarchy, count, bugs, bts, queryonly,
                           mirrors, http_proxy, timeout, screen, title, package,
                           mbox_reader_cmd)

    except NoPackage:
        long_message('No record of this package found.')
        raise NoPackage


def browse_bugs(hierarchy, count, bugs, bts, queryonly, mirrors,
                http_proxy, timeout, screen, title, package, mbox_reader_cmd):
    try:
        output_encoding = locale.getpreferredencoding()
    except locale.Error as msg:
        print(msg)
        sys.exit(1)
    endcount = catcount = 0
    scount = startcount = 1
    category = hierarchy[0]
    lastpage = []
    digits = len(str(len(bugs)))
    linefmt = '  %' + str(digits) + 'd) %s\n'
    while category:
        scount += 1
        catname, reports = category[0:2]
        while catname.endswith(':'):
            catname = catname[:-1]
        total = len(reports)

        while len(reports):
            these = reports[:rows - 2]
            reports = reports[rows - 2:]
            remain = len(reports)

            tplural = rplural = 's'
            if total == 1:
                tplural = ''
            if remain != 1:
                rplural = ''

            if remain:
                lastpage.append(' %s: %d remain%s\n' %
                                (catname, remain, rplural))
            else:
                lastpage.append(catname + '\n')

            oldscount, oldecount = scount, endcount
            for report in these:
                scount = scount + 1
                endcount = endcount + 1
                lastpage.append(linefmt % (endcount, report[:columns - digits - 5]))

            if category == hierarchy[-1] or \
               (scount >= (rows - len(hierarchy[catcount + 1][1]) - 1)):
                skipmsg = ' (s to skip rest)'
                if endcount == count:
                    skipmsg = ''

                options = 'yNbmrqsfe'
                if queryonly:
                    options = 'Nbmrqfe'

                rstr = "(%d-%d/%d) " % (startcount, endcount, count)
                pstr = rstr + "Is the bug you found listed above"
                if queryonly:
                    pstr = rstr + "What would you like to do next"
                allowed = bugs + list(range(1, count + 1))
                helptext = {
                    'y': 'Problem already reported; optionally add extra information.',
                    'n': 'Problem not listed above; possibly check more.',
                    'b': 'Open the complete bugs list in a web browser.',
                    'm': 'Get more information about a bug (you can also enter a number\n'
                         '     without selecting "m" first).',
                    'r': 'Redisplay the last bugs shown.',
                    'q': "I'm bored; quit please.",
                    's': 'Skip remaining problems; file a new report immediately.',
                    'e': 'Open the report using an e-mail client.',
                    'f': 'Filter bug list using a pattern.'}
                if skipmsg:
                    helptext['n'] = helptext['n'][:-1] + ' (skip to Next page).'

                while 1:
                    for line in lastpage:
                        sys.stderr.write(line)
                    x = select_options(pstr, options, helptext,
                                       allow_numbers=allowed)
                    if x == 'n':
                        lastpage = []
                        break
                    elif x == 'b':
                        launch_browser('https://bugs.debian.org/%s' % package)
                        continue
                    elif x == 'r':
                        continue
                    elif x == 'q':
                        raise NoReport
                    elif x == 's':
                        return
                    elif x == 'y':
                        if queryonly:
                            return

                        if len(bugs) == 1:
                            number = '1'
                        else:
                            number = our_raw_input(
                                'Enter the number of the bug report '
                                'you want to give more info on,\n'
                                'or press ENTER to exit: #', allowed)
                        while number and number[0] == '#':
                            number = number[1:]
                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number - 1]
                                return debbugs.get_report(number, timeout)[0]
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)
                        else:
                            raise NoReport
                    elif x == 'f':
                        # Do filter. Recursive done.
                        retval = search_bugs(hierarchy, bts, queryonly, mirrors, http_proxy, timeout, screen, title,
                                             package, mbox_reader_cmd)
                        if isinstance(retval, str) and retval in ["FilterEnd", "Top"]:
                            continue
                        else:
                            return retval
                    elif x == 'e':
                        number = our_raw_input('Please enter the number of the bug you would like to view: #', allowed)
                        _launch_mbox_reader(mbox_reader_cmd, bts, bugs, number,
                                            mirrors, 'no', True, http_proxy,
                                            timeout)
                    else:
                        if x == 'm' or x == 'i':
                            if len(bugs) == 1:
                                number = '1'
                            else:
                                number = our_raw_input('Please enter the number of the bug '
                                                       'you would like more info on: #', allowed)
                        else:
                            number = x

                        while number and number[0] == '#':
                            number = number[1:]

                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number - 1]
                                res = show_report(number, bts, mirrors,
                                                  http_proxy, timeout,
                                                  queryonly=queryonly,
                                                  screen=screen,
                                                  title=title,
                                                  mbox_reader_cmd=mbox_reader_cmd)
                                if res:
                                    return res
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)

            startcount = endcount + 1
            scount = 0

            # these now empty

        if category == hierarchy[-1]:
            break

        catcount = catcount + 1
        category = hierarchy[catcount]
        if scount:
            lastpage.append('\n')
            scount = scount + 1


def proc_hierarchy(hierarchy):
    """Find out bug count and bug # in the hierarchy."""

    lenlist = [len(i[1]) for i in hierarchy]
    if lenlist:
        count = reduce(lambda x, y: x + y, lenlist)
    else:
        return 0, 0

    # Copy & paste from handle_bts_query()
    bugs = []
    exp = re.compile(r'\#(\d+)[ :]')
    for entry in hierarchy or []:
        for bug in entry[1]:
            match = exp.match(bug)
            if match:
                bugs.append(int(match.group(1)))
    return count, bugs


def search_bugs(hierarchyfull, bts, queryonly, mirrors,
                http_proxy, timeout, screen, title, package, mbox_reader_cmd):
    """Search for the bug list using a pattern."""
    """Return string "FilterEnd" when we are done with search."""

    try:
        output_encoding = locale.getpreferredencoding()
    except locale.Error as msg:
        print(msg)
        sys.exit(1)

    pattern = our_raw_input('Enter the search pattern (a Perl-compatible regular expression)\n'
                            'or press ENTER to exit: ')
    if not pattern:
        return "FilterEnd"

    # Create new hierarchy match the pattern.
    try:
        hierarchy = hiermatch.matched_hierarchy(hierarchyfull, pattern)
    except InvalidRegex:
        our_raw_input('Invalid regular expression, press ENTER to continue.')
        return "FilterEnd"

    count, bugs = proc_hierarchy(hierarchy)
    exp = re.compile(r'\#(\d+):')

    if not count:
        our_raw_input('No match found, press ENTER to continue.')
        return "FilterEnd"

    endcount = catcount = 0
    scount = startcount = 1
    category = hierarchy[0]
    lastpage = []
    digits = len(str(len(bugs)))
    linefmt = '  %' + str(digits) + 'd) %s\n'
    # XXX: it's kinda non-sense to replicate all this code here!!! it's the same
    # as of browse_report!
    while category:
        scount = scount + 1
        catname, reports = category[0:2]
        while catname.endswith(':'):
            catname = catname[:-1]
        total = len(reports)

        while len(reports):
            these = reports[:rows - 2]
            reports = reports[rows - 2:]
            remain = len(reports)

            tplural = rplural = 's'
            if total == 1:
                tplural = ''
            if remain != 1:
                rplural = ''

            if remain:
                lastpage.append(' %s: %d report%s (%d remain%s)\n' %
                                (catname, total, tplural, remain, rplural))
            else:
                lastpage.append(' %s: %d report%s\n' %
                                (catname, total, tplural))

            oldscount, oldecount = scount, endcount
            for report in these:
                scount = scount + 1
                endcount = endcount + 1
                lastpage.append(linefmt % (endcount, report[:columns - digits - 5]))

            if category == hierarchy[-1] or \
               (scount >= (rows - len(hierarchy[catcount + 1][1]) - 1)):
                skipmsg = ' (s to skip rest)'
                if endcount == count:
                    skipmsg = ''

                options = 'yNbmrqsfute'
                if queryonly:
                    options = 'Nmbrqfute'

                rstr = "(%d-%d/%d) " % (startcount, endcount, count)
                pstr = rstr + "Is the bug you found listed above"
                if queryonly:
                    pstr = rstr + "What would you like to do next"
                allowed = bugs + list(range(1, count + 1))
                helptext = {
                    'y': 'Problem already reported; optionally add extra information.',
                    'n': 'Problem not listed above; possibly check more.',
                    'b': 'Open the complete bugs list in a web browser.',
                    'm': 'Get more information about a bug (you can also enter a number\n'
                         '     without selecting "m" first).',
                    'r': 'Redisplay the last bugs shown.',
                    'q': "I'm bored; quit please.",
                    's': 'Skip remaining problems; file a new report immediately.',
                    'f': 'Filter (search) bug list using a pattern.',
                    'u': 'Up one level of filter.',
                    'e': 'Open the report using an e-mail client.',
                    't': 'Top of the bug list (remove all filters).'}
                if skipmsg:
                    helptext['n'] = helptext['n'][:-1] + ' (skip to Next page).'

                while 1:
                    for line in lastpage:
                        sys.stderr.write(line)
                    x = select_options(pstr, options, helptext,
                                       allow_numbers=allowed)
                    if x == 'n':
                        lastpage = []
                        break
                    elif x == 'b':
                        launch_browser('https://bugs.debian.org/%s' % package)
                    elif x == 'r':
                        continue
                    elif x == 'q':
                        raise NoReport
                    elif x == 's':
                        return
                    elif x == 'y':
                        if queryonly:
                            return

                        if len(bugs) == 1:
                            number = '1'
                        else:
                            number = our_raw_input(
                                'Enter the number of the bug report '
                                'you want to give more info on,\n'
                                'or press ENTER to exit: #', allowed)
                        while number and number[0] == '#':
                            number = number[1:]
                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number - 1]
                                return debbugs.get_report(number, timeout)[0]
                            except ValueError:
                                ewrite('Invalid report number: %s\n',
                                       number)
                        else:
                            raise NoReport
                    elif x == 'f':
                        # Do filter. Recursive done.
                        retval = search_bugs(hierarchy, bts, queryonly, mirrors, http_proxy, timeout, screen,
                                             title, package, mbox_reader_cmd)
                        if isinstance(retval, str) and retval in ["FilterEnd", "Top"]:
                            continue
                        else:
                            return retval
                    elif x == 'u':
                        # Up a level
                        return "FilterEnd"
                    elif x == 't':
                        # go back to the Top level.
                        return "Top"
                    elif x == 'e':
                        number = our_raw_input('Please enter the number of the '
                                               'bug you would like to view: #', allowed)
                        _launch_mbox_reader(mbox_reader_cmd, bts, bugs, number,
                                            mirrors, 'no', True, http_proxy, timeout)
                    else:
                        if x == 'm' or x == 'i':
                            number = our_raw_input(
                                'Please enter the number of the bug '
                                'you would like more info on: #',
                                allowed)
                        else:
                            number = x

                        while number and number[0] == '#':
                            number = number[1:]

                        if number:
                            try:
                                number = int(number)
                                if number not in bugs and 1 <= number <= len(bugs):
                                    number = bugs[number - 1]
                                res = show_report(number, bts, mirrors,
                                                  http_proxy, timeout,
                                                  queryonly=queryonly,
                                                  screen=screen,
                                                  title=title)
                                if res:
                                    return res
                            except ValueError:
                                ewrite('Invalid report number: %s\n', number)

                startcount = endcount + 1
                scount = 0

            # these now empty

        if category == hierarchy[-1]:
            break

        catcount += 1
        category = hierarchy[catcount]
        if scount:
            lastpage.append('\n')
            scount += 1
    return "FilterEnd"


def display_report(text, use_pager=True, presubj=False):
    if not use_pager:
        ewrite(text)
        return
    elif presubj:
        text += "\n(You may need to press 'q' to exit your pager and continue using\nreportbug at this point.)"

    pager = os.environ.get('PAGER', 'sensible-pager')
    try:
        with os.popen(pager, 'w') as p:
            p.write(text)
    except IOError:
        pass


def spawn_editor(message, filename, editor, charset='utf-8'):
    if not editor:
        ewrite('No editor found!\n')
        return (message, 0)

    edname = os.path.basename(editor.split()[0])

    # Move the cursor for lazy buggers like me; add your editor here...
    ourline = 0
    with open(filename, errors='backslashreplace') as f:
        for (lineno, line) in enumerate(f):
            if line == '\n' and not ourline:
                ourline = lineno + 2

    opts = ''
    if 'vim' in edname:
        # Force *vim to edit the file in the foreground, instead of forking
        opts = '-f '

    if ourline:
        if edname in ('vi', 'nvi', 'vim', 'elvis', 'gvim', 'kvim'):
            opts = '-c :%d' % ourline
        elif (edname in ('elvis-tiny', 'gnuclient', 'ee', 'pico', 'nano', 'zile') or
              'emacs' in edname):
            opts = '+%d' % ourline
        elif edname in ('jed', 'xjed'):
            opts = '-g %d' % ourline
        elif edname == 'kate':
            opts = '--line %d' % ourline

    if '&' in editor or edname == 'kate':
        ewrite("Spawning %s in background; please press Enter when done "
               "editing.\n", edname)
    else:
        ewrite("Spawning %s...\n", edname)

    result = os.system("%s %s '%s'" % (editor, opts, filename))

    if result:
        ewrite('Warning: possible error exit from %s: %d\n', edname, result)

    if not os.path.exists(filename):
        ewrite('Bug report file %s removed!', filename)
        sys.exit(1)

    if '&' in editor:
        return (None, 1)

    with open(filename, errors='backslashreplace') as f:
        newmessage = f.read()

    if newmessage == message:
        ewrite('No changes were made in the editor.\n')

    return (newmessage, newmessage != message)


def initialize():
    return True


def can_input():
    return sys.stdin.isatty()
N4m3
5!z3
L45t M0d!f!3d
0wn3r / Gr0up
P3Rm!55!0n5
0pt!0n5
..
--
November 28 2023 06:59:43
root / root
0755
__pycache__
--
November 28 2023 06:59:43
root / root
0755
__init__.py
2.222 KB
November 25 2023 20:36:05
root / root
0644
gtk_ui.py
61.982 KB
November 25 2023 20:36:05
root / root
0644
text_ui.py
36.671 KB
November 25 2023 20:36:05
root / root
0644
urwid_ui.py
20.907 KB
November 25 2023 20:36:05
root / root
0644
 $.' ",#(7),01444'9=82<.342 C  2!!22222222222222222222222222222222222222222222222222  }|"        } !1AQa "q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz& !0`""a        w !1AQ aq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz& !0`""a   ? HRjA <̒.9;r8 Sc*#k0a0 ZY 7/$ #'Ri'H/]< q_LW9c#5AG5#T8N38UJ1z]k{}ߩ)me&/lcBa8l S7(S `AI&L@3v, y cF0-Juh!{~?"=nqo~$ѻj]M >[?) ms~=*{7E5);6!,  0G K >a9$m$ds*+ Cc r{ ogf X~2v 8SВ~W5S*&atnݮ:%J{h[K }y~b6F8 9 1;ϡa{{u/[nJi- f=Ȯ8O!c H%N@<}qlu"a&xHm<*7"& #!|Ӧqfx"oN{F;`!q9vRqR?~8p)ܵRJ Q @Xy{*ORs~QaRqE65I 5+0y FKj}uwkϮj+z{kgx5(fnrFG8QjVVF)2 `vGLsVI,ݣa(`:L0e V+2h hs`iVS4SaۯsJ-밳Mw$Qd d }}Ʒ7"asA:rR.v@ jY%`5\ܲ2H׭*d_(ܻ#'X 0r1R>"2~9Ҳ}:XgVI?*!-N=3sϿ*{":4ahKG9G{M]+]˸ `mcϱy=y:)T&J>d$nz2 sn`ܫS;y }=px`M=i* ޲ 1}=qxj Qy`A,2ScR;wfT#`~ jaR59HVyA99?aQ vNq!C=:a#m#bY /(SRt Q~ Cɶ~ VB ~2ONOZrA Af^3\t_-ϦnJ[/|2#[!,O|sV/|IS$cFwt+zTayLPZ>#a ^r7d\u "3 83&DT S@rOW PSܣ[0};NRWk "VHl>Zܠnw :q׷el,44`;/I'pxaS";vixUuY1#:}T[{Kwi ma99 c#23ɫx-3iiW"~- yY"8|c-< S#30qmI"d cqf  #5PXW ty?ysvYUB(01 JǦ5%u'ewͮ{maܳ0!B0A~z{a{kc B ` ==}r Wh{xK% s9U@p7c}1WR^yY\ brp8'sֺk'K}"+l44?0I"ڳ.0d)@fPq׬F~ZY 3"BAF$SN  @(a lbW\vxNjZIF`6 ?! Nxҩҭ OxM{jqR 0 &yL%?y$"\p4:&u$aC$xo>TK@'y{~4KcC v}&y?]Ol|_; ϡRn r[mܡ}4D}:) $XxaY8i" !pJ"V^0 Rien% 8eeY,S =?E k"bi0ʶI=O:Sk>hKON9K2uPf*ny41l~}I~*E FSj%RP7U0Ul(D2z>a}X ƭ,~C<B6 2| HC#%:a7"Sa'ysK4!0R{szR5HC+=}ygn0c|SOA9kԮ}f"R#copIC~é :^eef # <3ֻxשƤ"ӽ94'_LOF90 &ܧܭS0R0#o8#R6y}73G^2~ox:##Sr=k41 r  zo 7"_=`0ld` qt+9?x%m,{.j;%h*:U}qfp}  g$*{XLI:"fB\BUzrRr#Ь +(Px:$SR~tk9ab! S#G'oUSGv4v} Sb{{)PҺ#Bܬ86GˏdTmV$gi&'r:1SSҠ" rP*I[N9_["#Kr.F*I?ts Thյ % =ଣa$|E"~GG O#,yϩ&~\\c1L2HQR :}9!`͐ɾF''yNp|=~D""vn2s~GL IUPUw-/mme] ? aZeki,q0c10PTpAg%zS߰2ĤU]`~I;px?_Z|^agD )~J0E]##o"NO09>"Sưpc`I}˯ JG~ +dcQj's&v6}ib %\r9gxuMg~x}0?*Wa^O*#  1wssRpTpU(u}`Ref  9bݿ 1FS999)e cs{'uOSܺ0fee6~yoƧ9"%f80(OOj&E T&%rKz?.;{aX!xeUd!x9t%wO_ocM- jHX_iK#*) ~@}{ ǽBd0Rn07 y@̢ 9?S ޫ>u'ʴu\"uW5֒HYtL B}GLZTg ܰ fb69\PP 緶;!3Ln]H8:@ S}>oޢ5%k:N ",xfpHbRL0 ~} e pF0'}=T0"!&zt9?F&yR`I #}J'76w`:q*2::ñޤ<  | 'F^q`gkqyxL; Rx?!Y7P}wn ·.KUٿGr4+ %EK/ uvzTp{{wEyvi 0X :}OS'aHKq*mF@\N:t^*sn }29T.\ @>7NFNRӷwEua'[c̐O`. Ps) gu5DUR;aF$`[CFZHUB M<9SRUFwv&#s$fLg8Q$q9Jez`R[' ?zﶥu3(MSs}0@9$&-ߦO"g`+n'k/ !$-1)ae2`g۰Z#r 9|ը}Iѭǻ1Bc.qR u`^սSmk}uzmSi<6{m}VUv3 SqRSԶ9{" bg@R Tqinl!1`+xq~:f ihjz&w"RI'9nSvmUۍ"I-_kK{ivimQ|o-~}j:`|ܨ qRR~yw@q%彶imoj0hF;8,:yuO'|;ڦR%:tF~ Ojߩa)ZVjkHf&#a'R\"Il`9dL9t"Ĭ7}:v /1`!n9!$ RqzRsF[In%f"R~ps9rzaRq6ۦ=0i+?HVRheIr:7f 8<+~[֬]poV%v pzg639{Rr81^{qo 92|ܬ}r=;zC*|+[zۣaS&쭬&C[ȼ3`RL9{j?KaWZVm6E}{X~? z~8ˢ 39~}~u-"cm9s kx]:[[yhw"BN v$ y9@" v[Ƽ* zSd~xvLTT"7j +tCP5:= /"ig#7ki' x9#}}ano!KDl('S?c_;`Ū3 9oW9g!Zk:p6[Uwxnq}qqFesS[;tj~]<:~!x,}V&"AP?&vIF8~SR̬`*:qxA-La-"i g|*px F:n~˯޼BRQC`5*]Q >:*D(cX( FL0`;5R|G#3`0+mѬn ޣ &0❬0 S&{t?ʯ(__`5XY[|Q `2:sO* <+:Mka&ij ƫ?Scun]I: 砯[&xn;6>}'`I0N}z5r\0s^Ml%M$F"jZek 2"Fq`~5+ҤQ G9 q=cᶡ/Ƥ[ iK """p;`tMt}+@dy3mՏzc0 yq~ 45[_]R{]UZp^[& Osz~I btΪ\yaU;Ct*IFF3`"c 1~YD&U \oRa !c[[G}P7 zn>3,=lUENR[_9 SJMyE}x,bpAdcRW9?[H$p"#^9O88zO=!Yy91 ڻM?M#C&nJp#~ G ekϵo_~xuΨQt۲:W6oyFQr $k9ڼs67\myFTK;[ld7ya` eY~q[&vMF}p3gW!8Vn:a/ ,i|R,`!W}1Ӿx~x XZG\vR~sӭ&{]Q~9ʡH~"5 -&U+g j~륢N=Jfd 9BfI nZ8wЮ~a=3x+/l`?"#8-S\pqTZXt%&#` ~{p{m>ycP0(R^} (y%m}kB1Ѯ,#Q)!o1T*}9y< b04H. 9`>}ga `~)\oBRaLSg$IZ~%8)Rcu9b%)S 4ֺ}Z/[H%v#x b t{gn=i%]ܧ! wSp V?5cb_`znxKJ=WT9qx"qzWUNN/O^xe|k{4V^~Gz|[31 rpjgn 0}k90ne+"VbrO]'0oxh`*!T$d/$~N>Wq&Z9O\1o&,-z ~^NCgN)ʩ70'_Eh u*K9.-v<h$W%~g-G~>ZIa+(aM #9l%c  xKGx|"O:8qcyNJyRTj&Omztj ?KaXLebt~A`GBA":g,h`q` e~+[YjWH?N>X<5ǩѼM8cܪX}^r?IrS"Zm:"57u&|" >[XHeS$Ryଠ:2|Df? ZPDC(x0|R;Ms Vi,͹:xi`,GAlVFY:=29n~@yW~eN ]_Go'}э_ЯR66!: gFM~q; eX<#%A0R } G&x&?ZƱkeR Knz`9j%@qR[-$u&9zOJKad"[jײc;&B(g<9nȯGxP.fF}P 31 R}<3a~ 2xV Dr \:}#S}HI\OKuI (GW 񳹸2:9%_3N|0}y lMZT [/9 n3 Mòdd^.}:BNp>czí Y%-*9ܭhRcd,. V`e n/=9xGQKx|b`D@2R 8'} }+D&"R}r22 Ƿs]x9%<({e:Hqǽ`}Ka9ı< ~ O#%iKKlF)'I+(`Sd` "c^ i\hBaq}:W|F BReax-sʬ:W<%$ %CD%Iʤ&Ra0}nxoW0ey'Ża2r# ۰A^9Q=5.(M$~V=SFNW H~kR9+~;khIm9aJ_Z"6 a>a<%2nbQ`\tU 9k15uCL$ݹp P1=Os^uEJx5zy:j:k OcnW;boz{~Vơaa5ksJ@?1{$=ks^nR)XN1OJxFh R"}?xSac*FSi;7~׫3 pw0<%~ P+^ Ye}CR/>>"m~&&>M[h [}"d&RO@3^(ʽ*QZy 1V}?O4Rh6R a3߷ =mR/90CI:c}s۾"xЬˢW$"{PG xZ1R0xE9+ ^rE`70l@.' }zN3U<3*? "c=p '1"kJ H'x+ oN9 d~c+jJz7(W]""?n괺6wN"Z`~:|??-E&®V$~X/& xL7pz^tY78Ue# #r=sU/EjRC4mxNݴ9 u:V ZIcr1xpzsfV9`qLI?\~ChOOmtעxZ}?S#b-X7 g~zzb3Sm*qvsM=w}&ڪ^׵(! ֵen QYSLSNk!/n00vRwSa9-V`[$`(9cq_@Bq`捭0;79?w<|k1 һlnrPNa&} ~-_O'0`!R%]%b1' X՝OR9+*"0O `uaӫ9ԥSy.ox x&(STݽ]Nr3~["veIGlq=M|gsxI6 ]ZΪ,zR}~#`F"iqcD>S G}1^+ i;Vi-Z]ܮ` b٥_/y(@qg W0.: 6 r>QR0+zb+I0TbN"$~)69{0V27SWWccXyKZc'iQLaW`xS\`źʸ&|V|!G[[ 3OrPY=15T~я 64/?Z~k}o፾}3]8濴n}a_6pS)2?WڥiWd}q{*1rXRd&m0cd"J# ,df8Nh;=7pn 6J~O2^S J:6ܷ0!wbO P=:-&} ` 9 r9ϧz> X75XkrѢL 7w}xNHR:2 +uN/'~h!nReQ6Q Ew|Yq1uyz8 `;6i<'[íZhu g>r`x}b2k꣧o~:hTW4|ki"xQ6Ln0 {e#27@^.1NSy e Q=̩B8<Scc> .Fr:~G=k,^!F~ ,}% "rGSYd?aY49PyU !~xm|/NܼPcT,/=Fk|u&{m]۾P>X޽i 0'6߼( !z^:S|,_&a]uѵ4jb~xƩ:,[ = R Y?}ڼ?x,1دv&@q Sz8Xz~"j=} ~h@'hF#p?xQ-lvpxcx&lxG·0L%y?-y`l7>q2A?"F}c!jB:J +Qv=Vu[Qml%R7aIT}x ? a7 1 -Ll}0O=up"3ҶW/!|w}w^qa M8Q?0IEhaX"`a ?!Q!R~q}~O`I0 Jy|!@99>8+u&! ʰ<6Iz S)Z_POw*nm=>Jh]&@nTR6IT ^Fx73!ַa$ 5Io:ȪmY[80*x"k+\ Ho}l"k, c{Z\ Q pz}3} JXOh٥LdR`6G^^[bYRʻd}4  2,; CQĴcmV{W\xx,MRl-n~ ?#}"SҥWN;~)"S9cLj뵿ūikiX7yny} t`V's$9:{wEk c$.~k}AprѢ!`lSs90IÝw&ef"pR9g}Tl} NkUK0Up ^ȥ{Hp`bqϩ^: }' Mz+5x('C$_I?^'z~+-}*?.x^1}My¸&L7&' bqG]˪1$oR8`.q}s־C98cvSfuַ _ۺxר:גxP-/mnQG`Rq=>nr!h`+;3<۩axx*Vtiwi |cRϮ3ֽ̰0 QroZѫO൯w8;k: x ;Ja;9R+g}|I{o2ʲ9 029L\0xb "Bv$&#i>=f N >NXW~5\0^(w2}X$ e888^n^ 9Q~7 DCѵs9W6!2\:?(#'$GJW\ 0E"g;Pv Nsx"}/:t+]JM*"^Ud|0M923"6H^&1oE.7*Htp{g<+cpby=8_skB\j""[9Pb9B& =93LaaXdP.0\0?"J" "S+=@9<AQ׻աxk",J$S}xZWH"UQ ]Xg< ߨg3-qe0*R$ܒ S8}_/e'+-Ӷ[sk%x0-peCr ϒ~=a(QWd\. \F0M>grq+SNHO  ܥݭnJ|P6Kc=Is} Ga)a=#vK:oKٍ&R[sټˏ" pwqSR 9!KS&vD A9 Rq} $SnIV[]}A |k|E Mu R.Idk}yvc iUSZ&zn*j-ɭ/SH\y5 ۠"0 xnz#ԯ, eŴ'c&<ݬ<S`kâna8=ʪ[x"pN02zK8.(v2@ ~xfuyUWa|:%Q^[|o5ZY"^{96Yv*x>_|UִtM9P## z/0-įdd,:p03S{9=+ ![!#="յjHh:[{?.u_%ccA }0x9>~9,ah2 Ary$VN ]=$} #1dMax!^!Kk FN8+{Ҽo[MRoe[_m/k.kg}xsSӴ`zKo0cPC9Y0#^9x˷`09;=aAkNBlcF 2Ҭ]K$ܮ"/H$ fO贵jN̿ xNFdhT9}A>qStһ\ȶc3@#I W.<ѬaA ; q2q $# ! !}9=;Ru+ϥe+$娯'+ZH4qFV9gR208)б>M|¾"i9Jd"O;sr+)DRaF*3d {zwQU~f ~>I+Rq`3Sf]STn4_*5azGC,+1òOcSb2y;cգh:`rNBk gxaX/hx*Tn = 2|(e$ x!'y+S=Y:i -BK":ơ&v-Y=Onjyf4T P`S7={m/ ZK&GbG AS*ÿ IoINU8Rw; 1Y "E Oyto/8~#ñl2f'h?CYd:qӷeĩ RL+~A3g=aRt3 QREw_;haSir ^i!|ROmJ/$lӿ [` >cF61 z7Ldxw9AXO"hm"NT I$pG~:bWS|n>Ϣܢ"%qL^ KpNA< &==ffF!yc $=ϭY]eDH>x_TP"a0ch['7a!?wn5u|c{O1"xsZ&y32  ~AcO45-fR. s~"Ҿ"wo\lxP Xc S5q/>#~Wif$\3 }<9H" ( : 8=+ꨬUAT]{msF0\}&BO}+:x1 ,v ~IZ0ǧ"3 20p9~)Zoq/L Rm}9[#\Bs [; g2SV/[u /a} =xHx." Qxh#a$'u<`:>2>+LSiwF1!eg`S }Vv $|,szΒxD\Rm o| :{Ӷn!0l, ( RR crsa,49MOH!@ }`9w;At0&.클5,u-cKӣ̺U.L0&%2"~x [`cnH}y"keRF{(ة `J#}wg<:;M ^\yhX!vBzrF?B/s<B)۱ w5:se{mѤh]Wm4W4bC3r$ pw`dzt!y`IhM)!edRm'>?wzKcRq6fp$)wUl`ARAgr:Rg[iYs5GK=FMG ``KɦuOQ!R/G`@qzd/(K%}bM x>RRVIY~#"@8 Sgq54v[(q c!FGa? UWZ$y}zק?>"6{""}.$`US& ' r$1(y7 V<~:  Mw'bxb7g~,iF8½k/{!2S/?:$eSRIRg9czrrNObi Ѻ/$,;R vxb" nmxn}3G,.٣u r`[<!@:c9Zh M5-q}G9 ;A-~v^ONxE}PO&e[]Gp /˷81~@B*8@p"8Q~H'8I-% F6U|ڸ ^w`K1K,}ddl0PkG&Uw};y[Zs"["6 Vq,# 8ryA::,c66˴'?t}H--":|Ƭ[  7#99$,+qS\ cy^ݸa"B-9%׮9Vw~vTꢷ%" [x"2gS?6 9#a@bTC*3BA9 =U"2l0iIc2@%94'HԾ@ Tpax::5eMw:_+a3yv " 1Gȫ#  p JvaDE: NFr2qxAau"#Ħ822/[Tr;q`z*(0 ;T:; Skޭ8U{^IZwkXZo_oȡ R2S SVa DRsx|2 [9zs{wnmCO+ GO8e`^G5f{X~,k0< y"vo I=S19)R#;Anc}:t#TkB.0R-Zgum}fJ+#2P~i%S3P*YA}2r:iRUQq0H9!={~ J}Vײm.ߺiYlkgLrT" &wH6`34e &L"%clyîA0 ~$[3u"pNO=  c{rYK ~F "a"Lr1ӯ2<"C".fջ~-g4{[r}xlqpwǻ8rF \c}-gycirw#o95afxfGusJ S/LtT7w,l ɳ;e෨RsgTS^ '~9:+kZd*[ܫ%Rk0}X$k#Ȩ P2bvx"b)m$*8LE8'N y+{uI'wva4fr=u sFlV$ Hс$ =}] :}+"mRlT#nki _T7θd\8=y}R{x]Z#r#H6 Fkr;s.&;s 9HSaխtU-n | vqS{gRtS.P9}0_[;mޭZRX{+"-7!G"9~nrYXp S!ӭoP̏t (0޹s#GLanJ!T#?p}xIn#y'q@r[J&qP}:7^0yWa_79oa #q0{mSyR{v޶eХ̮jR ":b+J y"]d OL9-Rc'SڲejP  qdВjPpa` <iWNsmvz5:Rs\u