From pypy.commits at gmail.com Wed Jan 1 04:19:22 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 01 Jan 2020 01:19:22 -0800 (PST) Subject: [pypy-commit] pypy default: update license for new year, ignor pypy/lib files for portable builds Message-ID: <5e0c641a.1c69fb81.e3b44.d287@mx.google.com> Author: Matti Picus Branch: Changeset: r98431:389122234122 Date: 2020-01-01 11:17 +0200 http://bitbucket.org/pypy/pypy/changeset/389122234122/ Log: update license for new year, ignor pypy/lib files for portable builds diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -17,8 +17,8 @@ ^site-packages$ ^site-packages/.*$ ^site-packages/.*$ -^bin$ ^pypy/bin/pypy-c +^pypy/lib/ ^pypy/module/cpyext/src/.+\.o$ ^pypy/module/cpyext/src/.+\.obj$ ^pypy/module/cpyext/test/.+\.errors$ diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -59,7 +59,7 @@ # General information about the project. project = u'PyPy' -copyright = u'2019, The PyPy Project' +copyright = u'2020, The PyPy Project' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From pypy.commits at gmail.com Wed Jan 1 04:19:24 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 01 Jan 2020 01:19:24 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge default into branch Message-ID: <5e0c641c.1c69fb81.111cf.7069@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r98432:73c04f01d522 Date: 2020-01-01 11:18 +0200 http://bitbucket.org/pypy/pypy/changeset/73c04f01d522/ Log: merge default into branch diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -19,8 +19,8 @@ ^site-packages$ ^site-packages/.*$ ^site-packages/.*$ -^bin$ ^pypy/bin/pypy-c +^pypy/lib/ ^pypy/module/cpyext/src/.+\.o$ ^pypy/module/cpyext/src/.+\.obj$ ^pypy/module/cpyext/test/.+\.errors$ diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -59,7 +59,7 @@ # General information about the project. project = u'PyPy' -copyright = u'2019, The PyPy Project' +copyright = u'2020, The PyPy Project' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -253,6 +253,9 @@ assert u''.rsplit('aaa') == [u''] assert u'a\nb\u1680c'.rsplit() == [u'a', u'b', u'c'] + def test_rsplit_bug(self): + assert u'Vestur- og Mið'.rsplit() == [u'Vestur-', u'og', u'Mið'] + def test_center(self): s=u"a b" assert s.center(0) == u"a b" diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py --- a/rpython/rlib/rstring.py +++ b/rpython/rlib/rstring.py @@ -139,7 +139,7 @@ if by is None: res = [] - i = len(value) - 1 + i = _decr(value, len(value), isutf8) while True: # starting from the end, find the end of the next word while i >= 0: diff --git a/rpython/rlib/test/test_rstring.py b/rpython/rlib/test/test_rstring.py --- a/rpython/rlib/test/test_rstring.py +++ b/rpython/rlib/test/test_rstring.py @@ -88,6 +88,7 @@ assert rsplit('baba', 'a', isutf8=1) == ['b', 'b', ''] assert rsplit('b b', isutf8=1) == ['b', 'b'] assert rsplit('b\xe1\x9a\x80b', isutf8=1) == ['b', 'b'] + assert rsplit('b\xe1\x9a\x80', isutf8=1) == ['b'] def test_string_replace(): def check_replace(value, sub, *args, **kwargs): From pypy.commits at gmail.com Wed Jan 1 10:54:21 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 01 Jan 2020 07:54:21 -0800 (PST) Subject: [pypy-commit] pypy py3.6: remove repeated function Message-ID: <5e0cc0ad.1c69fb81.df8e5.a2c3@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98433:11484c9b7bd0 Date: 2020-01-01 16:52 +0100 http://bitbucket.org/pypy/pypy/changeset/11484c9b7bd0/ Log: remove repeated function diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1740,16 +1740,6 @@ def utf8_w(self, w_obj): return w_obj.utf8_w(self) - def utf8_0_w(self, w_obj): - "Like utf_w, but rejects strings with NUL bytes." - from rpython.rlib import rstring - result = w_obj.utf8_w(self) - if '\x00' in result: - raise oefmt(self.w_TypeError, - "argument must be a string without NUL " - "characters") - return rstring.assert_str0(result) - def convert_to_w_unicode(self, w_obj): return w_obj.convert_to_w_unicode(self) From pypy.commits at gmail.com Wed Jan 1 10:54:23 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 01 Jan 2020 07:54:23 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge heads Message-ID: <5e0cc0af.1c69fb81.76af.9659@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98434:1a321e4e7973 Date: 2020-01-01 16:53 +0100 http://bitbucket.org/pypy/pypy/changeset/1a321e4e7973/ Log: merge heads diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1740,16 +1740,6 @@ def utf8_w(self, w_obj): return w_obj.utf8_w(self) - def utf8_0_w(self, w_obj): - "Like utf_w, but rejects strings with NUL bytes." - from rpython.rlib import rstring - result = w_obj.utf8_w(self) - if '\x00' in result: - raise oefmt(self.w_TypeError, - "argument must be a string without NUL " - "characters") - return rstring.assert_str0(result) - def convert_to_w_unicode(self, w_obj): return w_obj.convert_to_w_unicode(self) From pypy.commits at gmail.com Wed Jan 1 11:17:34 2020 From: pypy.commits at gmail.com (arigo) Date: Wed, 01 Jan 2020 08:17:34 -0800 (PST) Subject: [pypy-commit] pypy default: Move the 'assert pos >= 0' before the 'code[pos]', to avoid extra checking for Message-ID: <5e0cc61e.1c69fb81.b0e74.9711@mx.google.com> Author: Armin Rigo Branch: Changeset: r98435:04a0915490aa Date: 2020-01-01 17:17 +0100 http://bitbucket.org/pypy/pypy/changeset/04a0915490aa/ Log: Move the 'assert pos >= 0' before the 'code[pos]', to avoid extra checking for negative pos when indexing diff --git a/rpython/rlib/rutf8.py b/rpython/rlib/rutf8.py --- a/rpython/rlib/rutf8.py +++ b/rpython/rlib/rutf8.py @@ -153,22 +153,20 @@ """Gives the position of the previous codepoint. 'pos' must not be zero. """ - assert pos != 0 pos -= 1 + assert pos >= 0 if pos >= len(code): # for the case where pos - 1 == len(code): - assert pos >= 0 return pos # assume there is an extra '\x00' character chr1 = ord(code[pos]) if chr1 <= 0x7F: - assert pos >= 0 return pos pos -= 1 + assert pos >= 0 if ord(code[pos]) >= 0xC0: - assert pos >= 0 return pos pos -= 1 + assert pos >= 0 if ord(code[pos]) >= 0xC0: - assert pos >= 0 return pos pos -= 1 assert pos >= 0 From pypy.commits at gmail.com Thu Jan 2 04:45:22 2020 From: pypy.commits at gmail.com (arigo) Date: Thu, 02 Jan 2020 01:45:22 -0800 (PST) Subject: [pypy-commit] cffi default: Issue 436: improve docs and error message Message-ID: <5e0dbbb2.1c69fb81.131a5.462b@mx.google.com> Author: Armin Rigo Branch: Changeset: r3317:b9a98b040bd7 Date: 2020-01-02 10:45 +0100 http://bitbucket.org/cffi/cffi/changeset/b9a98b040bd7/ Log: Issue 436: improve docs and error message diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -4974,8 +4974,8 @@ if (sflags & SF_STD_FIELD_POS) { PyErr_Format(FFIError, "%s: %s%s%s (cdef says %zd, but C compiler says %zd)." - " fix it or use \"...;\" in the cdef for %s to " - "make it flexible", + " fix it or use \"...;\" as the last field in the " + "cdef for %s to make it flexible", ct->ct_name, msg1, txt, msg2, cdef_value, compiler_value, ct->ct_name); diff --git a/doc/source/cdef.rst b/doc/source/cdef.rst --- a/doc/source/cdef.rst +++ b/doc/source/cdef.rst @@ -235,7 +235,12 @@ byte. (Note that the packed attribute has no effect on bit fields so far, which mean that they may be packed differently than on GCC. Also, this has no effect on structs declared with ``"...;"``---more -about it later in `Letting the C compiler fill the gaps`_.) +about it later in `Letting the C compiler fill the gaps`_. In +particular, if your C source uses other attributes like +``__attribute__((aligned(16)))``, there is no way to declare this fact +in the ``cdef()``, but you can generally just declare the struct with +``"...;"`` as the last field.) + *New in version 1.12:* In ABI mode, you can also pass ``pack=n``, with an integer ``n`` which must be a power of two. Then the alignment of any field is limited to ``n`` if it would otherwise be @@ -471,10 +476,12 @@ ``cdef()`` at various places, in order to ask the C compiler to fill in the details. These places are: -* structure declarations: any ``struct { }`` that ends with "``...;``" as - the last "field" is - partial: it may be missing fields and/or have them declared out of order. - This declaration will be corrected by the compiler. (But note that you +* structure declarations: any ``struct { }`` or ``union { }`` that ends + with "``...;``" as the last "field" is partial: it may be missing + fields, have them declared out of order, use non-standard alignment, + etc. Precisely, the field offsets, total struct size, and total + struct alignment deduced by looking at the ``cdef`` are not relied + upon and will instead be corrected by the compiler. (But note that you can only access fields that you declared, not others.) Any ``struct`` declaration which doesn't use "``...``" is assumed to be exact, but this is checked: you get an error if it is not correct. From pypy.commits at gmail.com Thu Jan 2 05:08:18 2020 From: pypy.commits at gmail.com (arigo) Date: Thu, 02 Jan 2020 02:08:18 -0800 (PST) Subject: [pypy-commit] pypy py3.6: Issue 3136: Windows: os.putenv() Message-ID: <5e0dc112.1c69fb81.42e1a.408e@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r98436:1697fc0bff5d Date: 2020-01-02 11:07 +0100 http://bitbucket.org/pypy/pypy/changeset/1697fc0bff5d/ Log: Issue 3136: Windows: os.putenv() diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -909,11 +909,20 @@ @unwrap_spec(name=unicode, value=unicode) def putenv(space, name, value): """Change or add an environment variable.""" + # Search from index 1 because on Windows starting '=' is allowed for + # defining hidden environment variables. + if len(name) == 0 or u'=' in name[1:]: + raise oefmt(space.w_ValueError, "illegal environment variable name") + # len includes space for '=' and a trailing NUL if len(name) + len(value) + 2 > rwin32._MAX_ENV: raise oefmt(space.w_ValueError, "the environment variable is longer than %d " "characters", rwin32._MAX_ENV) + + if u'\x00' in name or u'\x00' in value: + raise oefmt(space.w_ValueError, "embedded null character") + try: rwin32._wputenv(name, value) except OSError as e: diff --git a/pypy/module/posix/test/test_interp_posix.py b/pypy/module/posix/test/test_interp_posix.py --- a/pypy/module/posix/test/test_interp_posix.py +++ b/pypy/module/posix/test/test_interp_posix.py @@ -69,3 +69,9 @@ cc = os.cpu_count() assert cc is None or (isinstance(cc, int) and cc > 0) """ + + def test_putenv_invalid_name(self): + """ + import os + raises(ValueError, os.putenv, "foo=bar", "xxx") + """ From pypy.commits at gmail.com Thu Jan 2 05:27:33 2020 From: pypy.commits at gmail.com (mattip) Date: Thu, 02 Jan 2020 02:27:33 -0800 (PST) Subject: [pypy-commit] benchmarks default: add a TODO with possible benchmark candidates Message-ID: <5e0dc595.1c69fb81.8707.ccc9@mx.google.com> Author: Matti Picus Branch: Changeset: r391:88a67ec6f3c4 Date: 2020-01-02 12:26 +0200 http://bitbucket.org/pypy/benchmarks/changeset/88a67ec6f3c4/ Log: add a TODO with possible benchmark candidates diff --git a/TODO b/TODO new file mode 100644 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +Possible benchmarks to explore: +- Web-site frameworks https://github.com/klen/py-frameworks-bench +- Exploration of django https://lincolnloop.com/blog/faster-django-sites-pypy/ +- black From pypy.commits at gmail.com Thu Jan 2 05:29:13 2020 From: pypy.commits at gmail.com (arigo) Date: Thu, 02 Jan 2020 02:29:13 -0800 (PST) Subject: [pypy-commit] pypy py3.7-bpo-27541: Close branch py3.7-bpo-27541 Message-ID: <5e0dc5f9.1c69fb81.80802.3d3d@mx.google.com> Author: Armin Rigo Branch: py3.7-bpo-27541 Changeset: r98437:ba114d9875d7 Date: 2020-01-02 10:28 +0000 http://bitbucket.org/pypy/pypy/changeset/ba114d9875d7/ Log: Close branch py3.7-bpo-27541 From pypy.commits at gmail.com Thu Jan 2 05:29:42 2020 From: pypy.commits at gmail.com (arigo) Date: Thu, 02 Jan 2020 02:29:42 -0800 (PST) Subject: [pypy-commit] pypy py3.7: Merged in py3.7-bpo-27541 (pull request #692) Message-ID: <5e0dc616.1c69fb81.a02e0.47c9@mx.google.com> Author: Armin Rigo Branch: py3.7 Changeset: r98438:c509e0d987c3 Date: 2020-01-02 10:28 +0000 http://bitbucket.org/pypy/pypy/changeset/c509e0d987c3/ Log: Merged in py3.7-bpo-27541 (pull request #692) Implement bpo-27541: Reprs of subclasses of some classes now contain actual type name diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py --- a/lib_pypy/_collections.py +++ b/lib_pypy/_collections.py @@ -211,14 +211,14 @@ def __repr__(self): threadlocalattr = '__repr' + str(_thread_ident()) if threadlocalattr in self.__dict__: - return 'deque([...])' + return '%s([...])' % (self.__class__.__name__,) else: self.__dict__[threadlocalattr] = True try: if self.maxlen is not None: - return 'deque(%r, maxlen=%s)' % (list(self), self.maxlen) + return '%s(%r, maxlen=%s)' % (self.__class__.__name__, list(self), self.maxlen) else: - return 'deque(%r)' % (list(self),) + return '%s(%r)' % (self.__class__.__name__, list(self)) finally: del self.__dict__[threadlocalattr] @@ -411,10 +411,10 @@ def __repr__(self, recurse=set()): if id(self) in recurse: - return "defaultdict(...)" + return "%s(...)" % (self.__class__.__name__,) try: recurse.add(id(self)) - return "defaultdict(%s, %s)" % (repr(self.default_factory), super(defaultdict, self).__repr__()) + return "%s(%s, %s)" % (self.__class__.__name__, repr(self.default_factory), super(defaultdict, self).__repr__()) finally: recurse.remove(id(self)) diff --git a/pypy/module/_collections/app_defaultdict.py b/pypy/module/_collections/app_defaultdict.py --- a/pypy/module/_collections/app_defaultdict.py +++ b/pypy/module/_collections/app_defaultdict.py @@ -40,7 +40,7 @@ factoryrepr = repr(self.default_factory) finally: recurse.remove(id(self)) - return "defaultdict(%s, %s)" % (factoryrepr, dictrepr) + return "%s(%s, %s)" % (self.__class__.__name__, factoryrepr, dictrepr) def copy(self): return type(self)(self.default_factory, self) diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py --- a/pypy/module/_collections/interp_deque.py +++ b/pypy/module/_collections/interp_deque.py @@ -536,7 +536,7 @@ maxlenrepr = '' else: maxlenrepr = ', maxlen=%d' % (d.maxlen,) - return 'deque(%s%s)' % (listrepr, maxlenrepr) + return '%s(%s%s)' % (d.__class__.__name__, listrepr, maxlenrepr) """, filename=__file__) dequerepr = app.interphook("dequerepr") diff --git a/pypy/module/_collections/test/test_defaultdict.py b/pypy/module/_collections/test/test_defaultdict.py --- a/pypy/module/_collections/test/test_defaultdict.py +++ b/pypy/module/_collections/test/test_defaultdict.py @@ -98,4 +98,10 @@ pass d = X.__new__(X) d.__init__(d.mydefault) - assert repr(d).endswith('defaultdict(..., {})>, {})') + assert repr(d).endswith('X(..., {})>, {})') + + def test_subclass_repr(self): + import _collections + class subclass(_collections.defaultdict): + pass + assert repr(subclass()) == 'subclass(None, {})' diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py --- a/pypy/module/_collections/test/test_deque.py +++ b/pypy/module/_collections/test/test_deque.py @@ -448,3 +448,9 @@ elements = 'ABCDEFGHI' d = deque([-2, -1, 0, 0, 1, 2]) assert d.index(0, -4*sys.maxsize, 4*sys.maxsize) == 2 + + def test_subclass_repr(self): + from _collections import deque + class subclass(deque): + pass + assert repr(subclass()) == 'subclass([])' diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -766,8 +766,9 @@ # Misc methods def descr_repr(self, space): + cls_name = space.type(self).getname(space) if self.len == 0: - return space.newtext("array('%s')" % self.typecode) + return space.newtext("%s('%s')" % (cls_name, self.typecode)) elif self.typecode == "u": try: w_unicode = self.descr_tounicode(space) @@ -778,11 +779,11 @@ r = "<%s>" % (space.text_w(w_exc_value),) else: r = space.text_w(space.repr(w_unicode)) - s = "array('%s', %s)" % (self.typecode, r) + s = "%s('%s', %s)" % (cls_name, self.typecode, r) return space.newtext(s) else: r = space.repr(self.descr_tolist(space)) - s = "array('%s', %s)" % (self.typecode, space.text_w(r)) + s = "%s('%s', %s)" % (cls_name, self.typecode, space.text_w(r)) return space.newtext(s) def check_valid_unicode(self, space, s): diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py --- a/pypy/module/array/test/test_array.py +++ b/pypy/module/array/test/test_array.py @@ -876,25 +876,25 @@ def extend(self, lst): self.append(10) - assert repr(mya('u', 'hi')) == "array('u', 'hi')" - assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" - assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" + assert repr(mya('u', 'hi')) == "mya('u', 'hi')" + assert repr(mya('i', [1, 2, 3])) == "mya('i', [1, 2, 3])" + assert repr(mya('i', (1, 2, 3))) == "mya('i', [1, 2, 3])" a = mya('i') a.fromlist([1, 2, 3]) - assert repr(a) == "array('i', [7])" + assert repr(a) == "mya('i', [7])" a = mya('b') a.fromstring(b'hi') - assert repr(a) == "array('b', [8])" + assert repr(a) == "mya('b', [8])" a = mya('u') a.fromunicode('hi') - assert repr(a) == "array('u', '9')" + assert repr(a) == "mya('u', '9')" a = mya('i') a.extend([1, 2, 3]) - assert repr(a) == "array('i', [10])" + assert repr(a) == "mya('i', [10])" def test_override_to(self): class mya(self.array): @@ -911,9 +911,9 @@ assert mya('u', 'hi').tobytes() == 'str' assert mya('u', 'hi').tounicode() == 'unicode' - assert repr(mya('u', 'hi')) == "array('u', 'hi')" - assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" - assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" + assert repr(mya('u', 'hi')) == "mya('u', 'hi')" + assert repr(mya('i', [1, 2, 3])) == "mya('i', [1, 2, 3])" + assert repr(mya('i', (1, 2, 3))) == "mya('i', [1, 2, 3])" def test_unicode_outofrange(self): input_unicode = u'\x01\u263a\x00\ufeff' @@ -1123,6 +1123,12 @@ struct.pack_into('>H', view, 1, 0x1234) assert a.tobytes() == b'ab\x12\x34ef' + def test_subclass_repr(self): + import array + class subclass(self.array): + pass + assert repr(subclass('i')) == "subclass('i')" + class AppTestArrayReconstructor: spaceconfig = dict(usemodules=('array', 'struct')) diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -27,12 +27,13 @@ def repr_w(self): space = self.space + cls_name = space.type(self).getname(space) c = space.text_w(space.repr(self.w_c)) if self.single_argument(): - s = 'count(%s)' % (c,) + s = '%s(%s)' % (cls_name, c) else: step = space.text_w(space.repr(self.w_step)) - s = 'count(%s, %s)' % (c, step) + s = '%s(%s, %s)' % (cls_name, c, step) return self.space.newtext(s) def reduce_w(self): @@ -107,11 +108,13 @@ return self.space.newint(self.count) def repr_w(self): - objrepr = self.space.text_w(self.space.repr(self.w_obj)) + space = self.space + cls_name = space.type(self).getname(space) + objrepr = self.space.text_w(space.repr(self.w_obj)) if self.counting: - s = 'repeat(%s, %d)' % (objrepr, self.count) + s = '%s(%s, %d)' % (cls_name, objrepr, self.count) else: - s = 'repeat(%s)' % (objrepr,) + s = '%s(%s)' % (cls_name, objrepr) return self.space.newtext(s) def descr_reduce(self): diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -36,6 +36,12 @@ raises(TypeError, itertools.count, 'a') raises(TypeError, itertools.count, []) + def test_count_subclass_repr(self): + import itertools + class subclass(itertools.count): + pass + assert repr(subclass(123)) == 'subclass(123)' + def test_repeat(self): import itertools @@ -99,6 +105,12 @@ r = itertools.repeat('a', -3) assert operator.length_hint(r, 3) == 0 + def test_repeat_subclass_repr(self): + import itertools + class subclass(itertools.repeat): + pass + assert repr(subclass('foobar')) == "subclass('foobar')" + def test_takewhile(self): import itertools diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -222,11 +222,13 @@ def descr_repr(self, space): s, start, end, _ = self._convert_idx_params(space, None, None) + cls_name = space.type(self).getname(space) # Good default if there are no replacements. - buf = StringBuilder(len("bytearray(b'')") + (end - start)) + buf = StringBuilder(len(cls_name) + len("(b'')") + (end - start)) - buf.append("bytearray(b") + buf.append(cls_name) + buf.append("(b") quote = "'" for i in range(start, end): c = s[i] diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -764,3 +764,8 @@ assert x.find(b'fe') == -1 assert x.index(b'f', 2, 11) == 5 assert x.__alloc__() == 14 + + def test_subclass_repr(self): + class subclass(bytearray): + pass + assert repr(subclass(b'test')) == "subclass(b'test')" From pypy.commits at gmail.com Thu Jan 2 08:19:34 2020 From: pypy.commits at gmail.com (mattip) Date: Thu, 02 Jan 2020 05:19:34 -0800 (PST) Subject: [pypy-commit] benchmarks chameleon: remove files Message-ID: <5e0dede6.1c69fb81.247bc.f575@mx.google.com> Author: Matti Picus Branch: chameleon Changeset: r392:0df6fffec28d Date: 2020-01-01 07:55 +0200 http://bitbucket.org/pypy/benchmarks/changeset/0df6fffec28d/ Log: remove files diff too long, truncating to 2000 out of 2819 lines diff --git a/lib/chameleon/.git/HEAD b/lib/chameleon/.git/HEAD deleted file mode 100644 --- a/lib/chameleon/.git/HEAD +++ /dev/null @@ -1,1 +0,0 @@ -ref: refs/heads/master diff --git a/lib/chameleon/.git/config b/lib/chameleon/.git/config deleted file mode 100644 --- a/lib/chameleon/.git/config +++ /dev/null @@ -1,11 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true -[remote "origin"] - url = https://github.com/malthe/chameleon.git - fetch = +refs/heads/*:refs/remotes/origin/* -[branch "master"] - remote = origin - merge = refs/heads/master diff --git a/lib/chameleon/.git/description b/lib/chameleon/.git/description deleted file mode 100644 --- a/lib/chameleon/.git/description +++ /dev/null @@ -1,1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/lib/chameleon/.git/hooks/applypatch-msg.sample b/lib/chameleon/.git/hooks/applypatch-msg.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -commitmsg="$(git rev-parse --git-path hooks/commit-msg)" -test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} -: diff --git a/lib/chameleon/.git/hooks/commit-msg.sample b/lib/chameleon/.git/hooks/commit-msg.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/lib/chameleon/.git/hooks/fsmonitor-watchman.sample b/lib/chameleon/.git/hooks/fsmonitor-watchman.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/fsmonitor-watchman.sample +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use IPC::Open2; - -# An example hook script to integrate Watchman -# (https://facebook.github.io/watchman/) with git to speed up detecting -# new and modified files. -# -# The hook is passed a version (currently 1) and a time in nanoseconds -# formatted as a string and outputs to stdout all files that have been -# modified since the given time. Paths must be relative to the root of -# the working tree and separated by a single NUL. -# -# To enable this hook, rename this file to "query-watchman" and set -# 'git config core.fsmonitor .git/hooks/query-watchman' -# -my ($version, $time) = @ARGV; - -# Check the hook interface version - -if ($version == 1) { - # convert nanoseconds to seconds - $time = int $time / 1000000000; -} else { - die "Unsupported query-fsmonitor hook version '$version'.\n" . - "Falling back to scanning...\n"; -} - -my $git_work_tree; -if ($^O =~ 'msys' || $^O =~ 'cygwin') { - $git_work_tree = Win32::GetCwd(); - $git_work_tree =~ tr/\\/\//; -} else { - require Cwd; - $git_work_tree = Cwd::cwd(); -} - -my $retry = 1; - -launch_watchman(); - -sub launch_watchman { - - my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') - or die "open2() failed: $!\n" . - "Falling back to scanning...\n"; - - # In the query expression below we're asking for names of files that - # changed since $time but were not transient (ie created after - # $time but no longer exist). - # - # To accomplish this, we're using the "since" generator to use the - # recency index to select candidate nodes and "fields" to limit the - # output to file names only. Then we're using the "expression" term to - # further constrain the results. - # - # The category of transient files that we want to ignore will have a - # creation clock (cclock) newer than $time_t value and will also not - # currently exist. - - my $query = <<" END"; - ["query", "$git_work_tree", { - "since": $time, - "fields": ["name"], - "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] - }] - END - - print CHLD_IN $query; - close CHLD_IN; - my $response = do {local $/; }; - - die "Watchman: command returned no output.\n" . - "Falling back to scanning...\n" if $response eq ""; - die "Watchman: command returned invalid output: $response\n" . - "Falling back to scanning...\n" unless $response =~ /^\{/; - - my $json_pkg; - eval { - require JSON::XS; - $json_pkg = "JSON::XS"; - 1; - } or do { - require JSON::PP; - $json_pkg = "JSON::PP"; - }; - - my $o = $json_pkg->new->utf8->decode($response); - - if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) { - print STDERR "Adding '$git_work_tree' to watchman's watch list.\n"; - $retry--; - qx/watchman watch "$git_work_tree"/; - die "Failed to make watchman watch '$git_work_tree'.\n" . - "Falling back to scanning...\n" if $? != 0; - - # Watchman will always return all files on the first query so - # return the fast "everything is dirty" flag to git and do the - # Watchman query just to get it over with now so we won't pay - # the cost in git to look up each individual file. - print "/\0"; - eval { launch_watchman() }; - exit 0; - } - - die "Watchman: $o->{error}.\n" . - "Falling back to scanning...\n" if $o->{error}; - - binmode STDOUT, ":utf8"; - local $, = "\0"; - print @{$o->{files}}; -} diff --git a/lib/chameleon/.git/hooks/post-update.sample b/lib/chameleon/.git/hooks/post-update.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/lib/chameleon/.git/hooks/pre-applypatch.sample b/lib/chameleon/.git/hooks/pre-applypatch.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -precommit="$(git rev-parse --git-path hooks/pre-commit)" -test -x "$precommit" && exec "$precommit" ${1+"$@"} -: diff --git a/lib/chameleon/.git/hooks/pre-commit.sample b/lib/chameleon/.git/hooks/pre-commit.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/pre-commit.sample +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ASCII filenames set this variable to true. -allownonascii=$(git config --bool hooks.allownonascii) - -# Redirect output to stderr. -exec 1>&2 - -# Cross platform projects tend to avoid non-ASCII filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 -then - cat <<\EOF -Error: Attempt to add a non-ASCII file name. - -This can cause problems if you want to work with people on other platforms. - -To be portable it is advisable to rename the file. - -If you know what you are doing you can disable this check using: - - git config hooks.allownonascii true -EOF - exit 1 -fi - -# If there are whitespace errors, print the offending file names and fail. -exec git diff-index --check --cached $against -- diff --git a/lib/chameleon/.git/hooks/pre-push.sample b/lib/chameleon/.git/hooks/pre-push.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/pre-push.sample +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# An example hook script to verify what is about to be pushed. Called by "git -# push" after it has checked the remote status, but before anything has been -# pushed. If this script exits with a non-zero status nothing will be pushed. -# -# This hook is called with the following parameters: -# -# $1 -- Name of the remote to which the push is being done -# $2 -- URL to which the push is being done -# -# If pushing without using a named remote those arguments will be equal. -# -# Information about the commits which are being pushed is supplied as lines to -# the standard input in the form: -# -# -# -# This sample shows how to prevent push of commits where the log message starts -# with "WIP" (work in progress). - -remote="$1" -url="$2" - -z40=0000000000000000000000000000000000000000 - -while read local_ref local_sha remote_ref remote_sha -do - if [ "$local_sha" = $z40 ] - then - # Handle delete - : - else - if [ "$remote_sha" = $z40 ] - then - # New branch, examine all commits - range="$local_sha" - else - # Update to existing branch, examine new commits - range="$remote_sha..$local_sha" - fi - - # Check for WIP commit - commit=`git rev-list -n 1 --grep '^WIP' "$range"` - if [ -n "$commit" ] - then - echo >&2 "Found WIP commit in $local_ref, not pushing" - exit 1 - fi - fi -done - -exit 0 diff --git a/lib/chameleon/.git/hooks/pre-rebase.sample b/lib/chameleon/.git/hooks/pre-rebase.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up to date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -<<\DOC_END - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". - -DOC_END diff --git a/lib/chameleon/.git/hooks/pre-receive.sample b/lib/chameleon/.git/hooks/pre-receive.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/pre-receive.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to make use of push options. -# The example simply echoes all push options that start with 'echoback=' -# and rejects all pushes when the "reject" push option is used. -# -# To enable this hook, rename this file to "pre-receive". - -if test -n "$GIT_PUSH_OPTION_COUNT" -then - i=0 - while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" - do - eval "value=\$GIT_PUSH_OPTION_$i" - case "$value" in - echoback=*) - echo "echo from the pre-receive-hook: ${value#*=}" >&2 - ;; - reject) - exit 1 - esac - i=$((i + 1)) - done -fi diff --git a/lib/chameleon/.git/hooks/prepare-commit-msg.sample b/lib/chameleon/.git/hooks/prepare-commit-msg.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first one removes the -# "# Please enter the commit message..." help message. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -COMMIT_MSG_FILE=$1 -COMMIT_SOURCE=$2 -SHA1=$3 - -/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" - -# case "$COMMIT_SOURCE,$SHA1" in -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; -# *) ;; -# esac - -# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" -# if test -z "$COMMIT_SOURCE" -# then -# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" -# fi diff --git a/lib/chameleon/.git/hooks/update.sample b/lib/chameleon/.git/hooks/update.sample deleted file mode 100755 --- a/lib/chameleon/.git/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to block unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/lib/chameleon/.git/index b/lib/chameleon/.git/index deleted file mode 100644 index b5bf8295eb5fd92d033d4c208691b21945fbb726..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch [cut] diff --git a/lib/chameleon/.git/info/exclude b/lib/chameleon/.git/info/exclude deleted file mode 100644 --- a/lib/chameleon/.git/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/lib/chameleon/.git/logs/HEAD b/lib/chameleon/.git/logs/HEAD deleted file mode 100644 --- a/lib/chameleon/.git/logs/HEAD +++ /dev/null @@ -1,1 +0,0 @@ -0000000000000000000000000000000000000000 559ab649c979fa77467982b5feb254b665f92950 mattip 1577804602 +0200 clone: from https://github.com/malthe/chameleon.git diff --git a/lib/chameleon/.git/logs/refs/heads/master b/lib/chameleon/.git/logs/refs/heads/master deleted file mode 100644 --- a/lib/chameleon/.git/logs/refs/heads/master +++ /dev/null @@ -1,1 +0,0 @@ -0000000000000000000000000000000000000000 559ab649c979fa77467982b5feb254b665f92950 mattip 1577804602 +0200 clone: from https://github.com/malthe/chameleon.git diff --git a/lib/chameleon/.git/logs/refs/remotes/origin/HEAD b/lib/chameleon/.git/logs/refs/remotes/origin/HEAD deleted file mode 100644 --- a/lib/chameleon/.git/logs/refs/remotes/origin/HEAD +++ /dev/null @@ -1,1 +0,0 @@ -0000000000000000000000000000000000000000 559ab649c979fa77467982b5feb254b665f92950 mattip 1577804602 +0200 clone: from https://github.com/malthe/chameleon.git diff --git a/lib/chameleon/.git/objects/pack/pack-3a33d60ede72fabfdc2df4a039559e5f5740948c.idx b/lib/chameleon/.git/objects/pack/pack-3a33d60ede72fabfdc2df4a039559e5f5740948c.idx deleted file mode 100644 index 1a05e34e4585a9277314274e95ec73ecc917f56e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch [cut] diff --git a/lib/chameleon/.git/objects/pack/pack-3a33d60ede72fabfdc2df4a039559e5f5740948c.pack b/lib/chameleon/.git/objects/pack/pack-3a33d60ede72fabfdc2df4a039559e5f5740948c.pack deleted file mode 100644 index 8a18da6ea0db9d7801f12d265d6eb77638db72b5..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch [cut] diff --git a/lib/chameleon/.git/packed-refs b/lib/chameleon/.git/packed-refs deleted file mode 100644 --- a/lib/chameleon/.git/packed-refs +++ /dev/null @@ -1,169 +0,0 @@ -# pack-refs with: peeled fully-peeled sorted -95c31f9ac136722f5ba0e16a6104e5180bd75fe4 refs/remotes/origin/1.3 -838fab8085ff4e4f741c27dec3c153b84f392bd9 refs/remotes/origin/allow-html5-data-attribute-as-contrl-prefix -aaaac4ee2aa20697740e26f9111490576f299ea0 refs/remotes/origin/fix-dollar-escape-at-end-of-string -559ab649c979fa77467982b5feb254b665f92950 refs/remotes/origin/master -9e299f4b4af7e38c3b0d4cec081d3f7adcf0bc66 refs/tags/2.0 -^440246a268791d8260bf95a630f194bc25bd2b20 -cd097e38679c0f872f3564803f81538480ea94aa refs/tags/2.0-rc1 -^f8626f626b5fc65cc8b2c3aff6b4bb940ad91a5f -4bfda45916d94ac665d96a027b3108fc6b7a1ac7 refs/tags/2.0-rc10 -^a21f6bde03d0a4a79dd8ac1b2a7ae05a3fe21e08 -313ab83b406fab82f796d72bc7814a5859bf7af7 refs/tags/2.0-rc11 -^1a91be02e4c9aa435c51da72f7874a6e24051617 -fb8c2fad2e62002904bf80f038fd1311abe6d54a refs/tags/2.0-rc12 -^f956817fa4a060ea694562fc8cdbfeb40eae04c5 -a40685bee1ad15d7aa8275da47ed6886fb098fe3 refs/tags/2.0-rc13 -^bc8d121c941fea419465941fef6805899e6861a4 -60004328a6e1d17927a00e346646205eb881e729 refs/tags/2.0-rc14 -^9fbb2ab5a923ad27bcad6b445575c2d018402862 -9668391f2e4e699d838f7ccd5aa804b113102445 refs/tags/2.0-rc2 -^3737f9850741531056c460d8acf572e8f035c833 -98f0791d11cadd3e423d45d6d65d15e100dcaa9f refs/tags/2.0-rc3 -^9c8adee93480a77f063a2a8afb1c7317e6a76a96 -b487d7277abf0b0fb0fad0514f7b64d1820f5486 refs/tags/2.0-rc4 -^27c33b96788a28190348191eead1a1fa7c9c17d9 -0c2d2709f2247d1424045014af61033f85f533c7 refs/tags/2.0-rc5 -^bdc4389ef54d34b9705345f46d28100fe27ec14d -713f3673fb605449b06f12f08f03893f1f9ec405 refs/tags/2.0-rc6 -^d120c5ed56e1e5f13b0b9a2ed5c42c2e0d6328f7 -913f2ee0a1c0b18e7c1381038266dfd0428a705a refs/tags/2.0-rc7 -^d03f4762259074bc50c138a8b4d26092f2285d9c -57f261ec57b9175491e2a8c4764c3c6d261a5c6e refs/tags/2.0-rc8 -^050c0c6335c0e07b9bfa3a6804effd7a6b6deb03 -a30c384497d00ab35a39a5d35f8b99487cc1ec94 refs/tags/2.0-rc9 -^4afe30ade113ad3b06a9ce6990469f00cf6e954a -116463e81292bd9df39a0452057188778d5d293b refs/tags/2.0.1 -^ab254f3a4b0bc4af6e180c276bd8b6e337db61c9 -8ee930bdbaa939da061719ccdfa13a3f46e36807 refs/tags/2.0.2 -^9c5bb7476c9225f95cc5ab5f6ebaf000926977ec -5d1821b82d086842ded6ba920a9ce9103d3b4777 refs/tags/2.1 -^b17b2dc1164564f5dc4d910ba9d82d8bd619d252 -0eed0c29636ad4e718f4e4ec56b669205fca1070 refs/tags/2.1.1 -^164898adb18b97fbfcb29b8c507d0233828f3181 -269ff35b2aa02f6d9dda6faae9eab7ccc2574f76 refs/tags/2.10 -^bf798ce808f618a1e0a337dbf0eba71e4d240104 -8f38725b65c99821d20c6336da8b692a9b6163ad refs/tags/2.11 -^b3d50ac45ef36b12aaa3e14083ee60a2dc2301db -ce7de4938759d847ac0ec208123941e16728e838 refs/tags/2.12 -^6d3ab682e9177cb14326806f4d7454dae3b55606 -e8472645d1be24d4e9a7a7a86826dfb4b212badc refs/tags/2.13 -^3355057b70021afc454cc2317f7db5f1b2347e3b -d2f66bddee3d7cb7c9fb002d2a811178eb79f5b2 refs/tags/2.13-1 -^b6c2a243d85eacfd4daca692142d5068a7dcf35b -0f753f1df3b3164ecc5c81e65f244ed5724dfd95 refs/tags/2.14 -^b2747539e76e5e35c2c5d2c5dfceb9abd2713817 -c54597c5a409199be6ec1bf63f186eeefbc03b30 refs/tags/2.15 -^3ae95a3d6d00dfa91e9789f840b7968293db711a -b11abb37d2760a4024f91d3b3973106a251fd60f refs/tags/2.16 -^7652686e721b8439be2b3d1357905cb09da203bf -a67ed8cf70c5e77c5b17d6cd37cf616ee92e571f refs/tags/2.17 -^64dc123da27d2c93c2f332ee66563190356a78c3 -4bb69fd43d046f903d522f319404ea7c2ce4c6fd refs/tags/2.18 -^da76c633c8236fba4010e1aabde3bf812ac5417f -44289cfe93890e903e2a3ed023474106603b6a1b refs/tags/2.19 -^91d356b25be0875fa2b72278a8a7a2c237280f0c -5f2e933460d8e7eb0249b860c1f21d4f75db9570 refs/tags/2.2 -^a1c159cb28fcecd89f865eecd411343fd3198923 -55fa99c883bf82ffb505a41eb32616d3f6018aed refs/tags/2.20 -^2473195f4f5326d6349bc64a9aaa46003f343cc3 -00c9f050ca19fd2ecbd366669ae134a910a6d24d refs/tags/2.21 -^8fdcd55dca30ddfbd0bb16b7636be93d0ad40861 -04a6e480598cfe5a6faa1109c7802ce2e7c0be5d refs/tags/2.22 -^07b1566d1eab0c333727a0371f66da0f875c25d2 -eadedf132ef90d984f4da5e83ed08509ffa2d475 refs/tags/2.23 -^65ad56d82c0716a59987475125bdaa676478d3fb -6a231e14c07ea5232d975b47c9d06fbc6df44e20 refs/tags/2.24 -^7326b8a13393a89ab8a6428f57e0d67bd6bc3e9b -f211ce07a4d1c18946a4f5b241708d6089438377 refs/tags/2.25 -^c1f4159d28dd00e08c0e1217c39ec9f01c1a1776 -d6cbcb6b739901a48b5c8a9c9ce8802c9425709d refs/tags/2.3 -^84016ef8323c4ce03517f24771b4c08466d53e40 -dcc96e9b0a02d6e4f67bc4a76ab273df569633e1 refs/tags/2.3.1 -^89b009f925c68f84a0ff62360c371b7d7bd869a1 -922804fdea269b7ed1879d0f908d356163485c28 refs/tags/2.3.2 -^11783a217dd322ab8c023cec192104d23cf634fa -006aa646b13f6bc663acf50d7bbca5709af23de9 refs/tags/2.3.3 -^f445d340f41dc2069034fa0fccbe1ecbff382631 -2a985fcb595964c791198e9b3217fba0976402dd refs/tags/2.3.4 -^607bee18c06b7e7898a8181fd3578d4fe3e89fab -650c0f8f879e97480515c8f6551e45d7a5199b51 refs/tags/2.3.5 -^9b087438795473ddabf878e84b67945a99d0f714 -2da784b626bc196da4b1c445683bfaccd9e7a942 refs/tags/2.3.6 -^af6684237baee47c3cc760d99fba3c3a4726e713 -f701ff06c05925a6076a1271bb8f16d4e7eafaa5 refs/tags/2.3.7 -^702184ea0ea4c986100c2381497e90c67d881710 -c0e625d8f65644e9bdf124bda3d8960bb84e75cc refs/tags/2.3.8 -^f007a40a77d41e952965c68fd97d3f992f1c653b -a072aa7578816583a799f59444a1eccc08e63159 refs/tags/2.4.0 -^789548751193158bd13b089053fa73afc6c5e487 -5fe744a6df9ac5b8cd6326059021232f738c78bc refs/tags/2.4.1 -^1d73a1d47c97b38e13380c8dcc2f57d55939fab0 -7856dee6dee2e462b53833388d49638de88b4960 refs/tags/2.4.2 -^943d4c61fb21c4fa48dd760fe9ff5eac6266a147 -0112d33d4a5593057fd94ee59b4050b31534a143 refs/tags/2.4.3 -^3c86ee1e6752c308a346bec17588f2fbb26251b9 -42ac6bd0f92c04d608dc5b8f86ec99672374ffc7 refs/tags/2.4.4 -^1ecbc7f6c30a0b29e1bcd6a48a985683922305d3 -ba9c751b3eee765ea4359c6ad1a75be98e2bac1d refs/tags/2.4.5 -^98363a1db489b11b4ec33dec61fe75fa478c6122 -4d87f43af187bbd4bfa0fb1bdd801145a23a3628 refs/tags/2.4.6 -^55b5fe905ea07694acd15c309cebd78dd2ddba41 -8500d255f022736710f9b7588caad3bc163d22d3 refs/tags/2.5.0 -^58fb4f80d3bac730ae3c664bdf83dcbad497445e -1a29ad86573fc95e2dbf2e23df75fb7259517558 refs/tags/2.5.1 -^619bf1fea11f61d0126d261fb53b1a121302ff46 -9abbf0c285ee9667ad66ca6472fb23be0634ca2e refs/tags/2.5.2 -^9af921665e9f8e2276c132728742a6c504ecd6ca -4c8a633bd10857e4db104a58b2c42e434b9243a4 refs/tags/2.5.3 -^8eca09d543f43c5edb41c5c25e6cd9bbe93992ed -c40073ae6924fd2fecbdcd092e914ba7bea09473 refs/tags/2.6.0 -^3386c26a4d9169815ad19b4cbe7fb04e6d3fd554 -911df611ac669112a462e52b33ed2f3eef07f383 refs/tags/2.6.1 -^bf34fd136237c5d724093758e9b418e61c47f806 -e9d6d40f7d70fea8d28aac339c4f97ea2f09ab90 refs/tags/2.6.2 -^dd6415f33a2efc62c8f1860740606d60d2d0f7ef -408074c6fc6c7df06499bb11a9f1735f54a48192 refs/tags/2.7.0 -^73723372a5a25c466425328a28a2cceb11e6104b -6995b1438841847d95bd616bdd533cdaa99a533e refs/tags/2.7.1 -^7074855da37eaedf4523b561d8373cefbf8e1270 -96c87855a70e0f01fa65c3ddaa83a3aadb77bf03 refs/tags/2.7.2 -^7147545d9d867522b6ad1580d6ecfb3f0d68c8f0 -608b6095732c0553ab607cbcd5d2289810aea4e7 refs/tags/2.7.3 -^e5a386587cbbe83e1f9a18130b0da9998774a244 -77a54c30688ec7157deef6dab2587d9056cf5ea1 refs/tags/2.7.4 -^631e3131a94468436dc8f581a068ece46e119be5 -c90af00b69cd9420da70360f8dfe85a8b55780b6 refs/tags/2.8.0 -^0d5e6ee1d24314d369cb952d814b9e7dfcdde40f -66905936b0435a1f14af92a513c700dc33e9af82 refs/tags/2.8.1 -^0c2a4497c7da50efcb54963c18492c8057ee9748 -e61b693773b2184435eea6c0636c022e792fc08d refs/tags/2.8.2 -^d3cb822dcf0983a55c9edcf547e72bf698a8e63b -a937d7e7230803804ec9fbda87751864c166585b refs/tags/2.8.3 -^26d5ac892a141c238f87c8e71b455e0e1d529d19 -51ae8757aee1dc54bab1ce985911837332c4019e refs/tags/2.8.4 -^f625708f40a1b0f7ab8fed561cc5a68090065645 -9f80e9a9133d61863fce9df7df4357fd8b9ab772 refs/tags/2.8.5 -^58ef63dfbd4d1b1fc874f10e16a7f30c2fe63555 -b22aee05cc2b9567cb1fac82c1f8dedb27a61a98 refs/tags/2.9.0 -^76bebbb82a8eb002c80143bfaa2ac57a0f2c388b -a76fd09520f58b5ca43d905b17548f55ea36dca7 refs/tags/2.9.1 -^bbfce8555f4af8c0e220efcc66805f66e10ff544 -659e060549b56a8d10d5e4230e550a875ba70ffa refs/tags/2.9.2 -^fe730e478b0f87e90bc38c2de9270849fda9c384 -f28a4ee980fb409d710104bb1d28ea26ecf1ca23 refs/tags/3.0 -^c47ea64b8e167050d017c913d4d4a28916d4ad8d -3a317c05505b9541362441d73dae6b9f50f59d92 refs/tags/3.1 -^12b3b6a44fa8a5b49ad0d63e0f21e59c75789a37 -24c360de8005e8b626a797689a5d42463c3730e3 refs/tags/3.2 -^78628c5027430c8d7d437845588bcc02aacfd1fc -98374bb6b982f53051975c02ae56dad048004914 refs/tags/3.3 -ebebf78e3feced96168ea927f08e908a838eb580 refs/tags/3.4 -eddaa33ac0428ae81bd9b163bed02f79a3a78116 refs/tags/3.5 -^9c1d8003f5409d4de6bf6d38446491383c6f2d5f -87a6dc321695c314bacdadc308a7f09d5c0898cc refs/tags/3.6 -^7da66acfa1b8a3479e800747f3f8ad6e469d24f9 -f91105a48715b8fffefc01cf632a4daad4c50b36 refs/tags/3.6.1 -^6d515df8e03051268df2cb635d415fa5b7f012c2 -aa9d5d1cd20ededeeae963532fe7bf5a03256517 refs/tags/3.6.2 -^f540da3de0033c0dac9853668ea193c333db49ac diff --git a/lib/chameleon/.git/refs/heads/master b/lib/chameleon/.git/refs/heads/master deleted file mode 100644 --- a/lib/chameleon/.git/refs/heads/master +++ /dev/null @@ -1,1 +0,0 @@ -559ab649c979fa77467982b5feb254b665f92950 diff --git a/lib/chameleon/.git/refs/remotes/origin/HEAD b/lib/chameleon/.git/refs/remotes/origin/HEAD deleted file mode 100644 --- a/lib/chameleon/.git/refs/remotes/origin/HEAD +++ /dev/null @@ -1,1 +0,0 @@ -ref: refs/remotes/origin/master diff --git a/lib/chameleon/src/chameleon/tests/outputs/001.html b/lib/chameleon/src/chameleon/tests/outputs/001.html deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/001.html +++ /dev/null @@ -1,7 +0,0 @@ - - - Hello world! - Hello world! - - Goodbye world! - diff --git a/lib/chameleon/src/chameleon/tests/outputs/001.pt b/lib/chameleon/src/chameleon/tests/outputs/001.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/001.pt +++ /dev/null @@ -1,9 +0,0 @@ - - - Hello world! - - - - ok - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/001.txt b/lib/chameleon/src/chameleon/tests/outputs/001.txt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/001.txt +++ /dev/null @@ -1,1 +0,0 @@ -<&> diff --git a/lib/chameleon/src/chameleon/tests/outputs/002.pt b/lib/chameleon/src/chameleon/tests/outputs/002.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/002.pt +++ /dev/null @@ -1,13 +0,0 @@ - - -
- Hello! - Hello. -
-
- Goodbye! - Goodbye. -
- ok - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/003.pt b/lib/chameleon/src/chameleon/tests/outputs/003.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/003.pt +++ /dev/null @@ -1,17 +0,0 @@ - - -
Hello world!
-
Hello world!
1 - 2
Hello world!
-
Hello world!
3 -
Hello world!
5 - 6
Hello world!
-
1
-
1.0
-
True
-
False
-
0
-
- <div>Hello world!</div> - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/004.pt b/lib/chameleon/src/chameleon/tests/outputs/004.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/004.pt +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/005.pt b/lib/chameleon/src/chameleon/tests/outputs/005.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/005.pt +++ /dev/null @@ -1,12 +0,0 @@ - - - - - Default - True - False - - Computed default - - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/006.pt b/lib/chameleon/src/chameleon/tests/outputs/006.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/006.pt +++ /dev/null @@ -1,9 +0,0 @@ - - - copyright (c) 2010 - copyright (c) 2010 - copyright (c) 2010 - $ignored - <type 'str'> - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/007.pt b/lib/chameleon/src/chameleon/tests/outputs/007.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/007.pt +++ /dev/null @@ -1,20 +0,0 @@ - - - Hello world! -
Hello world!
-
Hello world!
- <type 'str'> - && - - - Hello world - $leftalone -
-
Hello world
-
${} is ignored.
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/008.pt b/lib/chameleon/src/chameleon/tests/outputs/008.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/008.pt +++ /dev/null @@ -1,12 +0,0 @@ - - - {} - -
- static -
-
- nothing -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/009.pt b/lib/chameleon/src/chameleon/tests/outputs/009.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/009.pt +++ /dev/null @@ -1,5 +0,0 @@ - - -
Hello world!
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/010.pt b/lib/chameleon/src/chameleon/tests/outputs/010.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/010.pt +++ /dev/null @@ -1,9 +0,0 @@ - - -
1 < 2
-
2 < 3, 2&3, 2<3, 2>3
-
3 < 4
-
4 < 5
-
Hello world!
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/011-en.pt b/lib/chameleon/src/chameleon/tests/outputs/011-en.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/011-en.pt +++ /dev/null @@ -1,9 +0,0 @@ - - -
Message ('message' translation into 'en')
-
Message ('message' translation into 'en')
-
Message ('message' translation into 'en')
-
Message ('message' translation into 'en')
- Message ('message' translation into 'en') - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/011.pt b/lib/chameleon/src/chameleon/tests/outputs/011.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/011.pt +++ /dev/null @@ -1,9 +0,0 @@ - - -
Message
-
Message
-
Message
-
Message
- Message - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/012-en.pt b/lib/chameleon/src/chameleon/tests/outputs/012-en.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/012-en.pt +++ /dev/null @@ -1,10 +0,0 @@ - - -
-
Hello world! ('Hello world!' translation into 'en')
-
Hello world! ('hello_world' translation into 'en')
-
Hello world! ('Hello world!' translation into 'en')
-
Hello world! Goodbye planet! ('Hello ${first}! Goodbye ${second}!' translation into 'en')
-
Hello world! Goodbye planet! ('hello_goodbye' translation into 'en')
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/012.pt b/lib/chameleon/src/chameleon/tests/outputs/012.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/012.pt +++ /dev/null @@ -1,10 +0,0 @@ - - -
-
Hello world!
-
Hello world!
-
Hello world!
-
Hello world! Goodbye planet!
-
Hello world! Goodbye planet!
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/013.pt b/lib/chameleon/src/chameleon/tests/outputs/013.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/013.pt +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - -
- [1,1] - - [1,2] -
- [2,1] - - [2,2] -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/014.pt b/lib/chameleon/src/chameleon/tests/outputs/014.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/014.pt +++ /dev/null @@ -1,12 +0,0 @@ - - - - [3,3] - [3,4] - - - [4,3] - [4,4] - - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/015-en.pt b/lib/chameleon/src/chameleon/tests/outputs/015-en.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/015-en.pt +++ /dev/null @@ -1,5 +0,0 @@ - - -
Price: Per kilo 12.5 ('Per kilo ${amount}' translation into 'en') ('Price: ${price}' translation into 'en')
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/015.pt b/lib/chameleon/src/chameleon/tests/outputs/015.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/015.pt +++ /dev/null @@ -1,5 +0,0 @@ - - -
Price: Per kilo 12.5
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/016-en.pt b/lib/chameleon/src/chameleon/tests/outputs/016-en.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/016-en.pt +++ /dev/null @@ -1,9 +0,0 @@ - - -
Hello world! ('Hello world!' translation into 'en')
- Hello world! ('Hello world!' translation into 'en') - Hello world! ('hello_world' translation into 'en') - Hello world! ('Hello world!' translation into 'en') - Hello world! ('hello_world' translation into 'en') - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/016.pt b/lib/chameleon/src/chameleon/tests/outputs/016.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/016.pt +++ /dev/null @@ -1,9 +0,0 @@ - - -
Hello world!
- Hello world! - Hello world! - Hello world! - Hello world! - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/017.pt b/lib/chameleon/src/chameleon/tests/outputs/017.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/017.pt +++ /dev/null @@ -1,12 +0,0 @@ - - - Hello world! - 1 - Hello world! - 23 - 4Hello world! -
Hello world!
- Hello world! - Hello world! - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/018-en.pt b/lib/chameleon/src/chameleon/tests/outputs/018-en.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/018-en.pt +++ /dev/null @@ -1,3 +0,0 @@ -
- october ('october' translation into 'en') 1982 ('1982' translation into 'en') ('${monthname} ${year}' translation into 'en') -
diff --git a/lib/chameleon/src/chameleon/tests/outputs/018.pt b/lib/chameleon/src/chameleon/tests/outputs/018.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/018.pt +++ /dev/null @@ -1,3 +0,0 @@ -
- october 1982 -
diff --git a/lib/chameleon/src/chameleon/tests/outputs/019.pt b/lib/chameleon/src/chameleon/tests/outputs/019.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/019.pt +++ /dev/null @@ -1,13 +0,0 @@ - - - Hello world! - Hello world!1 - 2Hello world! - Hello world!3 - Hello world!5 - 6Hello world! - 1 - 1.0 - True - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/020.pt b/lib/chameleon/src/chameleon/tests/outputs/020.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/020.pt +++ /dev/null @@ -1,8 +0,0 @@ - - -
-
NameError thrown at 5:24.
-
-
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/021-en.pt b/lib/chameleon/src/chameleon/tests/outputs/021-en.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/021-en.pt +++ /dev/null @@ -1,12 +0,0 @@ - - -
Hello world! ('Hello world!' translation into 'en' with domain 'new')
-
Hello world! ('Hello world!' translation into 'en' with domain 'old')
-
- Hello world! -
-
- Hello world! -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/021.pt b/lib/chameleon/src/chameleon/tests/outputs/021.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/021.pt +++ /dev/null @@ -1,12 +0,0 @@ - - -
Hello world!
-
Hello world!
-
- Hello world! -
-
- Hello world! -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/022.pt b/lib/chameleon/src/chameleon/tests/outputs/022.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/022.pt +++ /dev/null @@ -1,21 +0,0 @@ - - -
- - ok - - - - ok -
-
- - ok -
-
- - - ok -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/023.pt b/lib/chameleon/src/chameleon/tests/outputs/023.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/023.pt +++ /dev/null @@ -1,6 +0,0 @@ - - - - ok - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/024.pt b/lib/chameleon/src/chameleon/tests/outputs/024.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/024.pt +++ /dev/null @@ -1,14 +0,0 @@ - - - - - first - - second - - - ok - - - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/025.pt b/lib/chameleon/src/chameleon/tests/outputs/025.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/025.pt +++ /dev/null @@ -1,22 +0,0 @@ - - -
    -
  • 1
  • -
  • 2
  • -
  • 3
  • -
  • 1
  • 2
  • 3
  • -
  • 1
  • -
  • 2
  • -
  • 3
  • - - - 1, - - 2, - - 3 - - . -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/026.pt b/lib/chameleon/src/chameleon/tests/outputs/026.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/026.pt +++ /dev/null @@ -1,17 +0,0 @@ -
-
    -
  • 0
  • -
  • 1
  • -
  • 2
  • -
-
    -
  • 0
  • -
  • 1
  • -
  • 2
  • -
-
    -
  • even
  • -
  • odd
  • -
  • even
  • -
-
diff --git a/lib/chameleon/src/chameleon/tests/outputs/027.pt b/lib/chameleon/src/chameleon/tests/outputs/027.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/027.pt +++ /dev/null @@ -1,7 +0,0 @@ -
- abcghi - Hello World! - Hello World! -
diff --git a/lib/chameleon/src/chameleon/tests/outputs/028.pt b/lib/chameleon/src/chameleon/tests/outputs/028.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/028.pt +++ /dev/null @@ -1,5 +0,0 @@ -
- - - -
diff --git a/lib/chameleon/src/chameleon/tests/outputs/029.pt b/lib/chameleon/src/chameleon/tests/outputs/029.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/029.pt +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/lib/chameleon/src/chameleon/tests/outputs/030.pt b/lib/chameleon/src/chameleon/tests/outputs/030.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/030.pt +++ /dev/null @@ -1,10 +0,0 @@ - - -
- 1, 1, 2 -
-
- 2, 3, 4 -
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/031.pt b/lib/chameleon/src/chameleon/tests/outputs/031.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/031.pt +++ /dev/null @@ -1,7 +0,0 @@ -
- Hello World! - Hello World! - Hello World! - 012 - True -
diff --git a/lib/chameleon/src/chameleon/tests/outputs/032.pt b/lib/chameleon/src/chameleon/tests/outputs/032.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/032.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - Master template - - -
- - - -
- - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/033.pt b/lib/chameleon/src/chameleon/tests/outputs/033.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/033.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - Master template - - -
- - - -
- - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/034.pt b/lib/chameleon/src/chameleon/tests/outputs/034.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/034.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - Master template - - -
- - - -
- - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/035.pt b/lib/chameleon/src/chameleon/tests/outputs/035.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/035.pt +++ /dev/null @@ -1,17 +0,0 @@ - - - - New title - - - -
- - - -
- - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/036.pt b/lib/chameleon/src/chameleon/tests/outputs/036.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/036.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - New title - - -
- - - -
- - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/037.pt b/lib/chameleon/src/chameleon/tests/outputs/037.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/037.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - Master template - - -
- - ok - -
- - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/038.pt b/lib/chameleon/src/chameleon/tests/outputs/038.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/038.pt +++ /dev/null @@ -1,6 +0,0 @@ - - - - ok - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/039.pt b/lib/chameleon/src/chameleon/tests/outputs/039.pt deleted file mode 100644 diff --git a/lib/chameleon/src/chameleon/tests/outputs/040.pt b/lib/chameleon/src/chameleon/tests/outputs/040.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/040.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - - - foo - - - - - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/041.pt b/lib/chameleon/src/chameleon/tests/outputs/041.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/041.pt +++ /dev/null @@ -1,7 +0,0 @@ - - -
Hello world!
-
Hello world!
-
Goodbye
- - diff --git a/lib/chameleon/src/chameleon/tests/outputs/042.pt b/lib/chameleon/src/chameleon/tests/outputs/042.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/042.pt +++ /dev/null @@ -1,15 +0,0 @@ - - - Master template - - -
- - - -
- - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/043.pt b/lib/chameleon/src/chameleon/tests/outputs/043.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/043.pt +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - My title - - - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/044.pt b/lib/chameleon/src/chameleon/tests/outputs/044.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/044.pt +++ /dev/null @@ -1,5 +0,0 @@ - - - a, b - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/045.pt b/lib/chameleon/src/chameleon/tests/outputs/045.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/045.pt +++ /dev/null @@ -1,12 +0,0 @@ - - -]> - - - ZZZ YYY XXX - - diff --git a/lib/chameleon/src/chameleon/tests/outputs/046.pt b/lib/chameleon/src/chameleon/tests/outputs/046.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/046.pt +++ /dev/null @@ -1,17 +0,0 @@ - - - Master template - - -
- - - -
- - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/047.pt b/lib/chameleon/src/chameleon/tests/outputs/047.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/047.pt +++ /dev/null @@ -1,17 +0,0 @@ - - - Master template - - -
- - - -
- - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/048.pt b/lib/chameleon/src/chameleon/tests/outputs/048.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/048.pt +++ /dev/null @@ -1,17 +0,0 @@ - - - Master template - - -
- - - -
- - - \ No newline at end of file diff --git a/lib/chameleon/src/chameleon/tests/outputs/049.pt b/lib/chameleon/src/chameleon/tests/outputs/049.pt deleted file mode 100644 --- a/lib/chameleon/src/chameleon/tests/outputs/049.pt +++ /dev/null @@ -1,11 +0,0 @@ - - -
amp=&amp; lt=&lt;
-
amp=& lt=<
- + + diff --git a/public/assets/css/_styles.css b/public/assets/css/_styles.css new file mode 100644 --- /dev/null +++ b/public/assets/css/_styles.css @@ -0,0 +1,1388 @@ +/*! sanitize.css v8.0.0 | CC0 License | github.com/csstools/sanitize.css */ +*, +::before, +::after { + background-repeat: no-repeat; + box-sizing: border-box; } + +::before, +::after { + text-decoration: inherit; + vertical-align: inherit; } + +html { + cursor: default; + font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + line-height: 1.15; + -moz-tab-size: 4; + tab-size: 4; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + word-break: break-word; } + +body { + margin: 0; } + +h1 { + font-size: 2em; + margin: 0.67em 0; } + +hr { + height: 0; + overflow: visible; } + +main { + display: block; } + +nav ol, +nav ul { + list-style: none; } + +pre { + font-family: Menlo, Consolas, Roboto Mono, Ubuntu Monospace, Noto Mono, Oxygen Mono, Liberation Mono, monospace; + font-size: 1em; } + +a { + background-color: transparent; } + +abbr[title] { + text-decoration: underline; + text-decoration: underline dotted; } + +b, +strong { + font-weight: bolder; } + +code, +kbd, +samp { + font-family: Menlo, Consolas, Roboto Mono, Ubuntu Monospace, Noto Mono, Oxygen Mono, Liberation Mono, monospace; + font-size: 1em; } + +small { + font-size: 80%; } + +::-moz-selection { + background-color: #b3d4fc; + color: #000; + text-shadow: none; } + +::selection { + background-color: #b3d4fc; + color: #000; + text-shadow: none; } + +audio, +canvas, +iframe, +img, +svg, +video { + vertical-align: middle; } + +audio, +video { + display: inline-block; } + +audio:not([controls]) { + display: none; + height: 0; } + +img { + border-style: none; } + +svg:not([fill]) { + fill: currentColor; } + +svg:not(:root) { + overflow: hidden; } + +table { + border-collapse: collapse; } + +button, +input, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; } + +button, +input, +select { + margin: 0; } + +button { + overflow: visible; + text-transform: none; } + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; } + +fieldset { + padding: 0.35em 0.75em 0.625em; } + +input { + overflow: visible; } + +legend { + color: inherit; + display: table; + max-width: 100%; + white-space: normal; } + +progress { + display: inline-block; + vertical-align: baseline; } + +select { + text-transform: none; } + +textarea { + margin: 0; + overflow: auto; + resize: vertical; } + +[type="checkbox"], +[type="radio"] { + padding: 0; } + +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; } + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; } + +::-webkit-input-placeholder { + color: inherit; + opacity: 0.54; } + +::-webkit-search-decoration { + -webkit-appearance: none; } + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; } + +::-moz-focus-inner { + border-style: none; + padding: 0; } + +:-moz-focusring { + outline: 1px dotted ButtonText; } + +details { + display: block; } + +dialog { + background-color: white; + border: solid; + color: black; + display: block; + height: -moz-fit-content; + height: -webkit-fit-content; + height: fit-content; + left: 0; + margin: auto; + padding: 1em; + position: absolute; + right: 0; + width: -moz-fit-content; + width: -webkit-fit-content; + width: fit-content; } + +dialog:not([open]) { + display: none; } + +summary { + display: list-item; } + +canvas { + display: inline-block; } + +template { + display: none; } + +a, +area, +button, +input, +label, +select, +summary, +textarea, +[tabindex] { + -ms-touch-action: manipulation; + touch-action: manipulation; } + +[hidden] { + display: none; } + +[aria-busy="true"] { + cursor: progress; } + +[aria-controls] { + cursor: pointer; } + +[aria-disabled="true"], +[disabled] { + cursor: not-allowed; } + +[aria-hidden="false"][hidden]:not(:focus) { + clip: rect(0, 0, 0, 0); + display: inherit; + position: absolute; } + +/*! Based on https://github.com/milligram/milligram */ +*, +*:after, +*:before { + box-sizing: inherit; } + +html { + box-sizing: border-box; + font-size: 62.5%; } + +body { + font-size: 1.6em; + font-weight: 300; + letter-spacing: .01em; + line-height: 1.6; + background-color: #fcfcfc; } + +body { + color: #4B545C; + font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; } + +b, +strong { + font-weight: bold; } + +p { + margin-top: 0; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: 300; + letter-spacing: -.1rem; + margin-bottom: 2.0rem; + margin-top: 0; } + +h1 { + font-size: 4.6rem; + line-height: 1.2; } + +h2 { + font-size: 3.6rem; + line-height: 1.25; } + +h3 { + font-size: 2.8rem; + line-height: 1.3; } + +h4 { + font-size: 2.2rem; + letter-spacing: -.08rem; + line-height: 1.35; } + +h5 { + font-size: 1.8rem; + letter-spacing: -.05rem; + line-height: 1.5; } + +h6 { + font-size: 1.6rem; + letter-spacing: 0; + line-height: 1.4; } + +blockquote { + border-left: 0.3rem solid #d1d1d1; + margin-left: 0; + margin-right: 0; + padding: 1rem 1.5rem; } + blockquote *:last-child { + margin-bottom: 0; } + +.button, +button { + background-color: #35bf712e; + border: 0.1rem solid #1890ff; + border-radius: .4rem; + color: #fcfcfc; + cursor: pointer; + display: inline-block; + font-size: 1.1rem; + font-weight: 700; + height: 3.8rem; + letter-spacing: .1rem; + line-height: 3.8rem; + padding: 0 3.0rem; + text-align: center; + text-decoration: none; + text-transform: uppercase; + white-space: nowrap; + -webkit-box-shadow: 0px 5px 10px 0px rgba(24, 144, 255, 0.2); + -webkit-box-shadow--moz-box-shadow: 0px 5px 10px 0px rgba(24, 144, 255, 0.2); + -webkit-box-shadow-box-shadow: 0px 5px 10px 0px rgba(24, 144, 255, 0.2); } + .button:focus, .button:hover, + button:focus, + button:hover, + input[type='button']:focus, + input[type='button']:hover, + input[type='reset']:focus, + input[type='reset']:hover, + input[type='submit']:focus, + input[type='submit']:hover { + background-color: #4B545C; + border-color: #4B545C; + color: #fcfcfc; + outline: 0; + -webkit-box-shadow: 0px 5px 10px 0px rgba(75, 84, 92, 0.2); + -webkit-box-shadow--moz-box-shadow: 0px 5px 10px 0px rgba(75, 84, 92, 0.2); + -webkit-box-shadow-box-shadow: 0px 5px 10px 0px rgba(75, 84, 92, 0.2); } + .button[disabled], + button[disabled], + input[type='button'][disabled], + input[type='reset'][disabled], + input[type='submit'][disabled] { + cursor: default; + opacity: .5; } + .button[disabled]:focus, .button[disabled]:hover, + button[disabled]:focus, + button[disabled]:hover, + input[type='button'][disabled]:focus, + input[type='button'][disabled]:hover, + input[type='reset'][disabled]:focus, + input[type='reset'][disabled]:hover, + input[type='submit'][disabled]:focus, + input[type='submit'][disabled]:hover { + background-color: #35bf712e; + border-color: #1890ff; } + .button.button-outline, + button.button-outline, + input[type='button'].button-outline, + input[type='reset'].button-outline, + input[type='submit'].button-outline { + background-color: transparent; + color: #35bf712e; } + .button.button-outline:focus, .button.button-outline:hover, + button.button-outline:focus, + button.button-outline:hover, + input[type='button'].button-outline:focus, + input[type='button'].button-outline:hover, + input[type='reset'].button-outline:focus, + input[type='reset'].button-outline:hover, + input[type='submit'].button-outline:focus, + input[type='submit'].button-outline:hover { + background-color: transparent; + border-color: #4B545C; + color: #4B545C; } + .button.button-outline[disabled]:focus, .button.button-outline[disabled]:hover, + button.button-outline[disabled]:focus, + button.button-outline[disabled]:hover, + input[type='button'].button-outline[disabled]:focus, + input[type='button'].button-outline[disabled]:hover, + input[type='reset'].button-outline[disabled]:focus, + input[type='reset'].button-outline[disabled]:hover, + input[type='submit'].button-outline[disabled]:focus, + input[type='submit'].button-outline[disabled]:hover { + border-color: inherit; + color: #35bf712e; } + .button.button-clear, + button.button-clear, + input[type='button'].button-clear, + input[type='reset'].button-clear, + input[type='submit'].button-clear { + background-color: transparent; + border-color: transparent; + color: #35bf712e; } + .button.button-clear:focus, .button.button-clear:hover, + button.button-clear:focus, + button.button-clear:hover, + input[type='button'].button-clear:focus, + input[type='button'].button-clear:hover, + input[type='reset'].button-clear:focus, + input[type='reset'].button-clear:hover, + input[type='submit'].button-clear:focus, + input[type='submit'].button-clear:hover { + background-color: transparent; + border-color: transparent; + color: #4B545C; } + .button.button-clear[disabled]:focus, .button.button-clear[disabled]:hover, + button.button-clear[disabled]:focus, + button.button-clear[disabled]:hover, + input[type='button'].button-clear[disabled]:focus, + input[type='button'].button-clear[disabled]:hover, + input[type='reset'].button-clear[disabled]:focus, + input[type='reset'].button-clear[disabled]:hover, + input[type='submit'].button-clear[disabled]:focus, + input[type='submit'].button-clear[disabled]:hover { + color: #35bf712e; } + +code { + background: #f4f5f6; + border-radius: .4rem; + font-size: 86%; + margin: 0 .2rem; + padding: 0.8rem 1rem; + white-space: normal; } + +pre { + border-left: 0.3rem solid #1890ff; + padding-left: 2rem; + background: #f4f5f6; + overflow-y: hidden; } + pre > code { + border-radius: 0; + display: block; + padding: 1rem 1.5rem; + white-space: pre; } + +hr { + border: 0; + border-top: 0.1rem solid #d1d1d1; + margin: 3.0rem 0; } + +:link { + color: #35bf712e; +} + +input[type='email'], +input[type='number'], +input[type='password'], +input[type='search'], +input[type='tel'], +input[type='text'], +input[type='url'], +input[type='color'], +input[type='date'], +input[type='month'], +input[type='week'], +input[type='datetime'], +input[type='datetime-local'], +input:not([type]), +textarea, +select { + -webkit-appearance: none; + -webkit-appearance--moz-appearance: none; + appearance: none; + background-color: transparent; + color: #4B545C; + border: 0.1rem solid #d1d1d1; + border-radius: .4rem; + box-shadow: none; + box-sizing: inherit; + height: 3.8rem; + padding: .6rem 1.0rem; + width: 100%; } + input[type='email']:focus, + input[type='number']:focus, + input[type='password']:focus, + input[type='search']:focus, + input[type='tel']:focus, + input[type='text']:focus, + input[type='url']:focus, + input[type='color']:focus, + input[type='date']:focus, + input[type='month']:focus, + input[type='week']:focus, + input[type='datetime']:focus, + input[type='datetime-local']:focus, + input:not([type]):focus, + textarea:focus, + select:focus { + border-color: #1890ff; + outline: 0; } + +select { + background: url('data:image/svg+xml;utf8,') center right no-repeat; + padding-right: 3.0rem; } + select:focus { + background-image: url('data:image/svg+xml;utf8,'); } + +textarea { + min-height: 6.5rem; } + +label, +legend { + display: block; + font-size: 1.6rem; + font-weight: 700; + margin-bottom: .5rem; } + +fieldset { + border-width: 0; + padding: 0; } + +input[type='checkbox'], +input[type='radio'] { + display: inline; } + +.label-inline { + display: inline-block; + font-weight: normal; + margin-left: .5rem; } + +a { + color: #1890ff; + text-decoration: none; } + a:focus, a:hover { + color: #4B545C; } + +dl, +ol, +ul { + list-style: none; + margin-top: 0; + padding-left: 3rem; } + dl dl, + dl ol, + dl ul, + ol dl, + ol ol, + ol ul, + ul dl, + ul ol, + ul ul { + font-size: 90%; + margin: 1.5rem 0 1.5rem 3.0rem; } + +ol { + list-style: decimal inside; + list-style-position: outside; } + +ul { + list-style: circle inside; + list-style-position: outside; } + +.button, +button, +dd, +dt, +li { + margin-bottom: 1.0rem; } + +fieldset, +input, +select, +textarea { + margin-bottom: 1.5rem; } + +blockquote, +dl, +figure, +form, +ol, +p, +pre, +table, +ul { + margin-bottom: 2.5rem; } + +table { + border-spacing: 0; + width: 100%; } + +td, +th { + border-bottom: 0.1rem solid #e1e1e1; + padding: 1.2rem 1.5rem; + text-align: left; } + td:first-child, + th:first-child { + padding-left: 0; } + td:last-child, + th:last-child { + padding-right: 0; } + + at media screen and (max-width: 40rem) { + table { + border-spacing: 0; + display: flex; + width: 100%; } + table thead { + border-right: solid 0.1rem #e1e1e1; } + table thead td, + table thead th { + padding-left: 0; } + table thead td:first-child, + table thead th:first-child { + padding-left: 0; } + table thead td:last-child, + table thead th:last-child { + padding-right: 1.2rem; } + table tbody { + display: flex; + overflow-x: auto; + white-space: nowrap; } + table tbody tr { + border-right: solid 0.1rem #e1e1e1; } + table tbody tr:last-child { + border-right: none; } + table td, + table th { + display: block; } + table td:first-child, + table th:first-child { + padding-left: 1.2rem; } + table td:last-child, + table th:last-child { + padding-right: 1.2rem; } } + +img { + max-width: 100%; } + +.p-0 { + padding: 0; } + +.pt-0 { + padding-top: 0; } + +.pb-0 { + padding-bottom: 0; } + +.pl-0 { + padding-left: 0; } + +.pr-0 { + padding-right: 0; } + +.py-0 { + padding-top: 0; + padding-bottom: 0; } + +.px-0 { + padding-left: 0; + padding-right: 0; } + +.p-1 { + padding: 1rem; } + +.pt-1 { + padding-top: 1rem; } + +.pb-1 { + padding-bottom: 1rem; } + +.pl-1 { + padding-left: 1rem; } + +.pr-1 { + padding-right: 1rem; } + +.py-1 { + padding-top: 1rem; + padding-bottom: 1rem; } + +.px-1 { + padding-left: 1rem; + padding-right: 1rem; } + +.p-2 { + padding: 2rem; } + +.pt-2 { + padding-top: 2rem; } + +.pb-2 { + padding-bottom: 2rem; } + +.pl-2 { + padding-left: 2rem; } + +.pr-2 { + padding-right: 2rem; } + +.py-2 { + padding-top: 2rem; + padding-bottom: 2rem; } + +.px-2 { + padding-left: 2rem; + padding-right: 2rem; } + +.p-3 { + padding: 3rem; } + +.pt-3 { + padding-top: 3rem; } + +.pb-3 { + padding-bottom: 3rem; } + +.pl-3 { + padding-left: 3rem; } + +.pr-3 { + padding-right: 3rem; } + +.py-3 { + padding-top: 3rem; + padding-bottom: 3rem; } + +.px-3 { + padding-left: 3rem; + padding-right: 3rem; } + +.p-4 { + padding: 6rem; } + +.pt-4 { + padding-top: 6rem; } + +.pb-4 { + padding-bottom: 6rem; } + +.pl-4 { + padding-left: 6rem; } + +.pr-4 { + padding-right: 6rem; } + +.py-4 { + padding-top: 6rem; + padding-bottom: 6rem; } + +.px-4 { + padding-left: 6rem; + padding-right: 6rem; } + +.p-5 { + padding: 8rem; } + +.pt-5 { + padding-top: 8rem; } + +.pb-5 { + padding-bottom: 8rem; } + +.pl-5 { + padding-left: 8rem; } + +.pr-5 { + padding-right: 8rem; } + +.py-5 { + padding-top: 8rem; + padding-bottom: 8rem; } + +.px-5 { + padding-left: 8rem; + padding-right: 8rem; } + +.m-0 { + margin: 0; } + +.mt-0 { + margin-top: 0; } + +.mb-0 { + margin-bottom: 0; } + +.ml-0 { + margin-left: 0; } + +.mr-0 { + margin-right: 0; } + +.my-0 { + margin-top: 0; + margin-bottom: 0; } + +.mx-0 { + margin-left: 0; + margin-right: 0; } + +.m-1 { + margin: 1rem; } + +.mt-1 { + margin-top: 1rem; } + +.mb-1 { + margin-bottom: 1rem; } + +.ml-1 { + margin-left: 1rem; } + +.mr-1 { + margin-right: 1rem; } + +.my-1 { + margin-top: 1rem; + margin-bottom: 1rem; } + +.mx-1 { + margin-left: 1rem; + margin-right: 1rem; } + +.m-2 { + margin: 2rem; } + +.mt-2 { + margin-top: 2rem; } + +.mb-2 { + margin-bottom: 2rem; } + +.ml-2 { + margin-left: 2rem; } + +.mr-2 { + margin-right: 2rem; } + +.my-2 { + margin-top: 2rem; + margin-bottom: 2rem; } + +.mx-2 { + margin-left: 2rem; + margin-right: 2rem; } + +.m-3 { + margin: 3rem; } + +.mt-3 { + margin-top: 3rem; } + +.mb-3 { + margin-bottom: 3rem; } + +.ml-3 { + margin-left: 3rem; } + +.mr-3 { + margin-right: 3rem; } + +.my-3 { + margin-top: 3rem; + margin-bottom: 3rem; } + +.mx-3 { + margin-left: 3rem; + margin-right: 3rem; } + +.m-4 { + margin: 6rem; } + +.mt-4 { + margin-top: 6rem; } + +.mb-4 { + margin-bottom: 6rem; } + +.ml-4 { + margin-left: 6rem; } + +.mr-4 { + margin-right: 6rem; } + +.my-4 { + margin-top: 6rem; + margin-bottom: 6rem; } + +.mx-4 { + margin-left: 6rem; + margin-right: 6rem; } + +.m-5 { + margin: 8rem; } + +.mt-5 { + margin-top: 8rem; } + +.mb-5 { + margin-bottom: 8rem; } + +.ml-5 { + margin-left: 8rem; } + +.mr-5 { + margin-right: 8rem; } + +.my-5 { + margin-top: 8rem; + margin-bottom: 8rem; } + +.mx-5 { + margin-left: 8rem; + margin-right: 8rem; } + +.mx-auto { + margin-left: auto; + margin-right: auto; } + +.text-justify { + text-align: justify; } + +.text-left { + text-align: left; } + +.text-center { + text-align: center; } + +.text-left { + text-align: right; } + +.text-sm { + font-size: 1rem; } + +.text-lg { + font-size: 2rem; } + +.text-xl { + font-size: 2.5rem; } + +.display-none { + display: none; } + +.display-inline { + display: inline; } + +.display-inline-block { + display: inline-block; } + +.display-block { + display: block; } + +.display-flex { + display: flex; } + +.display-inline-flex { + display: inline-flex; } + +.display-table { + display: table; } + +.clearfix:after { + clear: both; + content: ' '; + display: table; } + +.float-left { + float: left; } + +.float-right { + float: right; } + +.container { + margin: 0 auto; + max-width: 112.0rem; + padding: 0 2.0rem; + position: relative; + width: 100%; } + +.row { + display: flex; + flex-direction: column; + padding: 0; + width: 100%; } + .row.row-no-padding { + padding: 0; } + .row.row-no-padding > .column { + padding: 0; } + .row.row-wrap { + flex-wrap: wrap; } + .row.row-top { + align-items: flex-start; } + .row.row-bottom { + align-items: flex-end; } + .row.row-center { + align-items: center; } + .row.row-stretch { + align-items: stretch; } + .row.row-baseline { + align-items: baseline; } + .row .column { + display: block; + flex: 1 1 auto; + margin-left: 0; + max-width: 100%; + width: 100%; } + .row .column.column-offset-10 { + margin-left: 10%; } + .row .column.column-offset-20 { + margin-left: 20%; } + .row .column.column-offset-25 { + margin-left: 25%; } + .row .column.column-offset-33, .row .column.column-offset-34 { + margin-left: 33.3333%; } + .row .column.column-offset-50 { + margin-left: 50%; } + .row .column.column-offset-66, .row .column.column-offset-67 { + margin-left: 66.6666%; } + .row .column.column-offset-75 { + margin-left: 75%; } + .row .column.column-offset-80 { + margin-left: 80%; } + .row .column.column-offset-90 { + margin-left: 90%; } + .row .column.column-10 { + flex: 0 0 10%; + max-width: 10%; } + .row .column.column-20 { + flex: 0 0 20%; + max-width: 20%; } + .row .column.column-25 { + flex: 0 0 25%; + max-width: 25%; } + .row .column.column-33, .row .column.column-34 { + flex: 0 0 33.3333%; + max-width: 33.3333%; } + .row .column.column-40 { + flex: 0 0 40%; + max-width: 40%; } + .row .column.column-50 { + flex: 0 0 50%; + max-width: 50%; } + .row .column.column-60 { + flex: 0 0 60%; + max-width: 60%; } + .row .column.column-66, .row .column.column-67 { + flex: 0 0 66.6666%; + max-width: 66.6666%; } + .row .column.column-75 { + flex: 0 0 75%; + max-width: 75%; } + .row .column.column-80 { + flex: 0 0 80%; + max-width: 80%; } + .row .column.column-90 { + flex: 0 0 90%; + max-width: 90%; } + .row .column .column-top { + align-self: flex-start; } + .row .column .column-bottom { + align-self: flex-end; } + .row .column .column-center { + align-self: center; } + + at media (min-width: 40rem) { + .row { + flex-direction: row; + margin-left: -1.0rem; + width: calc(100% + 2.0rem); } + .row .column { + margin-bottom: inherit; + padding: 0 1.0rem; } } + + at font-face { + font-family: 'ico'; + src: url("../font/ico.eot?13319731"); + src: url("../font/ico.eot?13319731#iefix") format("embedded-opentype"), url("../font/ico.woff2?13319731") format("woff2"), url("../font/ico.woff?13319731") format("woff"), url("../font/ico.ttf?13319731") format("truetype"), url("../font/ico.svg?13319731#ico") format("svg"); + font-weight: normal; + font-style: normal; } + +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* + @media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'ico'; + src: url('../font/ico.svg?13319731#ico') format('svg'); + } + } + */ +[class^="icon-"]:before, [class*=" icon-"]:before { + font-family: "ico"; + font-style: normal; + font-weight: normal; + speak: none; + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; + /* opacity: .8; */ + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + margin-left: .2em; + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + /* Font smoothing. That was taken from TWBS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ } + +/* + Animation example, for spinners + */ +.animate-spin { + -moz-animation: spin 2s infinite linear; + -o-animation: spin 2s infinite linear; + -webkit-animation: spin 2s infinite linear; + animation: spin 2s infinite linear; + display: inline-block; } + + at -moz-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } + + at -webkit-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } + + at -o-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } + + at -ms-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } + + at keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); } } + +.icon-menu-outline:before { + content: '\e800'; } + +.icon-github-circled:before { + content: '\f09b'; } + +.icon-rss:before { + content: '\f09e'; } + +.icon-menu:before { + content: '\f0c9'; } + +.icon-spinner:before { + content: '\f110'; } + +.icon-code:before { + content: '\f121'; } + +.icon-bitbucket:before { + content: '\f171'; } + +.icon-circle-notch:before { + content: '\f1ce'; } + +.icon-github-text:before { + content: '\f307'; } + +.navbar { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin-top: 2rem; + padding-left: 0; + padding-inline-start: 0; } + +.navbar-item { + padding: 0.5rem 0.66rem; + margin: 0 0.2rem; } + +.nav-item-active { + border-radius: .4rem; + border: 0.1rem solid #1890ff; } + .nav-item-active:hover { + border-color: #4B545C; } + +.navbar-menu { + display: none; + position: fixed; + right: 0; + top: 0; + z-index: 100; + padding: 0.5rem 0.66rem; + margin-top: 2rem; + margin-right: 2rem; + border-radius: 50%; + background-color: #fff; } + + at media screen and (max-width: 60rem) { + .navbar { + justify-content: center; } } + +.navbar-smart { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin-top: 2rem; + padding-left: 0; + padding-inline-start: 0; } + + at media screen and (max-width: 60rem) { + .navbar-menu-on { + display: block; } + .navbar-smart { + display: none; + flex-direction: column; + align-items: flex-start; + position: fixed; + left: 0; + top: 0; + width: 100%; + z-index: 100; + padding: 1rem; + background-color: rgba(255, 255, 255, 0.98); } + .navbar-open { + display: flex; } } + +.shadow { + -webkit-box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3); + box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3); } + +.shadow-lg { + -webkit-box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.8); + -moz-box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.8); + box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.8); } + +.active { + -webkit-box-shadow: 0px 5px 10px 0px rgba(24, 144, 255, 0.2); + -moz-box-shadow: 0px 5px 10px 0px rgba(24, 144, 255, 0.2); + box-shadow: 0px 5px 10px 0px rgba(24, 144, 255, 0.2); } + +.shadow-secondary { + -webkit-box-shadow: 0px 5px 10px 0px rgba(75, 84, 92, 0.2); + -moz-box-shadow: 0px 5px 10px 0px rgba(75, 84, 92, 0.2); + box-shadow: 0px 5px 10px 0px rgba(75, 84, 92, 0.2); } + +.muted { + color: #8B9298; } + + at media screen and (max-width: 40rem) { + .row .column { + text-align: center; } } + +.person { + min-height: 190px; + margin-bottom: 8rem; } + .person h3 { + margin-bottom: 1rem; } + .person img { + float: left; + max-width: 150px; + margin-right: 2rem; + margin-bottom: 1rem; } + .person p { + margin-left: 150px; } + + at media screen and (max-width: 40rem) { + .person img { + float: none; } + .person p { + margin-left: 0; } } + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #9006b3; + background: #f4f5f6; } + +.hljs-comment, +.hljs-quote { + color: #bbbcc2; + font-style: italic; } + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #dd4600; } + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e45649; } + +.hljs-literal { + color: #009c15; } + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #2e912c; } + +.hljs-built_in, +.hljs-class .hljs-title { + color: #c1ae01; } + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #b97f00; } + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #2263f0; } + +.hljs-emphasis { + font-style: italic; } + +.hljs-strong { + font-weight: bold; } + +.hljs-link { + text-decoration: underline; } diff --git a/public/assets/css/code.css b/public/assets/css/code.css new file mode 100644 --- /dev/null +++ b/public/assets/css/code.css @@ -0,0 +1,71 @@ +/* code.css file generated by Nikola */ +pre.code , .highlight pre .hll { background-color: #ffffcc } +pre.code , .highlight pre { background: #f8f8f8; } +pre.code .c, .highlight pre .c { color: #408080; font-style: italic } /* Comment */ +pre.code .err, .highlight pre .err { border: 1px solid #FF0000 } /* Error */ +pre.code .k, .highlight pre .k { color: #008000; font-weight: bold } /* Keyword */ +pre.code .o, .highlight pre .o { color: #666666 } /* Operator */ +pre.code .ch, .highlight pre .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ +pre.code .cm, .highlight pre .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +pre.code .cp, .highlight pre .cp { color: #BC7A00 } /* Comment.Preproc */ +pre.code .cpf, .highlight pre .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ +pre.code .c1, .highlight pre .c1 { color: #408080; font-style: italic } /* Comment.Single */ +pre.code .cs, .highlight pre .cs { color: #408080; font-style: italic } /* Comment.Special */ +pre.code .gd, .highlight pre .gd { color: #A00000 } /* Generic.Deleted */ +pre.code .ge, .highlight pre .ge { font-style: italic } /* Generic.Emph */ +pre.code .gr, .highlight pre .gr { color: #FF0000 } /* Generic.Error */ +pre.code .gh, .highlight pre .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +pre.code .gi, .highlight pre .gi { color: #00A000 } /* Generic.Inserted */ +pre.code .go, .highlight pre .go { color: #888888 } /* Generic.Output */ +pre.code .gp, .highlight pre .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +pre.code .gs, .highlight pre .gs { font-weight: bold } /* Generic.Strong */ +pre.code .gu, .highlight pre .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +pre.code .gt, .highlight pre .gt { color: #0044DD } /* Generic.Traceback */ +pre.code .kc, .highlight pre .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +pre.code .kd, .highlight pre .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +pre.code .kn, .highlight pre .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +pre.code .kp, .highlight pre .kp { color: #008000 } /* Keyword.Pseudo */ +pre.code .kr, .highlight pre .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +pre.code .kt, .highlight pre .kt { color: #B00040 } /* Keyword.Type */ +pre.code .m, .highlight pre .m { color: #666666 } /* Literal.Number */ +pre.code .s, .highlight pre .s { color: #BA2121 } /* Literal.String */ +pre.code .na, .highlight pre .na { color: #7D9029 } /* Name.Attribute */ +pre.code .nb, .highlight pre .nb { color: #008000 } /* Name.Builtin */ +pre.code .nc, .highlight pre .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +pre.code .no, .highlight pre .no { color: #880000 } /* Name.Constant */ +pre.code .nd, .highlight pre .nd { color: #AA22FF } /* Name.Decorator */ +pre.code .ni, .highlight pre .ni { color: #999999; font-weight: bold } /* Name.Entity */ +pre.code .ne, .highlight pre .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +pre.code .nf, .highlight pre .nf { color: #0000FF } /* Name.Function */ +pre.code .nl, .highlight pre .nl { color: #A0A000 } /* Name.Label */ +pre.code .nn, .highlight pre .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +pre.code .nt, .highlight pre .nt { color: #008000; font-weight: bold } /* Name.Tag */ +pre.code .nv, .highlight pre .nv { color: #19177C } /* Name.Variable */ +pre.code .ow, .highlight pre .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +pre.code .w, .highlight pre .w { color: #bbbbbb } /* Text.Whitespace */ +pre.code .mb, .highlight pre .mb { color: #666666 } /* Literal.Number.Bin */ +pre.code .mf, .highlight pre .mf { color: #666666 } /* Literal.Number.Float */ +pre.code .mh, .highlight pre .mh { color: #666666 } /* Literal.Number.Hex */ +pre.code .mi, .highlight pre .mi { color: #666666 } /* Literal.Number.Integer */ +pre.code .mo, .highlight pre .mo { color: #666666 } /* Literal.Number.Oct */ +pre.code .sa, .highlight pre .sa { color: #BA2121 } /* Literal.String.Affix */ +pre.code .sb, .highlight pre .sb { color: #BA2121 } /* Literal.String.Backtick */ +pre.code .sc, .highlight pre .sc { color: #BA2121 } /* Literal.String.Char */ +pre.code .dl, .highlight pre .dl { color: #BA2121 } /* Literal.String.Delimiter */ +pre.code .sd, .highlight pre .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +pre.code .s2, .highlight pre .s2 { color: #BA2121 } /* Literal.String.Double */ +pre.code .se, .highlight pre .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +pre.code .sh, .highlight pre .sh { color: #BA2121 } /* Literal.String.Heredoc */ +pre.code .si, .highlight pre .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +pre.code .sx, .highlight pre .sx { color: #008000 } /* Literal.String.Other */ +pre.code .sr, .highlight pre .sr { color: #BB6688 } /* Literal.String.Regex */ +pre.code .s1, .highlight pre .s1 { color: #BA2121 } /* Literal.String.Single */ +pre.code .ss, .highlight pre .ss { color: #19177C } /* Literal.String.Symbol */ +pre.code .bp, .highlight pre .bp { color: #008000 } /* Name.Builtin.Pseudo */ +pre.code .fm, .highlight pre .fm { color: #0000FF } /* Name.Function.Magic */ +pre.code .vc, .highlight pre .vc { color: #19177C } /* Name.Variable.Class */ +pre.code .vg, .highlight pre .vg { color: #19177C } /* Name.Variable.Global */ +pre.code .vi, .highlight pre .vi { color: #19177C } /* Name.Variable.Instance */ +pre.code .vm, .highlight pre .vm { color: #19177C } /* Name.Variable.Magic */ +pre.code .il, .highlight pre .il { color: #666666 } /* Literal.Number.Integer.Long */ +table.codetable { width: 100%;} td.linenos {text-align: right; width: 4em;} diff --git a/public/assets/css/html4css1.css b/public/assets/css/html4css1.css new file mode 100644 --- /dev/null +++ b/public/assets/css/html4css1.css @@ -0,0 +1,1 @@ + at import url("rst_base.css"); diff --git a/public/assets/css/ipython.min.css b/public/assets/css/ipython.min.css new file mode 100644 --- /dev/null +++ b/public/assets/css/ipython.min.css @@ -0,0 +1,9 @@ +/*! +* +* IPython base +* +*/.modal.fade .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}code{color:#000}pre{font-size:inherit;line-height:inherit}label{font-weight:normal}.border-box-sizing{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.corner-all{border-radius:2px}.no-padding{padding:0}.hbox{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}.hbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none}.vbox{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}.vbox>*{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none}.hbox.reverse,.vbox.reverse,.reverse{-webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;flex-direction:row-reverse}.hbox.box-flex0,.vbox.box-flex0,.box-flex0{-webkit-box-flex:0;-moz-box-flex:0;box-flex:0;flex:none;width:auto}.hbox.box-flex1,.vbox.box-flex1,.box-flex1{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.hbox.box-flex,.vbox.box-flex,.box-flex{-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}.hbox.box-flex2,.vbox.box-flex2,.box-flex2{-webkit-box-flex:2;-moz-box-flex:2;box-flex:2;flex:2}.box-group1{-webkit-box-flex-group:1;-moz-box-flex-group:1;box-flex-group:1}.box-group2{-webkit-box-flex-group:2;-moz-box-flex-group:2;box-flex-group:2}.hbox.start,.vbox.start,.start{-webkit-box-pack:start;-moz-box-pack:start;box-pack:start;justify-content:flex-start}.hbox.end,.vbox.end,.end{-webkit-box-pack:end;-moz-box-pack:end;box-pack:end;justify-content:flex-end}.hbox.center,.vbox.center,.center{-webkit-box-pack:center;-moz-box-pack:center;box-pack:center;justify-content:center}.hbox.baseline,.vbox.baseline,.baseline{-webkit-box-pack:baseline;-moz-box-pack:baseline;box-pack:baseline;justify-content:baseline}.hbox.stretch,.vbox.stretch,.stretch{-webkit-box-pack:stretch;-moz-box-pack:stretch;box-pack:stretch;justify-content:stretch}.hbox.align-start,.vbox.align-start,.align-start{-webkit-box-align:start;-moz-box-align:start;box-align:start;align-items:flex-start}.hbox.align-end,.vbox.align-end,.align-end{-webkit-box-align:end;-moz-box-align:end;box-align:end;align-items:flex-end}.hbox.align-center,.vbox.align-center,.align-center{-webkit-box-align:center;-moz-box-align:center;box-align:center;align-items:center}.hbox.align-baseline,.vbox.align-baseline,.align-baseline{-webkit-box-align:baseline;-moz-box-align:baseline;box-align:baseline;align-items:baseline}.hbox.align-stretch,.vbox.align-stretch,.align-stretch{-webkit-box-align:stretch;-moz-box-align:stretch;box-align:stretch;align-items:stretch}div.error{margin:2em;text-align:center}div.error>h1{font-size:500%;line-height:normal}div.error>p{font-size:200%;line-height:normal}div.traceback-wrapper{text-align:left;max-width:800px;margin:auto}div.traceback-wrapper pre.traceback{max-height:600px;overflow:auto}/*! +* +* IPython notebook +* +*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-fg{color:#282c36}.ansi-black-intense-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-fg{color:#b22b31}.ansi-red-intense-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-fg{color:#007427}.ansi-green-intense-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-fg{color:#b27d12}.ansi-yellow-intense-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-fg{color:#0065ca}.ansi-blue-intense-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-fg{color:#a03196}.ansi-magenta-intense-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-fg{color:#258f8f}.ansi-cyan-intense-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-fg{color:#a1a6b2}.ansi-white-intense-bg{background-color:#a1a6b2}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}.ansi-inverse{outline:.5px dotted}.ansibold{font-weight:bold}.ansiblack{color:black}.ansired{color:darkred}.ansigreen{color:darkgreen}.ansiyellow{color:#c4a000}.ansiblue{color:darkblue}.ansipurple{color:darkviolet}.ansicyan{color:steelblue}.ansigray{color:gray}.ansibgblack{background-color:black}.ansibgred{background-color:red}.ansibggreen{background-color:green}.ansibgyellow{background-color:yellow}.ansibgblue{background-color:blue}.ansibgpurple{background-color:magenta}.ansibgcyan{background-color:cyan}.ansibggray{background-color:gray}div.cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch;border-radius:2px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;border-width:1px;border-style:solid;border-color:transparent;width:100%;padding:5px;margin:0;outline:0;position:relative;overflow:visible}div.cell:before{position:absolute;display:block;top:-1px;left:-1px;width:5px;height:calc(100%+2px);content:'';background:transparent}div.cell.jupyter-soft-selected{border-left-color:#e3f2fd;border-left-width:1px;padding-left:5px;border-right-color:#e3f2fd;border-right-width:1px;background:#e3f2fd}@media print{div.cell.jupyter-soft-selected{border-color:transparent}}div.cell.selected,div.cell.selected.jupyter-soft-selected{border-color:#ababab}div.cell.selected:before,div.cell.selected.jupyter-soft-selected:before{position:absolute;display:block;top:-1px;left:-1px;width:5px;height:calc(100%+2px);content:'';background:#42a5f5}@media print{div.cell.selected,div.cell.selected.jupyter-soft-selected{border-color:transparent}}.edit_mode div.cell.selected{border-color:#66bb6a}.edit_mode div.cell.selected:before{position:absolute;display:block;top:-1px;left:-1px;width:5px;height:calc(100%+2px);content:'';background:#66bb6a}@media print{.edit_mode div.cell.selected{border-color:transparent}}.prompt{min-width:14ex;padding:.4em;margin:0;font-family:monospace;text-align:right;line-height:1.21429em;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}@media(max-width:540px){.prompt{text-align:left}}div.inner_cell{min-width:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1}div.input_area>div.highlight>pre{border:1px solid #cfcfcf;line-height:1.21429em}div.prompt:empty{padding-top:0;padding-bottom:0}div.unrecognized_cell{padding:5px 5px 5px 0;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}div.unrecognized_cell .inner_cell{border-radius:2px;padding:5px;font-weight:bold;color:red;border:1px solid #cfcfcf;background:#eaeaea}div.unrecognized_cell .inner_cell a{color:inherit;text-decoration:none}div.unrecognized_cell .inner_cell a:hover{color:inherit;text-decoration:none}@media(max-width:540px){div.unrecognized_cell>div.prompt{display:none}}@media print{div.code_cell{page-break-inside:avoid}}div.input{page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}@media(max-width:540px){div.input{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}}div.input_prompt{color:#303f9f;border-top:1px solid transparent}div.input_area>div.highlight{margin:0;border:0;padding:0;background-color:transparent}div.input_area>div.highlight>pre{margin:0;border:0;padding:.4em}.CodeMirror{line-height:1.21429em;font-size:14px;height:auto;background:0}.CodeMirror-scroll{overflow-y:hidden;overflow-x:auto}.CodeMirror-lines{padding:.4em}.CodeMirror-linenumber{padding:0 8px 0 4px}.CodeMirror-gutters{border-bottom-left-radius:2px;border-top-left-radius:2px}.CodeMirror pre{padding:0;border:0;border-radius:0}.highlight-base{color:#000}.highlight-variable{color:#000}.highlight-variable-2{color:#1a1a1a}.highlight-variable-3{color:#333}.highlight-string{color:#ba2121}.highlight-comment{color:#408080;font-style:italic}.highlight-number{color:#080}.highlight-atom{color:#88F}.highlight-keyword{color:#008000;font-weight:bold}.highlight-builtin{color:#008000}.highlight-error{color:red}.highlight-operator{color:#a2f;font-weight:bold}.highlight-meta{color:#a2f}.highlight-def{color:#00f}.highlight-string-2{color:#f50}.highlight-qualifier{color:#555}.highlight-bracket{color:#997}.highlight-tag{color:#170}.highlight-attribute{color:#00c}.highlight-header{color:blue}.highlight-quote{color:#090}.highlight-link{color:#00c}.cm-s-ipython span.cm-keyword{color:#008000;font-weight:bold}.cm-s-ipython span.cm-atom{color:#88F}.cm-s-ipython span.cm-number{color:#080}.cm-s-ipython span.cm-def{color:#00f}.cm-s-ipython span.cm-variable{color:#000}.cm-s-ipython span.cm-operator{color:#a2f;font-weight:bold}.cm-s-ipython span.cm-variable-2{color:#1a1a1a}.cm-s-ipython span.cm-variable-3{color:#333}.cm-s-ipython span.cm-comment{color:#408080;font-style:italic}.cm-s-ipython span.cm-string{color:#ba2121}.cm-s-ipython span.cm-string-2{color:#f50}.cm-s-ipython span.cm-meta{color:#a2f}.cm-s-ipython span.cm-qualifier{color:#555}.cm-s-ipython span.cm-builtin{color:#008000}.cm-s-ipython span.cm-bracket{color:#997}.cm-s-ipython span.cm-tag{color:#170}.cm-s-ipython span.cm-attribute{color:#00c}.cm-s-ipython span.cm-header{color:blue}.cm-s-ipython span.cm-quote{color:#090}.cm-s-ipython span.cm-link{color:#00c}.cm-s-ipython span.cm-error{color:red}.cm-s-ipython span.cm-tab{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);background-position:right;background-repeat:no-repeat}div.output_wrapper{position:relative;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch;z-index:1}div.output_scroll{height:24em;width:100%;overflow:auto;border-radius:2px;-webkit-box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);box-shadow:inset 0 2px 8px rgba(0,0,0,0.8);display:block}div.output_collapsed{margin:0;padding:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}div.out_prompt_overlay{height:100%;padding:0 .4em;position:absolute;border-radius:2px}div.out_prompt_overlay:hover{-webkit-box-shadow:inset 0 0 1px #000;box-shadow:inset 0 0 1px #000;background:rgba(240,240,240,0.5)}div.output_prompt{color:#d84315}div.output_area{padding:0;page-break-inside:avoid;display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}div.output_area .MathJax_Display{text-align:left !important}div.output_area .rendered_html table{margin-left:0;margin-right:0}div.output_area .rendered_html img{margin-left:0;margin-right:0}div.output_area img,div.output_area svg{max-width:100%;height:auto}div.output_area img.unconfined,div.output_area svg.unconfined{max-width:none}div.output_area .mglyph>img{max-width:none}.output{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}@media(max-width:540px){div.output_area{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;display:flex;flex-direction:column;align-items:stretch}}div.output_area pre{margin:0;padding:0;border:0;vertical-align:baseline;color:black;background-color:transparent;border-radius:0}div.output_subarea{overflow-x:auto;padding:.4em;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;flex:1;max-width:calc(100% - 14ex)}div.output_scroll div.output_subarea{overflow-x:visible}div.output_text{text-align:left;color:#000;line-height:1.21429em}div.output_stderr{background:#fdd}div.output_latex{text-align:left}div.output_javascript:empty{padding:0}.js-error{color:darkred}div.raw_input_container{line-height:1.21429em;padding-top:5px}input.raw_input{font-family:monospace;font-size:inherit;color:inherit;width:auto;vertical-align:baseline;padding:0 .25em;margin:0 .25em}input.raw_input:focus{box-shadow:none}p.p-space{margin-bottom:10px}div.output_unrecognized{padding:5px;font-weight:bold;color:red}div.output_unrecognized a{color:inherit;text-decoration:none}div.output_unrecognized a:hover{color:inherit;text-decoration:none}.rendered_html{color:#000}.rendered_html em{font-style:italic}.rendered_html strong{font-weight:bold}.rendered_html u{text-decoration:underline}.rendered_html :link{text-decoration:underline}.rendered_html :visited{text-decoration:underline}.rendered_html h1{font-size:185.7%;margin:1.08em 0 0 0;font-weight:bold;line-height:1.0}.rendered_html h2{font-size:157.1%;margin:1.27em 0 0 0;font-weight:bold;line-height:1.0}.rendered_html h3{font-size:128.6%;margin:1.55em 0 0 0;font-weight:bold;line-height:1.0}.rendered_html h4{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1.0}.rendered_html h5{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1.0;font-style:italic}.rendered_html h6{font-size:100%;margin:2em 0 0 0;font-weight:bold;line-height:1.0;font-style:italic}.rendered_html h1:first-child{margin-top:.538em}.rendered_html h2:first-child{margin-top:.636em}.rendered_html h3:first-child{margin-top:.777em}.rendered_html h4:first-child{margin-top:1em}.rendered_html h5:first-child{margin-top:1em}.rendered_html h6:first-child{margin-top:1em}.rendered_html ul:not(.list-inline),.rendered_html ol:not(.list-inline){padding-left:2em}.rendered_html ul{list-style:disc}.rendered_html ul ul{list-style:square}.rendered_html ul ul ul{list-style:circle}.rendered_html ol{list-style:decimal}.rendered_html ol ol{list-style:upper-alpha}.rendered_html ol ol ol{list-style:lower-alpha}.rendered_html ol ol ol ol{list-style:lower-roman}.rendered_html ol ol ol ol ol{list-style:decimal}.rendered_html *+ul{margin-top:1em}.rendered_html *+ol{margin-top:1em}.rendered_html hr{color:black;background-color:black}.rendered_html pre{margin:1em 2em}.rendered_html pre,.rendered_html code{border:0;background-color:#fff;color:#000;font-size:100%;padding:0}.rendered_html blockquote{margin:1em 2em}.rendered_html table{margin-left:auto;margin-right:auto;border:0;border-collapse:collapse;border-spacing:0;color:black;font-size:12px;table-layout:fixed}.rendered_html thead{border-bottom:1px solid black;vertical-align:bottom}.rendered_html tr,.rendered_html th,.rendered_html td{text-align:right;vertical-align:middle;padding:.5em .5em;line-height:normal;white-space:normal;max-width:none;border:0}.rendered_html th{font-weight:bold}.rendered_html tbody tr:nth-child(odd){background:#f5f5f5}.rendered_html tbody tr:hover{background:rgba(66,165,245,0.2)}.rendered_html *+table{margin-top:1em}.rendered_html p{text-align:left}.rendered_html *+p{margin-top:1em}.rendered_html img{display:block;margin-left:auto;margin-right:auto}.rendered_html *+img{margin-top:1em}.rendered_html img,.rendered_html svg{max-width:100%;height:auto}.rendered_html img.unconfined,.rendered_html svg.unconfined{max-width:none}.rendered_html .alert{margin-bottom:initial}.rendered_html *+.alert{margin-top:1em}div.text_cell{display:-webkit-box;-webkit-box-orient:horizontal;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:horizontal;-moz-box-align:stretch;display:box;box-orient:horizontal;box-align:stretch;display:flex;flex-direction:row;align-items:stretch}@media(max-width:540px){div.text_cell>div.prompt{display:none}}div.text_cell_render{outline:0;resize:none;width:inherit;border-style:none;padding:.5em .5em .5em .4em;color:#000;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}a.anchor-link:link{text-decoration:none;padding:0 20px;visibility:hidden}h1:hover .anchor-link,h2:hover .anchor-link,h3:hover .anchor-link,h4:hover .anchor-link,h5:hover .anchor-link,h6:hover .anchor-link{visibility:visible}.text_cell.rendered .input_area{display:none}.text_cell.rendered .rendered_html{overflow-x:auto;overflow-y:hidden}.text_cell.rendered .rendered_html tr,.text_cell.rendered .rendered_html th,.text_cell.rendered .rendered_html td{max-width:none}.text_cell.unrendered .text_cell_render{display:none}.text_cell .dropzone .input_area{border:2px dashed #bababa;margin:-1px}.cm-header-1,.cm-header-2,.cm-header-3,.cm-header-4,.cm-header-5,.cm-header-6{font-weight:bold;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.cm-header-1{font-size:185.7%}.cm-header-2{font-size:157.1%}.cm-header-3{font-size:128.6%}.cm-header-4{font-size:110%}.cm-header-5{font-size:100%;font-style:italic}.cm-header-6{font-size:100%;font-style:italic} diff --git a/public/assets/css/nikola_ipython.css b/public/assets/css/nikola_ipython.css new file mode 100644 --- /dev/null +++ b/public/assets/css/nikola_ipython.css @@ -0,0 +1,56 @@ +div.prompt { + padding: 0.6em; + font-size: 13px; + background-color: #E9E9E9; + margin-right: 1em; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +div.output_prompt { + /* 5px right shift to account for margin in parent container */ + margin: 0 5px 0 0px; +} + +div.output_area pre { + font-size: 13px; +} + +div.text_cell_render { + padding: 0px; + color: #333333; +} + +.rendered_html p { + text-align: left; +} + +.rendered_html ul { + margin: 0 0 12px 25px; +} + +.rendered_html :visited { + text-decoration: none; +} + +.rendered_html :link { + text-decoration: none; +} + +.rendered_html pre, .rendered_html code { + background-color: #DDDDDD; + margin: 1em 0em; + font-size: 14px; +} + +.rendered_html pre { + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.05em; + padding-bottom: 0.05em; +} + +.page-content > .content p { + margin: 0 0 0px; +} diff --git a/public/assets/css/nikola_rst.css b/public/assets/css/nikola_rst.css new file mode 100644 --- /dev/null +++ b/public/assets/css/nikola_rst.css @@ -0,0 +1,64 @@ +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning, div.sidebar, +div.system-message { +/* stolen from Boostrap 4 (.card) */ + margin-bottom: 2rem; + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + color: #212529; + background-clip: border-box; + border: 1px solid rgba(0,0,0,.125); + border-radius: .25rem; + padding: 0; +} + +div.attention, div.caution, div.danger, div.error, div.warning { + /* stolen from Boostrap 3 (.border-danger) */ + border-color: #dc3545!important; +} + +div.admonition p, div.hint p, +div.important p, div.note p, +div.tip p, div.sidebar p, +div.attention p, div.caution p, +div.danger p, div.error p, +div.warning p, div.system-message p { + padding-left: 1rem; + padding-right: 1rem; +} + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title, div.sidebar p.sidebar-title, +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, div.system-message p.system-message-title { +/* stolen from Boostrap 4 (.card .card-header) */ + font-weight: 400; + font-size: 1.25rem; + padding: .75rem 1.25rem; + margin-bottom: 1rem; + background-color: rgba(0,0,0,.03); + border-bottom: 1px solid rgba(0,0,0,.125); +} + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, div.system-message p.system-message-title { + /* stolen from Boostrap 4 (.card .card-header .bg-danger) */ + background-color: #dc3545; + color: white; +} + +div.sidebar { + margin-right: 0; +} diff --git a/public/assets/css/rst.css b/public/assets/css/rst.css new file mode 100644 --- /dev/null +++ b/public/assets/css/rst.css @@ -0,0 +1,2 @@ + at import url("rst_base.css"); + at import url("nikola_rst.css"); diff --git a/public/assets/css/rst_base.css b/public/assets/css/rst_base.css new file mode 100644 --- /dev/null +++ b/public/assets/css/rst_base.css @@ -0,0 +1,474 @@ +/* Minimal style sheet for the HTML output of Docutils. */ +/* */ +/* :Author: Günter Milde, based on html4css1.css by David Goodger */ +/* :Id: $Id: minimal.css 7952 2016-07-26 18:15:59Z milde $ */ +/* :Copyright: © 2015 Günter Milde. */ +/* :License: Released under the terms of the `2-Clause BSD license`_, */ +/* in short: */ +/* */ +/* Copying and distribution of this file, with or without modification, */ +/* are permitted in any medium without royalty provided the copyright */ +/* notice and this notice are preserved. */ +/* */ +/* This file is offered as-is, without any warranty. */ +/* */ +/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */ + +/* This CSS2.1_ stylesheet defines rules for Docutils elements without */ +/* HTML equivalent. It is required to make the document semantic visible. */ +/* */ +/* .. _CSS2.1: http://www.w3.org/TR/CSS2 */ +/* .. _validates: http://jigsaw.w3.org/css-validator/validator$link */ + +/* alignment of text and inline objects inside block objects*/ +.align-left { text-align: left; } +.align-right { text-align: right; } +.align-center { clear: both; text-align: center; } +.align-top { vertical-align: top; } +.align-middle { vertical-align: middle; } +.align-bottom { vertical-align: bottom; } + +/* titles */ +h1.title, p.subtitle { + text-align: center; +} +p.admonition-title, +p.topic-title, +p.sidebar-title, +p.rubric, +p.system-message-title { + font-weight: bold; +} +h1 + p.subtitle, +h1 + p.section-subtitle { + font-size: 1.6em; +} +h2 + p.section-subtitle { font-size: 1.28em; } +p.subtitle, +p.section-subtitle, +p.sidebar-subtitle { + font-weight: bold; + margin-top: -0.5em; +} +p.sidebar-title, +p.rubric { + font-size: larger; +} +p.rubric { color: maroon; } +a.toc-backref { + color: black; + text-decoration: none; } + +/* Warnings, Errors */ +div.caution p.admonition-title, +div.attention p.admonition-title, +div.danger p.admonition-title, +div.error p.admonition-title, +div.warning p.admonition-title, +div.system-messages h1, +div.error, +span.problematic, +p.system-message-title { + color: red; +} + +/* inline literals */ +span.docutils.literal { + font-family: monospace; + white-space: pre-wrap; +} +/* do not wraph at hyphens and similar: */ +.literal > span.pre { white-space: nowrap; } + +/* Lists */ + +/* compact and simple lists: no margin between items */ +.simple li, .compact li, +.simple ul, .compact ul, +.simple ol, .compact ol, +.simple > li p, .compact > li p, +dl.simple > dd, dl.compact > dd { + margin-top: 0; + margin-bottom: 0; +} + +/* Table of Contents */ +/*div.topic.contents { margin: 0; }*/ +ul.auto-toc { + list-style-type: none; + padding-left: 1.5em; } + +/* Enumerated Lists */ +ol.arabic { list-style: decimal } +ol.loweralpha { list-style: lower-alpha } +ol.upperalpha { list-style: upper-alpha } +ol.lowerroman { list-style: lower-roman } +ol.upperroman { list-style: upper-roman } + +dt span.classifier { font-style: italic } +dt span.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + +/* Field Lists and drivatives */ +/* bold field name, content starts on the same line */ +dl.field-list > dt, +dl.option-list > dt, +dl.docinfo > dt, +dl.footnote > dt, +dl.citation > dt { + font-weight: bold; + clear: left; + float: left; + margin: 0; + padding: 0; + padding-right: 0.5em; +} +/* Offset for field content (corresponds to the --field-name-limit option) */ +dl.field-list > dd, +dl.option-list > dd, +dl.docinfo > dd { + margin-left: 9em; /* ca. 14 chars in the test examples */ +} +/* start field-body on a new line after long field names */ +dl.field-list > dd > *:first-child, +dl.option-list > dd > *:first-child +{ + display: inline-block; + width: 100%; + margin: 0; +} +/* field names followed by a colon */ +dl.field-list > dt:after, +dl.docinfo > dt:after { + content: ":"; +} + +/* Bibliographic Fields (docinfo) */ +pre.address { font: inherit; } +dd.authors > p { margin: 0; } + +/* Option Lists */ +dl.option-list { margin-left: 40px; } +dl.option-list > dt { font-weight: normal; } +span.option { white-space: nowrap; } + +/* Footnotes and Citations */ +dl.footnote.superscript > dd {margin-left: 1em; } +dl.footnote.brackets > dd {margin-left: 2em; } +dl > dt.label { font-weight: normal; } +a.footnote-reference.brackets:before, +dt.label > span.brackets:before { content: "["; } +a.footnote-reference.brackets:after, +dt.label > span.brackets:after { content: "]"; } +a.footnote-reference.superscript, +dl.footnote.superscript > dt.label { + vertical-align: super; + font-size: smaller; +} +dt.label > span.fn-backref { margin-left: 0.2em; } +dt.label > span.fn-backref > a { font-style: italic; } + +/* Line Blocks */ +div.line-block { display: block; } +div.line-block div.line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 40px; +} + +/* Figures, Images, and Tables */ +.figure.align-left, +img.align-left, +object.align-left, +table.align-left { + margin-right: auto; +} +.figure.align-center, +img.align-center, +object.align-center { + margin-left: auto; + margin-right: auto; + display: block; +} +table.align-center { + margin-left: auto; + margin-right: auto; +} +.figure.align-right, +img.align-right, +object.align-right, +table.align-right { + margin-left: auto; +} +/* reset inner alignment in figures and tables */ +div.align-left, div.align-center, div.align-right, +table.align-left, table.align-center, table.align-right +{ text-align: inherit } + +/* Admonitions and System Messages */ +div.admonition, +div.system-message, +div.sidebar{ + margin: 40px; + border: medium outset; + padding-right: 1em; + padding-left: 1em; +} + +/* Sidebar */ +div.sidebar { + width: 30%; + max-width: 26em; + float: right; + clear: right; +} + +/* Text Blocks */ +div.topic, +pre.literal-block, +pre.doctest-block, +pre.math, +pre.code { + margin-right: 40px; + margin-left: 40px; +} +pre.code .ln { color: gray; } /* line numbers */ + +/* Tables */ +table.docutils { border-collapse: collapse; } +table.docutils > td, table.docutils > th { + border-style: solid; + border-color: silver; + padding: 0 1ex; + border-width: thin; +} +table.docutils > td > p:first-child, table.docutils > th > p:first-child { margin-top: 0; } +table.docutils > td > p, table.docutils > th > p { margin-bottom: 0; } + +table.docutils > caption { + text-align: left; + margin-bottom: 0.25em +} + +table.borderless td, table.borderless th { + border: 0; + padding: 0; + padding-right: 0.5em /* separate table cells */ +} + +/* CSS31_ style sheet for the output of Docutils HTML writers. */ +/* Rules for easy reading and pre-defined style variants. */ +/* */ +/* :Author: Günter Milde, based on html4css1.css by David Goodger */ +/* :Id: $Id: plain.css 7952 2016-07-26 18:15:59Z milde $ */ +/* :Copyright: © 2015 Günter Milde. */ +/* :License: Released under the terms of the `2-Clause BSD license`_, */ +/* in short: */ +/* */ +/* Copying and distribution of this file, with or without modification, */ +/* are permitted in any medium without royalty provided the copyright */ +/* notice and this notice are preserved. */ +/* */ +/* This file is offered as-is, without any warranty. */ +/* */ +/* .. _2-Clause BSD license: http://www.spdx.org/licenses/BSD-2-Clause */ +/* .. _CSS3: http://www.w3.org/TR/CSS3 */ + + +/* Document Structure */ +/* ****************** */ + +/* Sections */ + +/* Transitions */ + +hr.docutils { + width: 80%; + margin-top: 1em; + margin-bottom: 1em; + clear: both; +} From pypy.commits at gmail.com Wed Jan 8 03:41:57 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 00:41:57 -0800 (PST) Subject: [pypy-commit] pypy.org nikola: fix two typos Message-ID: <5e1595d5.1c69fb81.336b0.fcdb@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: nikola Changeset: r971:8c85569a1071 Date: 2020-01-08 09:38 +0100 http://bitbucket.org/pypy/pypy.org/changeset/8c85569a1071/ Log: fix two typos diff --git a/pages/index.rst b/pages/index.rst --- a/pages/index.rst +++ b/pages/index.rst @@ -41,14 +41,14 @@ .. class:: small -On average, PyPy is **4.4 times faser** than CPython +On average, PyPy is **4.4 times faster** than CPython .. figure:: images/pypy_speed_graph.png :alt: PyPy vs. Python speed comparison graph" :figclass: text-sm PyPy trunk (with JIT) benchmark times normalized to CPython. Smaller is - better. Based on he geometric average of all benchmarks + better. Based on the geometric average of all benchmarks .. raw:: html diff --git a/public/archive.html b/public/archive.html --- a/public/archive.html +++ b/public/archive.html @@ -61,7 +61,7 @@

No posts found.

diff --git a/public/blog/index.html b/public/blog/index.html --- a/public/blog/index.html +++ b/public/blog/index.html @@ -64,7 +64,7 @@ diff --git a/public/categories/index.html b/public/categories/index.html --- a/public/categories/index.html +++ b/public/categories/index.html @@ -63,7 +63,7 @@ diff --git a/public/compat.html b/public/compat.html --- a/public/compat.html +++ b/public/compat.html @@ -109,11 +109,11 @@ not support refcounting semantics. The following code won't fill the file immediately, but only after a certain period of time, when the GC does a collection:

-
open("filename", "w").write("stuff")
+
open("filename", "w").write("stuff")
 

The proper fix is

-
with open("filename", "w") as f:
-    f.write("stuff")
+
with open("filename", "w") as f:
+    f.write("stuff")
 

The same problem---not closing your files---can also show up if your program opens a large number of files without closing them explicitly. @@ -127,22 +127,22 @@

Similarly, remember that you must close() a non-exhausted generator in order to have its pending finally or with clauses executed immediately:

-
def mygen():
-    with foo:
-        yield 42
-
-for x in mygen():
-    if x == 42:
-        break    # foo.__exit__ is not run immediately!
-
-# fixed version:
-gen = mygen()
-try:
-    for x in gen:
-        if x == 42:
-            break
-finally:
-    gen.close()
+
def mygen():
+    with foo:
+        yield 42
+
+for x in mygen():
+    if x == 42:
+        break    # foo.__exit__ is not run immediately!
+
+# fixed version:
+gen = mygen()
+try:
+    for x in gen:
+        if x == 42:
+            break
+finally:
+    gen.close()
 

More generally, __del__() methods are not executed as predictively as on CPython: they run "some time later" in PyPy (or not at all if @@ -163,7 +163,7 @@

diff --git a/public/contact.html b/public/contact.html --- a/public/contact.html +++ b/public/contact.html @@ -82,7 +82,7 @@ diff --git a/public/download.html b/public/download.html --- a/public/download.html +++ b/public/download.html @@ -257,11 +257,11 @@ trunk using Mercurial. The trunk usually works and is of course more up-to-date. The following command should run in about 7 minutes nowadays if you have hg >= 3.7 (it is much slower with older versions):

-
hg clone https://bitbucket.org/pypy/pypy
+
hg clone https://bitbucket.org/pypy/pypy
 

The trunk contains PyPy 2. For PyPy 3, switch to the correct branch:

-
# switch to the branch that implements Python 3.6
-hg update py3.6
+
# switch to the branch that implements Python 3.6
+hg update py3.6
 

Alternatively, get one of the following smaller packages for the source at the same revision as the above binaries:

@@ -275,19 +275,19 @@
  • Enter the goal directory:

    -
    cd pypy/pypy/goal
    +
    cd pypy/pypy/goal
     
  • Run the rpython script. Here are the common combinations of options (works also with python instead of pypy; requires CPython 2.7 or PyPy 2, even to build PyPy 3):

    -
    # get the JIT version
    -pypy ../../rpython/bin/rpython -Ojit targetpypystandalone
    -# get the no-jit version
    -pypy ../../rpython/bin/rpython -O2 targetpypystandalone
    -# get the sandbox version
    -pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone
    +
    # get the JIT version
    +pypy ../../rpython/bin/rpython -Ojit targetpypystandalone
    +# get the no-jit version
    +pypy ../../rpython/bin/rpython -O2 targetpypystandalone
    +# get the sandbox version
    +pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone
     
  • Enjoy Mandelbrot :-) It takes on the order of half an hour to @@ -320,9 +320,9 @@ call it with ...pypy-c ../../rpython/bin/rpython -Ojit.

    2. if even using PyPy instead of CPython is not enough, try to tweak some internal parameters. Example (slower but saves around 400MB):

    -
    PYPY_DONT_RUN_SUBPROCESS=1 PYPY_GC_MAX_DELTA=200MB \
    -pypy --jit loop_longevity=300 ../../rpython/bin/rpython -Ojit --source
    -# then read the next point about --source
    +
    PYPY_DONT_RUN_SUBPROCESS=1 PYPY_GC_MAX_DELTA=200MB \
    +pypy --jit loop_longevity=300 ../../rpython/bin/rpython -Ojit --source
    +# then read the next point about --source
     
  • You can run translations with --source, which only builds the C @@ -343,9 +343,9 @@

    Once PyPy is translated from source the binary package similar to those provided in the section Default (with a JIT Compiler) above could be easily created with package.py script:

    -
    cd ./pypy/pypy/tool/release/
    -python package.py --help #for information
    -python package.py --archive-name pypy-my-own-package-name
    +
    cd ./pypy/pypy/tool/release/
    +python package.py --help #for information
    +python package.py --archive-name pypy-my-own-package-name
     

    It is recommended to use package.py because custom scripts will invariably become out-of-date. If you want to write custom scripts @@ -455,7 +455,7 @@

    diff --git a/public/features.html b/public/features.html --- a/public/features.html +++ b/public/features.html @@ -157,16 +157,16 @@ build pypy-sandbox from it (see Building from source). These instructions give you a pypy-c that you should rename to pypy-sandbox to avoid future confusion. Then run:

    -
    cd pypy/sandbox
    -pypy_interact.py path/to/pypy-sandbox
    -# don't confuse it with pypy/goal/pyinteractive.py!
    +
    cd pypy/sandbox
    +pypy_interact.py path/to/pypy-sandbox
    +# don't confuse it with pypy/goal/pyinteractive.py!
     

    You get a fully sandboxed interpreter, in its own filesystem hierarchy (try os.listdir('/')). For example, you would run an untrusted script as follows:

    -
    mkdir virtualtmp
    -cp untrusted.py virtualtmp/
    -pypy_interact.py --tmp=virtualtmp pypy-sandbox /tmp/untrusted.py
    +
    mkdir virtualtmp
    +cp untrusted.py virtualtmp/
    +pypy_interact.py --tmp=virtualtmp pypy-sandbox /tmp/untrusted.py
     

    Note that the path /tmp/untrusted.py is a path inside the sandboxed filesystem. You don't have to put untrusted.py in the real /tmp @@ -180,7 +180,7 @@

    diff --git a/public/index.html b/public/index.html --- a/public/index.html +++ b/public/index.html @@ -20,15 +20,12 @@ - @@ -75,25 +72,20 @@
    -
    -
    +
    PyPy logo

    A fast, compliant alternative implementation of Python

    Get Started : Download and install

    What is PyPy : Features

    Documentation (external link)

    -
    -
    -

    On average, PyPy is 4.4 times faser than CPython

    -
    -PyPy vs. Python speed comparison graph"

    PyPy trunk (with JIT) benchmark times normalized to CPython. Smaller is -better. Based on he geometric average of all benchmarks

    -
    -
    -
    "If you want your code to run faster,
     you should probably just use PyPy."
     -- Guido van Rossum (creator of Python)
    +

    On average, PyPy is 4.4 times faster than CPython

    +
    +PyPy vs. Python speed comparison graph"

    PyPy trunk (with JIT) benchmark times normalized to CPython. Smaller is +better. Based on the geometric average of all benchmarks

    +

    Advantages and distinct Features

    • Speed: thanks to its Just-in-Time compiler, Python programs @@ -108,11 +100,12 @@

    • As well as other features.

    +
    diff --git a/public/index.rst b/public/index.rst --- a/public/index.rst +++ b/public/index.rst @@ -34,32 +34,22 @@ .. _`What is PyPy`: features.html .. _`Documentation`: https://doc.pypy.org -.. raw:: html - -
    +:: -.. class:: small + "If you want your code to run faster, + you should probably just use PyPy." + -- Guido van Rossum (creator of Python) -On average, PyPy is **4.4 times faser** than CPython +On average, PyPy is **4.4 times faster** than CPython .. figure:: images/pypy_speed_graph.png :alt: PyPy vs. Python speed comparison graph" :figclass: text-sm PyPy trunk (with JIT) benchmark times normalized to CPython. Smaller is - better. Based on he geometric average of all benchmarks + better. Based on the geometric average of all benchmarks -.. raw:: html - -
    - - -:: - - "If you want your code to run faster, - you should probably just use PyPy." - -- Guido van Rossum (creator of Python) **Advantages and distinct Features** diff --git a/public/people.html b/public/people.html --- a/public/people.html +++ b/public/people.html @@ -188,7 +188,7 @@ diff --git a/public/performance.html b/public/performance.html --- a/public/performance.html +++ b/public/performance.html @@ -235,13 +235,13 @@

    String concatenation is expensive

    In CPython, you may want to replace:

    -
    s = head + body + maybe + tail
    +
    s = head + body + maybe + tail
     

    with the admittedly less readable:

    -
    s = "%(head)s%(body)s%(maybe)s%(tail)s" % locals()
    +
    s = "%(head)s%(body)s%(maybe)s%(tail)s" % locals()
     

    or even:

    -
    s = "{head}{body}{maybe}{tail}".format(**locals())
    +
    s = "{head}{body}{maybe}{tail}".format(**locals())
     

    Both of the latter forms avoid multiple-allocation overhead. But PyPy's JIT makes the overhead of intermediate concatenations @@ -249,8 +249,8 @@ small, bound and constant. (And locals() is rather slow with PyPy's JIT.)

    On the other hand, in code like this with a string-valued foo() function:

    -
    for x in mylist:
    -    s += foo(x)
    +
    for x in mylist:
    +    s += foo(x)
     

    the JIT cannot optimize out intermediate copies. This code is actually quadratic in the total size of the mylist strings due to @@ -258,10 +258,10 @@ is always fine for bytearrays, because in this case += is an in-place operation.)

    This:

    -
    parts = []
    -for x in mylist:
    -    parts.append(foo(x))
    -s = "".join(parts)
    +
    parts = []
    +for x in mylist:
    +    parts.append(foo(x))
    +s = "".join(parts)
     

    can be much faster because all the string concatenation in the last line creates exactly one new string object with one C-level copy @@ -373,7 +373,7 @@

    diff --git a/public/rss.xml b/public/rss.xml --- a/public/rss.xml +++ b/public/rss.xml @@ -1,2 +1,2 @@ -PyPyhttps://www.pypy.org/A Faster PythonenContents © 2019 <a href="mailto:pypy-dev at pypy.org">The PyPy Team</a> Mon, 30 Dec 2019 07:43:17 GMTNikola (getnikola.com)http://blogs.law.harvard.edu/tech/rss \ No newline at end of file +PyPyhttps://www.pypy.org/A Faster PythonenContents © 2020 <a href="mailto:pypy-dev at pypy.org">The PyPy Team</a> Wed, 08 Jan 2020 08:33:50 GMTNikola (getnikola.com)http://blogs.law.harvard.edu/tech/rss \ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -7,42 +7,42 @@ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> https://www.pypy.org/ - 2019-12-30T13:22:00Z + 2020-01-08T08:35:00Z https://www.pypy.org/archive.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/blog/ - 2019-12-30T07:43:00Z + 2020-01-08T05:16:00Z https://www.pypy.org/categories/ - 2019-12-30T07:43:00Z + 2020-01-08T05:16:00Z https://www.pypy.org/compat.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/contact.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/download.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/features.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/people.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/performance.html - 2019-12-30T13:28:00Z + 2020-01-08T08:33:00Z \ No newline at end of file diff --git a/public/sitemapindex.xml b/public/sitemapindex.xml --- a/public/sitemapindex.xml +++ b/public/sitemapindex.xml @@ -7,10 +7,10 @@ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> https://www.pypy.org/rss.xml - 2019-12-30T07:43:00Z + 2020-01-08T08:33:00Z https://www.pypy.org/sitemap.xml - 2019-12-30T13:28:00Z + 2020-01-08T08:35:00Z \ No newline at end of file From pypy.commits at gmail.com Wed Jan 8 06:50:13 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 03:50:13 -0800 (PST) Subject: [pypy-commit] pypy py3.7: implement error message improvement of CPython Message-ID: <5e15c1f5.1c69fb81.13221.00ae@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98485:a4a502d7215c Date: 2020-01-08 12:31 +0100 http://bitbucket.org/pypy/pypy/changeset/a4a502d7215c/ Log: implement error message improvement of CPython diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -918,11 +918,23 @@ w_obj.getclass(self)) return w_obj + def _iter_unpackiterable(self, w_iterable): + try: + return self.iter(w_iterable) + except OperationError as e: + if e.got_any_traceback(): + raise + if not e.match(self, self.w_TypeError): + raise + raise oefmt(self.w_TypeError, + "cannot unpack non-iterable %T object", + w_iterable) + def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable into a real (interpreter-level) list. Raise an OperationError(w_ValueError) if the length is wrong.""" - w_iterator = self.iter(w_iterable) + w_iterator = self._iter_unpackiterable(w_iterable) if expected_length == -1: if self.is_generator(w_iterator): # special hack for speed @@ -999,7 +1011,7 @@ # Like unpackiterable(), but for the cases where we have # an expected_length and want to unroll when JITted. # Returns a fixed-size list. - w_iterator = self.iter(w_iterable) + w_iterator = self._iter_unpackiterable(w_iterable) assert expected_length != -1 return self._unpackiterable_known_length_jitlook(w_iterator, expected_length) diff --git a/pypy/interpreter/test/test_interpreter.py b/pypy/interpreter/test/test_interpreter.py --- a/pypy/interpreter/test/test_interpreter.py +++ b/pypy/interpreter/test/test_interpreter.py @@ -516,3 +516,13 @@ else: assert False, "Expected ValueError" """ + + def test_errormsg_unpacking(self): + with raises(TypeError) as excinfo: + a, b, c = 1 + assert str(excinfo.value) == "cannot unpack non-iterable int object" + + with raises(TypeError) as excinfo: + for a, b in range(10): + pass + assert str(excinfo.value) == "cannot unpack non-iterable int object" From pypy.commits at gmail.com Wed Jan 8 06:50:15 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 03:50:15 -0800 (PST) Subject: [pypy-commit] pypy py3.7: add repr to frames Message-ID: <5e15c1f7.1c69fb81.963ca.048e@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98486:628cfb318d11 Date: 2020-01-08 12:49 +0100 http://bitbucket.org/pypy/pypy/changeset/628cfb318d11/ Log: add repr to frames diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -951,6 +951,12 @@ self.space, operr, self, self.last_instr) raise operr + def descr_repr(self, space): + code = self.pycode + moreinfo = ", file '%s', line %s, code %s" % ( + code.co_filename, self.get_last_lineno(), code.co_name) + return self.getrepr(space, "frame", moreinfo) + # ____________________________________________________________ def get_block_class(opname): diff --git a/pypy/interpreter/test/test_pyframe.py b/pypy/interpreter/test/test_pyframe.py --- a/pypy/interpreter/test/test_pyframe.py +++ b/pypy/interpreter/test/test_pyframe.py @@ -111,3 +111,12 @@ assert res == 2 if hasattr(self, "check_no_w_locals"): # not appdirect assert self.check_no_w_locals(fh.frame) + + def test_repr(self): + import sys + def a_name(a, b, c): + a + b + c + return sys._getframe() + frame = a_name(5, 6, 4) + r = repr(frame) + assert "a_name" in r diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -658,6 +658,7 @@ f_code = GetSetProperty(PyFrame.fget_code), f_locals = GetSetProperty(PyFrame.fget_getdictscope), f_globals = GetSetProperty(PyFrame.fget_w_globals), + __repr__ = interp2app(PyFrame.descr_repr), ) assert not PyFrame.typedef.acceptable_as_base_class # no __new__ From pypy.commits at gmail.com Wed Jan 8 07:48:11 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 04:48:11 -0800 (PST) Subject: [pypy-commit] pypy default: move test_nestedscope.py to apptest_nestedscope.py Message-ID: <5e15cf8b.1c69fb81.983e2.055e@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98487:aeecc116648d Date: 2020-01-08 12:56 +0100 http://bitbucket.org/pypy/pypy/changeset/aeecc116648d/ Log: move test_nestedscope.py to apptest_nestedscope.py diff --git a/pypy/interpreter/test/test_nestedscope.py b/pypy/interpreter/test/apptest_nestedscope.py rename from pypy/interpreter/test/test_nestedscope.py rename to pypy/interpreter/test/apptest_nestedscope.py --- a/pypy/interpreter/test/test_nestedscope.py +++ b/pypy/interpreter/test/apptest_nestedscope.py @@ -1,137 +1,135 @@ +from pytest import raises +def test_nested_scope(): + x = 42 + def f(): return x + assert f() == 42 -class AppTestNestedScope: +def test_nested_scope2(): + x = 42 + y = 3 + def f(): return x + assert f() == 42 - def test_nested_scope(self): - x = 42 - def f(): return x - assert f() == 42 +def test_nested_scope3(): + x = 42 + def f(): + def g(): + return x + return g + assert f()() == 42 - def test_nested_scope2(self): - x = 42 - y = 3 - def f(): return x - assert f() == 42 +def test_nested_scope4(): + def f(): + x = 3 + def g(): + return x + a = g() + x = 4 + b = g() + return (a, b) + assert f() == (3, 4) - def test_nested_scope3(self): - x = 42 - def f(): - def g(): - return x - return g - assert f()() == 42 +def test_nested_scope_locals(): + def f(): + x = 3 + def g(): + i = x + return locals() + return g() + d = f() + assert d == {'i':3, 'x':3} - def test_nested_scope4(self): - def f(): - x = 3 - def g(): - return x - a = g() - x = 4 - b = g() - return (a, b) - assert f() == (3, 4) - - def test_nested_scope_locals(self): - def f(): - x = 3 - def g(): +def test_deeply_nested_scope_locals(): + def f(): + x = 3 + def g(): + def h(): i = x return locals() - return g() - d = f() - assert d == {'i':3, 'x':3} + return locals(), h() + return g() + outer_locals, inner_locals = f() + assert inner_locals == {'i':3, 'x':3} + keys = outer_locals.keys() + keys.sort() + assert keys == ['h', 'x'] - def test_deeply_nested_scope_locals(self): - def f(): - x = 3 - def g(): - def h(): - i = x - return locals() - return locals(), h() - return g() - outer_locals, inner_locals = f() - assert inner_locals == {'i':3, 'x':3} - keys = outer_locals.keys() - keys.sort() - assert keys == ['h', 'x'] +def test_lambda_in_genexpr(): + assert eval('map(apply, (lambda: t for t in range(10)))') == range(10) - def test_lambda_in_genexpr(self): - assert eval('map(apply, (lambda: t for t in range(10)))') == range(10) +def test_cell_repr(): + import re + from repr import repr as r # Don't shadow builtin repr - def test_cell_repr(self): - import re - from repr import repr as r # Don't shadow builtin repr + def get_cell(): + x = 42 + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'', repr(x)) + assert re.match(r'', r(x)) - def get_cell(): + def get_cell(): + if False: x = 42 - def inner(): + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'', repr(x)) + +def test_cell_contents(): + def f(x): + def f(y): + return x + y + return f + + g = f(10) + assert g.func_closure[0].cell_contents == 10 + +def test_empty_cell_contents(): + + def f(): + def f(y): + return x + y + return f + x = 1 + + g = f() + with raises(ValueError): + g.func_closure[0].cell_contents + +def test_compare_cells(): + def f(n): + if n: + x = 42 + def f(y): + return x + y + return f + + g0 = f(0).func_closure[0] + g1 = f(1).func_closure[0] + assert cmp(g0, g1) == -1 + +def test_leaking_class_locals(): + def f(x): + class X: + x = 12 + def f(self): return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'', repr(x)) - assert re.match(r'', r(x)) + locals() + return X + assert f(1).x == 12 - def get_cell(): - if False: - x = 42 - def inner(): - return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'', repr(x)) - - def test_cell_contents(self): - def f(x): - def f(y): - return x + y - return f - - g = f(10) - assert g.func_closure[0].cell_contents == 10 - - def test_empty_cell_contents(self): - - def f(): - def f(y): - return x + y - return f - x = 1 - - g = f() - with raises(ValueError): - g.func_closure[0].cell_contents - - def test_compare_cells(self): - def f(n): - if n: - x = 42 - def f(y): - return x + y - return f - - g0 = f(0).func_closure[0] - g1 = f(1).func_closure[0] - assert cmp(g0, g1) == -1 - - def test_leaking_class_locals(self): - def f(x): - class X: - x = 12 - def f(self): - return x - locals() - return X - assert f(1).x == 12 - - def test_nested_scope_locals_mutating_cellvars(self): - def f(): - x = 12 - def m(): - locals() - x - locals() - return x - return m - assert f()() == 12 +def test_nested_scope_locals_mutating_cellvars(): + def f(): + x = 12 + def m(): + locals() + x + locals() + return x + return m + assert f()() == 12 From pypy.commits at gmail.com Wed Jan 8 07:48:12 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 04:48:12 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5e15cf8c.1c69fb81.d6f82.37c1@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98488:966e088ca813 Date: 2020-01-08 13:04 +0100 http://bitbucket.org/pypy/pypy/changeset/966e088ca813/ Log: merge default diff too long, truncating to 2000 out of 2009 lines diff --git a/pypy/interpreter/test/test_nestedscope.py b/pypy/interpreter/test/apptest_nestedscope.py rename from pypy/interpreter/test/test_nestedscope.py rename to pypy/interpreter/test/apptest_nestedscope.py --- a/pypy/interpreter/test/test_nestedscope.py +++ b/pypy/interpreter/test/apptest_nestedscope.py @@ -1,171 +1,169 @@ +from pytest import raises +def test_nested_scope(): + x = 42 + def f(): return x + assert f() == 42 -class AppTestNestedScope: +def test_nested_scope2(): + x = 42 + y = 3 + def f(): return x + assert f() == 42 - def test_nested_scope(self): - x = 42 - def f(): return x - assert f() == 42 +def test_nested_scope3(): + x = 42 + def f(): + def g(): + return x + return g + assert f()() == 42 - def test_nested_scope2(self): - x = 42 - y = 3 - def f(): return x - assert f() == 42 +def test_nested_scope4(): + def f(): + x = 3 + def g(): + return x + a = g() + x = 4 + b = g() + return (a, b) + assert f() == (3, 4) - def test_nested_scope3(self): - x = 42 - def f(): - def g(): - return x - return g - assert f()() == 42 +def test_nested_scope_locals(): + def f(): + x = 3 + def g(): + i = x + return locals() + return g() + d = f() + assert d == {'i':3, 'x':3} - def test_nested_scope4(self): - def f(): - x = 3 - def g(): - return x - a = g() - x = 4 - b = g() - return (a, b) - assert f() == (3, 4) - - def test_nested_scope_locals(self): - def f(): - x = 3 - def g(): +def test_deeply_nested_scope_locals(): + def f(): + x = 3 + def g(): + def h(): i = x return locals() - return g() - d = f() - assert d == {'i':3, 'x':3} + return locals(), h() + return g() + outer_locals, inner_locals = f() + assert inner_locals == {'i':3, 'x':3} + keys = sorted(outer_locals.keys()) + assert keys == ['h', 'x'] - def test_deeply_nested_scope_locals(self): - def f(): - x = 3 - def g(): - def h(): - i = x - return locals() - return locals(), h() - return g() - outer_locals, inner_locals = f() - assert inner_locals == {'i':3, 'x':3} - keys = sorted(outer_locals.keys()) - assert keys == ['h', 'x'] +def test_lambda_in_genexpr(): + assert [x() for x in (lambda: x for x in range(10))] == list(range(10)) - def test_lambda_in_genexpr(self): - assert [x() for x in (lambda: x for x in range(10))] == list(range(10)) +def test_cell_repr(): + import re + from reprlib import repr as r # Don't shadow builtin repr - def test_cell_repr(self): - import re - from reprlib import repr as r # Don't shadow builtin repr + def get_cell(): + x = 42 + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'', repr(x)) + assert re.match(r'', r(x)) - def get_cell(): + def get_cell(): + if False: x = 42 - def inner(): + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'', repr(x)) + +def test_cell_contents(): + def f(x): + def f(y): + return x + y + return f + + g = f(10) + assert g.__closure__[0].cell_contents == 10 + +def test_empty_cell_contents(): + + def f(): + def f(y): + return x + y + return f + x = 1 + + g = f() + with raises(ValueError): + g.__closure__[0].cell_contents + +def test_compare_cells(): + def f(n): + if n: + x = n + def f(y): + return x + y + return f + + empty_cell_1 = f(0).__closure__[0] + empty_cell_2 = f(0).__closure__[0] + g1 = f(1).__closure__[0] + g2 = f(2).__closure__[0] + assert g1 < g2 + assert g1 <= g2 + assert g2 > g1 + assert g2 >= g1 + assert not g1 == g2 + assert g1 != g2 + # + assert empty_cell_1 == empty_cell_2 + assert not empty_cell_1 != empty_cell_2 + assert empty_cell_1 < g1 + +def test_leaking_class_locals(): + def f(x): + class X: + x = 12 + def f(self): return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'', repr(x)) - assert re.match(r'', r(x)) + locals() + return X + assert f(1).x == 12 - def get_cell(): - if False: - x = 42 - def inner(): - return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'', repr(x)) +def test_nested_scope_locals_mutating_cellvars(): + def f(): + x = 12 + def m(): + locals() + x + locals() + return x + return m + assert f()() == 12 - def test_cell_contents(self): - def f(x): - def f(y): - return x + y - return f - g = f(10) - assert g.__closure__[0].cell_contents == 10 +def test_unbound_local_after_del(): + """ + # #4617: It is now legal to delete a cell variable. + # The following functions must obviously compile, + # and give the correct error when accessing the deleted name. + def errorInOuter(): + y = 1 + del y + print(y) + def inner(): + return y - def test_empty_cell_contents(self): + def errorInInner(): + def inner(): + return y + y = 1 + del y + inner() - def f(): - def f(y): - return x + y - return f - x = 1 - - g = f() - with raises(ValueError): - g.__closure__[0].cell_contents - - def test_compare_cells(self): - def f(n): - if n: - x = n - def f(y): - return x + y - return f - - empty_cell_1 = f(0).__closure__[0] - empty_cell_2 = f(0).__closure__[0] - g1 = f(1).__closure__[0] - g2 = f(2).__closure__[0] - assert g1 < g2 - assert g1 <= g2 - assert g2 > g1 - assert g2 >= g1 - assert not g1 == g2 - assert g1 != g2 - # - assert empty_cell_1 == empty_cell_2 - assert not empty_cell_1 != empty_cell_2 - assert empty_cell_1 < g1 - - def test_leaking_class_locals(self): - def f(x): - class X: - x = 12 - def f(self): - return x - locals() - return X - assert f(1).x == 12 - - def test_nested_scope_locals_mutating_cellvars(self): - def f(): - x = 12 - def m(): - locals() - x - locals() - return x - return m - assert f()() == 12 - - - def test_unbound_local_after_del(self): - """ - # #4617: It is now legal to delete a cell variable. - # The following functions must obviously compile, - # and give the correct error when accessing the deleted name. - def errorInOuter(): - y = 1 - del y - print(y) - def inner(): - return y - - def errorInInner(): - def inner(): - return y - y = 1 - del y - inner() - - raises(UnboundLocalError, "errorInOuter()") - raises(NameError, "errorInInner()") - """ + raises(UnboundLocalError, "errorInOuter()") + raises(NameError, "errorInInner()") + """ diff --git a/rpython/rlib/unicodedata/generate_unicodedb.py b/rpython/rlib/unicodedata/generate_unicodedb.py --- a/rpython/rlib/unicodedata/generate_unicodedb.py +++ b/rpython/rlib/unicodedata/generate_unicodedb.py @@ -538,7 +538,7 @@ print >> outfile, '}' -def writeUnicodedata(version, table, outfile, base): +def writeUnicodedata(version, version_tuple, table, outfile, base): if base: print >> outfile, 'import %s as base_mod' % base base_mod = __import__(base) @@ -549,38 +549,47 @@ print >> outfile, 'version = %r' % version print >> outfile - if version < "4.1": + if version_tuple < (4, 1, 0): cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FA5 or" " 0x20000 <= code <= 0x2A6D6)") - elif version < "5": # don't know the exact limit + elif version_tuple < (5, 0, 0): # don't know the exact limit cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FBB or" " 0x20000 <= code <= 0x2A6D6)") - elif version < "6": + elif version_tuple < (6, 0, 0): cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FCB or" " 0x20000 <= code <= 0x2A6D6 or" " 0x2A700 <= code <= 0x2B734)") - elif version < "6.1": + elif version_tuple < (6, 1, 0): cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FCB or" " 0x20000 <= code <= 0x2A6D6 or" " 0x2A700 <= code <= 0x2B734 or" " 0x2B740 <= code <= 0x2B81D)") - elif version < "8": + elif version_tuple < (8, 0, 0): cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FCC or" " 0x20000 <= code <= 0x2A6D6 or" " 0x2A700 <= code <= 0x2B734 or" " 0x2B740 <= code <= 0x2B81D)") - else: + elif version_tuple == (9, 0, 0): cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" " 0x4E00 <= code <= 0x9FD5 or" " 0x20000 <= code <= 0x2A6D6 or" " 0x2A700 <= code <= 0x2B734 or" " 0x2B740 <= code <= 0x2B81D or" " 0x2B820 <= code <= 0x2CEA1)") + elif version_tuple == (11, 0, 0): + cjk_interval = ("(0x3400 <= code <= 0x4DB5 or" + " 0x4E00 <= code <= 0x9FEF or" + " 0x20000 <= code <= 0x2A6D6 or" + " 0x2A700 <= code <= 0x2B734 or" + " 0x2B740 <= code <= 0x2B81D or" + " 0x2B820 <= code <= 0x2CEA1)") + else: + raise ValueError("please look up CJK ranges and fix the script, e.g. here: https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)") write_character_names(outfile, table, base_mod) @@ -977,7 +986,8 @@ named_sequences = 'NamedSequences-%(version)s.txt', casefolding = 'CaseFolding-%(version)s.txt', ) - if options.unidata_version > '5': + version_tuple = tuple(int(x) for x in options.unidata_version.split(".")) + if version_tuple[0] > 5: filenames['special_casing'] = 'SpecialCasing-%(version)s.txt' filenames = dict((name, filename % dict(version=options.unidata_version)) for (name, filename) in filenames.items()) @@ -985,7 +995,7 @@ for (name, filename) in filenames.items()) table = read_unicodedata(files) - table.upper_lower_from_properties = (options.unidata_version >= '6') + table.upper_lower_from_properties = (version_tuple[0] >= 6) print >> outfile, '# UNICODE CHARACTER DATABASE' print >> outfile, '# This file was generated with the command:' print >> outfile, '# ', ' '.join(sys.argv) @@ -993,7 +1003,7 @@ print >> outfile, 'from rpython.rlib.rarithmetic import r_longlong' print >> outfile print >> outfile - writeUnicodedata(options.unidata_version, table, outfile, options.base) + writeUnicodedata(options.unidata_version, version_tuple, table, outfile, options.base) if __name__ == '__main__': main() diff --git a/rpython/rlib/unicodedata/test/test_ucd.py b/rpython/rlib/unicodedata/test/test_ucd.py --- a/rpython/rlib/unicodedata/test/test_ucd.py +++ b/rpython/rlib/unicodedata/test/test_ucd.py @@ -1,5 +1,6 @@ +import pytest from rpython.rlib.runicode import code_to_unichr, MAXUNICODE -from rpython.rlib.unicodedata import unicodedb_5_2_0 +from rpython.rlib.unicodedata import unicodedb_5_2_0, unicodedb_11_0_0 from rpython.rtyper.test.tool import BaseRtypingTest from rpython.translator.c.test.test_genc import compile @@ -26,3 +27,26 @@ assert got == 0xd808 # first char of a pair else: assert got == 0x12346 + +def test_cjk(): + cases = [ + ('3400', '4DB5'), + ('4E00', '9FEF'), + ('20000', '2A6D6'), + ('2A700', '2B734'), + ('2B740', '2B81D'), + ('2B820', '2CEA1'), + ] + for first, last in cases: + first = int(first, 16) + last = int(last, 16) + # Test at and inside the boundary + for i in (first, first + 1, last - 1, last): + charname = 'CJK UNIFIED IDEOGRAPH-%X'%i + assert unicodedb_11_0_0.lookup(charname) == i + # Test outside the boundary + for i in first - 1, last + 1: + charname = 'CJK UNIFIED IDEOGRAPH-%X'%i + with pytest.raises(KeyError): + unicodedb_11_0_0.lookup(charname) + diff --git a/rpython/rlib/unicodedata/unicodedb_11_0_0.py b/rpython/rlib/unicodedata/unicodedb_11_0_0.py --- a/rpython/rlib/unicodedata/unicodedb_11_0_0.py +++ b/rpython/rlib/unicodedata/unicodedb_11_0_0.py @@ -61172,7 +61172,7 @@ if not ('0' <= c <= '9' or 'A' <= c <= 'F'): raise KeyError code = int(cjk_code, 16) - if (0x3400 <= code <= 0x4DB5 or 0x4E00 <= code <= 0x9FA5 or 0x20000 <= code <= 0x2A6D6): + if (0x3400 <= code <= 0x4DB5 or 0x4E00 <= code <= 0x9FEF or 0x20000 <= code <= 0x2A6D6 or 0x2A700 <= code <= 0x2B734 or 0x2B740 <= code <= 0x2B81D or 0x2B820 <= code <= 0x2CEA1): return code raise KeyError @@ -61197,7 +61197,7 @@ return code def name(code): - if (0x3400 <= code <= 0x4DB5 or 0x4E00 <= code <= 0x9FA5 or 0x20000 <= code <= 0x2A6D6): + if (0x3400 <= code <= 0x4DB5 or 0x4E00 <= code <= 0x9FEF or 0x20000 <= code <= 0x2A6D6 or 0x2A700 <= code <= 0x2B734 or 0x2B740 <= code <= 0x2B81D or 0x2B820 <= code <= 0x2CEA1): return "CJK UNIFIED IDEOGRAPH-" + hex(code)[2:].upper() if 0xAC00 <= code <= 0xD7A3: # vl_code, t_code = divmod(code - 0xAC00, len(_hangul_T)) @@ -61255,10 +61255,12 @@ ('Ll', 'R', 'N', 7202), ('Lm', 'AL', 'N', 15362), ('Lm', 'L', 'A', 15362), +('Lm', 'L', 'A', 15394), ('Lm', 'L', 'H', 14338), ('Lm', 'L', 'H', 15362), -('Lm', 'L', 'N', 12290), +('Lm', 'L', 'N', 12322), ('Lm', 'L', 'N', 15362), +('Lm', 'L', 'N', 15394), ('Lm', 'L', 'W', 15362), ('Lm', 'ON', 'A', 15362), ('Lm', 'ON', 'N', 12290), @@ -61266,7 +61268,7 @@ ('Lm', 'R', 'N', 15362), ('Lo', 'AL', 'N', 4098), ('Lo', 'AL', 'N', 7170), -('Lo', 'L', 'A', 7170), +('Lo', 'L', 'A', 7202), ('Lo', 'L', 'H', 7170), ('Lo', 'L', 'N', 6146), ('Lo', 'L', 'N', 7170), @@ -61284,6 +61286,7 @@ ('Me', 'NSM', 'N', 12288), ('Mn', 'L', 'N', 14336), ('Mn', 'NSM', 'A', 14336), +('Mn', 'NSM', 'A', 14368), ('Mn', 'NSM', 'N', 14336), ('Mn', 'NSM', 'N', 15360), ('Mn', 'NSM', 'W', 14336), @@ -61293,8 +61296,11 @@ ('Nd', 'EN', 'Na', 6592), ('Nd', 'L', 'N', 6592), ('Nd', 'R', 'N', 6592), -('Nl', 'L', 'A', 7232), +('Nl', 'L', 'A', 7240), +('Nl', 'L', 'A', 7264), ('Nl', 'L', 'N', 7232), +('Nl', 'L', 'N', 7240), +('Nl', 'L', 'N', 7264), ('Nl', 'L', 'W', 7232), ('Nl', 'ON', 'N', 7232), ('No', 'AL', 'N', 4160), @@ -61417,6 +61423,8 @@ ('So', 'ET', 'N', 4096), ('So', 'ET', 'N', 7168), ('So', 'L', 'A', 4096), +('So', 'L', 'A', 4104), +('So', 'L', 'A', 4128), ('So', 'L', 'N', 4096), ('So', 'L', 'W', 4096), ('So', 'ON', 'A', 4096), @@ -61505,350 +61513,350 @@ 'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\xb6' ) _db_pages = ( -'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xd1\x8c\x8c\x81\x9e\x81\x8c\x8d\x96k\x8c\xacza{zCCCCCCCCCC{\x8c\xba\xb9\xba\x8c' -'\x8c66666666666666666666666666\x96\x8ck\xa6^\xa6\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x96\xb9k\xb9\x01' -'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xce\x84\x9e\x9e\x9a\x9e\xc9\x84\xa3\xc7+t\xb9\x07\xc4\xa6\xbe\xaeNN\xa3\x1b\x84\x86\xa3N+pUUU\x84' -'55555535555555553555555\xb13555553\x19\x19\x19\x1b\x1b\x1b\x1b\x19\x1b\x19\x19\x19\x1b\x19\x19\x1b\x1b\x19\x1b\x19\x19\x1b\x1b\x1b\xb1\x19\x19\x19\x1b\x19\x1b\x19\x1b' -'5\x195\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x195\x195\x1b5\x1b5\x1b5\x195\x1b5\x1b5\x1b5\x1b5\x1b3\x195\x1b5\x195\x1b5\x1b5\x193\x195\x1b5\x1b\x195\x1b5\x1b5\x1b3' -'\x193\x195\x195\x1b5\x19\x193\x195\x195\x1b5\x1b3\x195\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b3\x195\x1b5\x195\x1b5\x1b5\x1b5\x1b5\x1b5\x1b55\x1b5\x1b5\x1b\x1b' -'\x1b55\x1b5\x1b55\x1b555\x1b\x1b5555\x1b55\x1b555\x1b\x1b\x1b55\x1b55\x1b5\x1b5\x1b55\x1b5\x1b\x1b5\x1b55\x1b555\x1b5\x1b55\x1b\x1b.5\x1b\x1b\x1b' -'....52\x1b52\x1b52\x1b5\x195\x195\x195\x195\x195\x195\x195\x19\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b52\x1b5\x1b555\x1b5\x1b5\x1b5\x1b' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b\x1b\x1b\x1b\x1b\x1b55\x1b55\x1b' -'\x1b5\x1b5555\x1b5\x1b5\x1b5\x1b5\x1b\x1b\x19\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x19\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -"\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b.\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b#########''#####" -"##\xa5\xa5\xa3\xa5'%'%%%'%''\x1f#\xa5\xa5\xa5\xa5\xa5\xa5\xa3\xa3\xa3\xa3\xa5\xa3\xa5\xa3#####\xa5\xa5\xa5\xa5\xa5\xa5\xa5'\xa5#\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5" -'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<' -'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<5\x1b5\x1b\'\xa55\x1b\x15\x15"\x1b\x1b\x1b\x8a5' -'\x15\x15\x15\x15\xa5\xa55\x8b555\x155\x1555\x1b33333333333333333\x15333333355\x1b\x1b\x1b\x1b\x1b\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19' -'\x19\x19\x1b\x19\x19\x19\x19\x19\x19\x19\x1b\x1b\x1b\x1b\x1b5\x1b\x1b555\x1b\x1b\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b\x1b\x1b\x1b5\x1b\xb65\x1b55\x1b\x1b555' -'535555555555555533333333333333333333333333333333\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19' -'\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x1b\x19\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'5\x1b\xc2=====::5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'55\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x15555555555555555' -'55555555555555555555555\x15\x15#\x83\x83\x83\x83\x83\x83\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x83d\x15\x15\xc7\xc7\x9d\x15=============================================f=' -'\x90==\x90==\x90=\x15\x15\x15\x15\x15\x15\x15\x15111111111111111111111111111\x15\x15\x15\x151111\x90\x91\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x06\x06\x06\x06\x06\x06\xb6\xb6\xa8\x80\x80\x99yu\xc7\xc7===========u\x05\x15uu********************************' -'\x1e**********=====================@@@@@@@@@@\x80vvu**=***************' -'****************************************************************' -'********************u*=======\x06\xc7======\x1e\x1e==\xc7====**BBBBBBBBBB***\xbd\xbd*' -'uuuuuuuuuuuuuu\x15\x05*=******************************================' -'===========\x15\x15***************************************************' -'**************************************===========*\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'EEEEEEEEEE111111111111111111111111111111111=========((\xc7\x8a\x8a\x8a(\x15\x15=\xa0\xa0' -'1111111111111111111111====(=========(===(=====\x15\x15\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x15' -'1111111111111111111111111===\x15\x15\x90\x15***********\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15*********************\x15********\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15===============\x06=============================' -'===8......................................................=8=.88' -'8========8888=88.=======..........==\x83\x83DDDDDDDDDD\x83#..............' -'.=88\x15........\x15\x15..\x15\x15......................\x15.......\x15.\x15\x15\x15....\x15\x15=.88' -'8====\x15\x1588\x15\x1588=.\x15\x15\x15\x15\x15\x15\x15\x158\x15\x15\x15\x15..\x15...==\x15\x15DDDDDDDDDD..\x9d\x9dRRRRRR\xc2\x9d.\x83=\x15' -'\x15==8\x15......\x15\x15\x15\x15..\x15\x15......................\x15.......\x15..\x15..\x15..\x15\x15=\x1588' -'8==\x15\x15\x15\x15==\x15\x15===\x15\x15\x15=\x15\x15\x15\x15\x15\x15\x15....\x15.\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD==...=\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15==8\x15.........\x15...\x15......................\x15.......\x15..\x15.....\x15\x15=.88' -'8=====\x15==8\x1588=\x15\x15.\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15..==\x15\x15DDDDDDDDDD\x83\x9d\x15\x15\x15\x15\x15\x15\x15.======' -'\x15=88\x15........\x15\x15..\x15\x15......................\x15.......\x15..\x15.....\x15\x15=.8=' -'8====\x15\x1588\x15\x1588=\x15\x15\x15\x15\x15\x15\x15\x15=8\x15\x15\x15\x15..\x15...==\x15\x15DDDDDDDDDD\xc2.RRRRRR\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15=.\x15......\x15\x15\x15...\x15....\x15\x15\x15..\x15.\x15..\x15\x15\x15..\x15\x15\x15...\x15\x15\x15............\x15\x15\x15\x1588' -'=88\x15\x15\x15888\x15888=\x15\x15.\x15\x15\x15\x15\x15\x158\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDDRRR\xc7\xc7\xc7\xc7\xc7\xc7\x9d\xc7\x15\x15\x15\x15\x15' -'=888=........\x15...\x15.......................\x15................\x15\x15\x15.==' -'=8888\x15===\x15====\x15\x15\x15\x15\x15\x15\x15==\x15...\x15\x15\x15\x15\x15..==\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15\x15\x15WWWWWWW\xc2' -'.=88\x83........\x15...\x15.......................\x15..........\x15.....\x15\x15=.8;' -'88888\x15;88\x1588==\x15\x15\x15\x15\x15\x15\x1588\x15\x15\x15\x15\x15\x15\x15.\x15..==\x15\x15DDDDDDDDDD\x15..\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'==88\x15........\x15...\x15.........................................==.88' -'8====\x15888\x15888=.\xc2\x15\x15\x15\x15...8RRRRRRR...==\x15\x15DDDDDDDDDDRRRRRRRRR\xc2......' -'\x15\x1588\x15..................\x15\x15\x15........................\x15.........\x15.\x15\x15' -'.......\x15\x15\x15=\x15\x15\x15\x15888===\x15=\x1588888888\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x1588\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15................................................=.-=======\x15\x15\x15\x15\x9d' -'......#========\x83DDDDDDDDDD\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15..\x15.\x15\x15..\x15.\x15\x15.\x15\x15\x15\x15\x15\x15....\x15.......\x15...\x15.\x15.\x15\x15..\x15....=.-======\x15==.\x15\x15' -'.....\x15#\x15======\x15\x15DDDDDDDDDD\x15\x15....\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.\xc2\xc2\xc2\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\xc2\x83\xc2\xc2\xc2==\xc2\xc2\xc2\xc2\xc2\xc2DDDDDDDDDDRRRRRRRRRR\xc2=\xc2=\xc2=\x95j\x95j88' -'........\x15....................................\x15\x15\x15\x15==============8' -'=====\x83==.....===========\x15====================================\x15\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2=\xc2\xc2\xc2\xc2\xc2\xc2\x15\xc2\xc2\x83\x83\x83\x83\x83\xc2\xc2\xc2\xc2\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...........................................88====8======8==88==.' -'DDDDDDDDDD\x83\x83\x83\x83\x83\x83......88==....===.888..8888888...====...........' -'..=88==888888=.8DDDDDDDDDD888=\xc2\xc255555555555555555555555555555555' -'555555\x155\x15\x15\x15\x15\x155\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x83#\x1b\x1b\x1b' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////................................' -'................................................................' -'................................................................' -'................................................................' -'.........\x15....\x15\x15.......\x15.\x15....\x15\x15................................' -'.........\x15....\x15\x15.................................\x15....\x15\x15.......\x15' -'.\x15....\x15\x15...............\x15........................................' -'.................\x15....\x15\x15........................................' -'...........................\x15\x15===\x83\x83\x83\x83\x83\x83\x83\x83\x83SSSSSSSSSRRRRRRRRRRR\x15\x15\x15' -'................\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x1555555555555555555555555555555555' -'555555555555555555555555555555555555555555555555555555\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15' -'d...............................................................' -'................................................................' -'................................................................' -'................................................................' -'................................................................' -'................................................................' -'................................................................' -'................................................................' -'................................................................' -'.............................................\x83\x83.................' -'\xd0..........................\x95j\x15\x15\x15................................' -'...........................................\x83\x83\x83GGG........\x15\x15\x15\x15\x15\x15\x15' -'.............\x15....===\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15..................===\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'..................==\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15.............\x15...\x15==\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'....................................................==8=======88' -'888888=88===========\x83\x83\x83#\x83\x83\x83\x9d.=\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15WWWWWWWWWW\x15\x15\x15\x15\x15\x15' -'\x8a\x8a\x8a\x8a\x8a\x8ad\x8a\x8a\x8a\x8a===\x08\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15................................' -'...#.....................................................\x15\x15\x15\x15\x15\x15\x15' -'.....>>..................................=.\x15\x15\x15\x15\x15................' -'......................................................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...............................\x15===8888==888\x15\x15\x15\x1588=888888===\x15\x15\x15\x15' -'\xc7\x15\x15\x15\x8a\x8aDDDDDDDDDD..............................\x15\x15.....\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'............................................\x15\x15\x15\x15................' -'..........\x15\x15\x15\x15\x15\x15DDDDDDDDDDS\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'.......................==88=\x15\x15\x83\x83................................' -'.....................8=8=======\x15=8=88========888888==========\x15\x15=' -'DDDDDDDDDD\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15\x83\x83\x83\x83\x83\x83\x83#\x83\x83\x83\x83\x83\x83\x15\x15==============:\x15' +'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x00\x03\x04\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x02\xd9\x92\x92\x87\xa4\x87\x92\x93\x9cq\x92\xb2\x80g\x81\x80FFFFFFFFFF\x81\x92\xc0\xbf\xc0\x92' +'\x9288888888888888888888888888\x9c\x92q\xacd\xac\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x1c\x9c\xbfq\xbf\x01' +'\x01\x01\x01\x01\x01\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xd6\x8a\xa4\xa4\xa0\xa4\xd1\x8a\xa9\xcf-z\xbf\x07\xcc\xac\xc4\xb4TT\xa9\x1b\x8a\x8c\xa9T-v[[[\x8a' +'77777757777777775777777\xb75777775\x19\x19\x19\x1b\x1b\x1b\x1b\x19\x1b\x19\x19\x19\x1b\x19\x19\x1b\x1b\x19\x1b\x19\x19\x1b\x1b\x1b\xb7\x19\x19\x19\x1b\x19\x1b\x19\x1b' +'7\x197\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x197\x197\x1b7\x1b7\x1b7\x197\x1b7\x1b7\x1b7\x1b7\x1b5\x197\x1b7\x197\x1b7\x1b7\x195\x197\x1b7\x1b\x197\x1b7\x1b7\x1b5' +'\x195\x197\x197\x1b7\x19\x195\x197\x197\x1b7\x1b5\x197\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b5\x197\x1b7\x197\x1b7\x1b7\x1b7\x1b7\x1b7\x1b77\x1b7\x1b7\x1b\x1b' +'\x1b77\x1b7\x1b77\x1b777\x1b\x1b7777\x1b77\x1b777\x1b\x1b\x1b77\x1b77\x1b7\x1b7\x1b77\x1b7\x1b\x1b7\x1b77\x1b777\x1b7\x1b77\x1b\x1b07\x1b\x1b\x1b' +'000074\x1b74\x1b74\x1b7\x197\x197\x197\x197\x197\x197\x197\x19\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b74\x1b7\x1b777\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b\x1b\x1b\x1b\x1b\x1b77\x1b77\x1b' +'\x1b7\x1b7777\x1b7\x1b7\x1b7\x1b7\x1b\x1b\x19\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x19\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b0\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b%%%%%%%%%))$$$$$' +"%%\xab\xab\xa9\xab)')''')'))\x1f$\xab\xab\xab\xab\xab\xab\xa9\xa9\xa9\xa9\xab\xa9\xab\xa9%%%%%\xab\xab\xab\xab\xab\xab\xab)\xab$\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab" +'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' +'>>>>>?>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>7\x1b7\x1b)\xab7\x1b\x15\x15#\x1b\x1b\x1b\x907' +'\x15\x15\x15\x15\xab\xab7\x91777\x157\x1577\x1b55555555555555555\x15555555577\x1b\x1b\x1b\x1b\x1b\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19' +'\x19\x19\x1b\x19\x19\x19\x19\x19\x19\x19\x1b\x1b\x1b\x1b\x1b7\x1b\x1b777\x1b\x1b\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b\x1b\x1b\x1b7\x1b\xbc7\x1b77\x1b\x1b777' +'757777777777777755555555555555555555555555555555\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19' +'\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x1b\x19\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b\xca@@@@@<<7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'77\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x15777777777777777' +'77777777777777777777777\x15\x15$\x89\x89\x89\x89\x89\x89\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x89j\x15\x15\xcf\xcf\xa3\x15@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@l@' +'\x96@@\x96@@\x96@\x15\x15\x15\x15\x15\x15\x15\x15333333333333333333333333333\x15\x15\x15\x153333\x96\x97\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x06\x06\x06\x06\x06\x06\xbc\xbc\xae\x86\x86\x9f\x7f{\xcf\xcf@@@@@@@@@@@{\x05\x15{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +'\x1e,,,,,,,,,,@@@@@@@@@@@@@@@@@@@@@CCCCCCCCCC\x86||{,,@,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,{,@@@@@@@\x06\xcf@@@@@@\x1e\x1e@@\xcf@@@@,,EEEEEEEEEE,,,\xc3\xc3,' +'{{{{{{{{{{{{{{\x15\x05,@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@@@@@@@@@@@@@@@' +'@@@@@@@@@@@\x15\x15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@@@@@@@@@@,\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'HHHHHHHHHH333333333333333333333333333333333@@@@@@@@@**\xcf\x90\x90\x90*\x15\x15@\xa6\xa6' +'3333333333333333333333@@@@*@@@@@@@@@*@@@*@@@@@\x15\x15\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x96\x15' +'3333333333333333333333333@@@\x15\x15\x96\x15,,,,,,,,,,,\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15,,,,,,,,,,,,,,,,,,,,,\x15,,,,,,,,\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15@@@@@@@@@@@@@@@\x06@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' +'@@@:000000000000000000000000000000000000000000000000000000@:@0::' +':@@@@@@@@::::@::0@@@@@@@0000000000@@\x89\x89GGGGGGGGGG\x89$00000000000000' +'0@::\x1500000000\x15\x1500\x15\x150000000000000000000000\x150000000\x150\x15\x15\x150000\x15\x15 at 0::' +':@@@@\x15\x15::\x15\x15::@0\x15\x15\x15\x15\x15\x15\x15\x15:\x15\x15\x15\x1500\x15000@@\x15\x15GGGGGGGGGG00\xa3\xa3XXXXXX\xca\xa30\x89@\x15' +'\x15@@:\x15000000\x15\x15\x15\x1500\x15\x150000000000000000000000\x150000000\x1500\x1500\x1500\x15\x15@\x15::' +':@@\x15\x15\x15\x15@@\x15\x15@@@\x15\x15\x15@\x15\x15\x15\x15\x15\x15\x150000\x150\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG@@000@\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15@@:\x15000000000\x15000\x150000000000000000000000\x150000000\x1500\x1500000\x15\x15 at 0::' +':@@@@@\x15@@:\x15::@\x15\x150\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1500@@\x15\x15GGGGGGGGGG\x89\xa3\x15\x15\x15\x15\x15\x15\x150@@@@@@' +'\x15@::\x1500000000\x15\x1500\x15\x150000000000000000000000\x150000000\x1500\x1500000\x15\x15 at 0:@' +':@@@@\x15\x15::\x15\x15::@\x15\x15\x15\x15\x15\x15\x15\x15@:\x15\x15\x15\x1500\x15000@@\x15\x15GGGGGGGGGG\xca0XXXXXX\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15 at 0\x15000000\x15\x15\x15000\x150000\x15\x15\x1500\x150\x1500\x15\x15\x1500\x15\x15\x15000\x15\x15\x15000000000000\x15\x15\x15\x15::' +'@::\x15\x15\x15:::\x15:::@\x15\x150\x15\x15\x15\x15\x15\x15:\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGGXXX\xcf\xcf\xcf\xcf\xcf\xcf\xa3\xcf\x15\x15\x15\x15\x15' +'@:::@00000000\x15000\x1500000000000000000000000\x150000000000000000\x15\x15\x150@@' +'@::::\x15@@@\x15@@@@\x15\x15\x15\x15\x15\x15\x15@@\x15000\x15\x15\x15\x15\x1500@@\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x15\x15]]]]]]]\xca' +'0@::\x8900000000\x15000\x1500000000000000000000000\x150000000000\x1500000\x15\x15 at 0:=' +':::::\x15=::\x15::@@\x15\x15\x15\x15\x15\x15\x15::\x15\x15\x15\x15\x15\x15\x150\x1500@@\x15\x15GGGGGGGGGG\x1500\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'@@::\x1500000000\x15000\x1500000000000000000000000000000000000000000@@0::' +':@@@@\x15:::\x15:::@0\xca\x15\x15\x15\x15000:XXXXXXX000@@\x15\x15GGGGGGGGGGXXXXXXXXX\xca000000' +'\x15\x15::\x15000000000000000000\x15\x15\x15000000000000000000000000\x15000000000\x150\x15\x15' +'0000000\x15\x15\x15@\x15\x15\x15\x15:::@@@\x15@\x15::::::::\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15::\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15000000000000000000000000000000000000000000000000 at 0/@@@@@@@\x15\x15\x15\x15\xa3' +'000000$@@@@@@@@\x89GGGGGGGGGG\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x1500\x150\x15\x1500\x150\x15\x150\x15\x15\x15\x15\x15\x150000\x150000000\x15000\x150\x150\x15\x1500\x150000 at 0/@@@@@@\x15@@0\x15\x15' +'00000\x15$\x15@@@@@@\x15\x15GGGGGGGGGG\x15\x150000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0\xca\xca\xca\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\xca\x89\xca\xca\xca@@\xca\xca\xca\xca\xca\xcaGGGGGGGGGGXXXXXXXXXX\xca@\xca@\xca@\x9bp\x9bp::' +'00000000\x15000000000000000000000000000000000000\x15\x15\x15\x15@@@@@@@@@@@@@@:' +'@@@@@\x89@@00000@@@@@@@@@@@\x15@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\x15\xca\xca' +'\xca\xca\xca\xca\xca\xca@\xca\xca\xca\xca\xca\xca\x15\xca\xca\x89\x89\x89\x89\x89\xca\xca\xca\xca\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000::@@@@:@@@@@@:@@::@@0' +'GGGGGGGGGG\x89\x89\x89\x89\x89\x89000000::@@0000@@@0:::00:::::::000@@@@00000000000' +'00@::@@::::::@0:GGGGGGGGGG:::@\xca\xca77777777777777777777777777777777' +'777777\x157\x15\x15\x15\x15\x157\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x89$\x1b\x1b\x1b' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111100000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'000000000\x150000\x15\x150000000\x150\x150000\x15\x1500000000000000000000000000000000' +'000000000\x150000\x15\x15000000000000000000000000000000000\x150000\x15\x150000000\x15' +'0\x150000\x15\x15000000000000000\x150000000000000000000000000000000000000000' +'00000000000000000\x150000\x15\x150000000000000000000000000000000000000000' +'000000000000000000000000000\x15\x15@@@\x89\x89\x89\x89\x89\x89\x89\x89\x89YYYYYYYYYXXXXXXXXXXX\x15\x15\x15' +'0000000000000000\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x1577777777777777777777777777777777' +'777777777777777777777777777777777777777777777777777777\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15' +'j000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'000000000000000000000000000000000000000000000\x89\x8900000000000000000' +'\xd800000000000000000000000000\x9bp\x15\x15\x1500000000000000000000000000000000' +'0000000000000000000000000000000000000000000\x89\x89\x89KKK00000000\x15\x15\x15\x15\x15\x15\x15' +'0000000000000\x150000@@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15000000000000000000@@@\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x150000000000000\x15000\x15@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000@@:@@@@@@@::' +'::::::@::@@@@@@@@@@@\x89\x89\x89$\x89\x89\x89\xa30@\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15]]]]]]]]]]\x15\x15\x15\x15\x15\x15' +'\x90\x90\x90\x90\x90\x90j\x90\x90\x90\x90@@@\x08\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x1500000000000000000000000000000000' +'000$00000000000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15' +'00000AA0000000000000000000000000000000000 at 0\x15\x15\x15\x15\x150000000000000000' +'000000000000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000\x15@@@::::@@:::\x15\x15\x15\x15::@::::::@@@\x15\x15\x15\x15' +'\xcf\x15\x15\x15\x90\x90GGGGGGGGGG000000000000000000000000000000\x15\x1500000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'00000000000000000000000000000000000000000000\x15\x15\x15\x150000000000000000' +'0000000000\x15\x15\x15\x15\x15\x15GGGGGGGGGGY\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'00000000000000000000000@@::@\x15\x15\x89\x8900000000000000000000000000000000' +'000000000000000000000:@:@@@@@@@\x15@:@::@@@@@@@@::::::@@@@@@@@@@\x15\x15@' +'GGGGGGGGGG\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x89\x89\x89\x89\x89\x89\x89$\x89\x89\x89\x89\x89\x89\x15\x15@@@@@@@@@@@@@@<\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'====8...............................................=8=====8=888' -'88=88.......\x15\x15\x15\x15DDDDDDDDDD\x83\x83\x83\x83\x83\x83\x83\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2=========\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\x15\x15\x15' -'==8..............................8====88==8===..DDDDDDDDDD......' -'......................................=8==888=8===88\x15\x15\x15\x15\x15\x15\x15\x15\x83\x83\x83\x83' -'....................................88888888========88==\x15\x15\x15\x83\x83\x83\x83\x83' -'DDDDDDDDDD\x15\x15\x15...DDDDDDDDDD..............................######\x83\x83' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x15\x15\x155555555555555555555555555555555555555555555\x15\x15555' -'\x83\x83\x83\x83\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15===\x83=============8=======....=....88=..8==\x15\x15\x15\x15\x15\x15' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b####################' -'###########################################\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b#\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b#####################################' -'==========================================================\x15=====' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15555555\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555' -'\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15555555\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x155\x155\x155\x155\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b22222222\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b22222222\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b22222222\x1b\x1b\x1b\x1b\x1b\x15\x1b\x1b55552\xa5\x1b\xa5' -'\xa5\xa5\x1b\x1b\x1b\x15\x1b\x1b55552\xa5\xa5\xa5\x1b\x1b\x1b\x1b\x15\x15\x1b\x1b5555\x15\xa5\xa5\xa5\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555\xa5\xa5\xa5\x15\x15\x1b\x1b\x1b\x15\x1b\x1b55552\xa5\xa5\x15' -'\xd0\xd0\xd0\xd0\xd0\xd0\xd0\xd0\xd0\xd0\xd0\x08\x08\x08\n\x11cddccc\x84\x8aro\x94sqn\x94s\x84\x84\x84\x8a\x85\x84\x84\x85\xcc\xcd\x0b\x12\x0f\r\x14\xce~\x80~~\x80\x84\x8a\x8a\x8atp\x84\x8a\x8a\x84]' -']\x8a\x8a\x8a\xa9\x95j\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xb6\x8a]\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\xd0\x08\x08\x08\x08\x08\x15\x0c\x13\t\x10\x08\x08\x08\x08\x08\x08P#\x15\x15NPPPPP\xab\xab\xb6\x95j\x1f' -'PNNNNPPPPP\xab\xab\xb6\x95j\x15#############\x15\x15\x15\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9c\x9d\x9d\x9a\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d\x9d' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15=============::::=:::============\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc75\xc4\xc7\xc4\xc75\xc7\xc4\x1b555\x1b\x1b555\x19\xc75\xc4\xc7\xb855555\xc7\xc7\xc7\xc4\xc4\xc75\xc73\xc75\xc75355\xc0\x1b5555\x1b....\x1b\xc7\xc7\x1b\x1b55' -'\xb7\xb6\xb6\xb6\xb65\x1b\x1b\x1b\x1b\xc7\xb6\xc7\xc7\x1b\xc2WWWUUWWWWWWUUUUWFFFFFFFFFFFFGGGGFFFFFFFFFFGGGGGG' -'GGG5\x1bGGGGU\xc7\xc7\x15\x15\x15\x15\xb1\xb1\xb1\xb1\xb1\xc4\xc4\xc4\xc4\xc4\xb6\xb6\xc7\xc7\xc7\xc7\xb6\xc7\xc7\xb6\xc7\xc7\xb6\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xb6\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xb6\xb6\xc7\xc7\xb1\xc7\xb1\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6' -'\xb1\xb7\xb2\xb2\xb7\xb6\xb6\xb1\xb2\xb7\xb7\xb2\xb7\xb7\xb6\xb1\xb6\xb2\xab\xaf\xb6\xb2\xb7\xb6\xb6\xb6\xb2\xb7\xb7\xb2\xb1\xb2\xb2\xb7\xb7\xb1\xb7\xb1\xb7\xb1\xb1\xb1\xb1\xb2\xb2\xb7\xb2\xb7\xb7\xb7\xb7\xb7\xb1\xb1\xb1\xb1\xb6\xb7\xb6\xb7\xb2\xb2\xb7\xb7' -'\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb2\xb7\xb7\xb7\xb2\xb6\xb6\xb6\xb6\xb6\xb2\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb2\xb1\xb7\xb6\xb2\xb2\xb2\xb2\xb7\xb7\xb2\xb2\xb6\xb6\xb2\xb2\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7' -'\xb7\xb7\xb2\xb2\xb7\xb7\xb2\xb2\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb7\xb7\xb7\xb7\xb6\xb6\xb1\xb6\xb6\xb7\xb1\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb6\xb1\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb7\xb2' -'\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb7\xb7\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x95j\x95j\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xc7\xc7\xc7\xc7\xb7\xb7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x98m\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc7\xb6\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc2\xc7\xc7\xc7\xc7\xc7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xb6\xb6\xb6\xb6\xb6\xb6\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xc7\xc7\xc7\xca\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15VVVVVVVVVUUUUUUUUUUUVVVVVVVVVUUU' -'UUUUUUUUNNNNNNNNNMMMMMMMMMMM\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1' -'\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1XUUUUUUUUUUVVVVVVVVVUV' -'\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4' -'\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc7\xc7\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc7\xc4\xb1\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc7' -'\xc4\xb1\xc7\xc7\xc7\xc7\xc4\xc4\xc4\xc7\xc7\xc4\xc7\xc7\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xb6\xb6\xb6\xb6\xb6\xbb\xbb\xb6' -'\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc7\xc4\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc7\xc7\xc7\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc4\xc7\xc4\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xc4\xc4\xc4\xc7\xc4\xc4\xc4\xc4\xc7\xc4\xc4\xc7\xb1\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc4\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xc2\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xc4' -'\xc7\xc7\xc7\xc7\xca\xca\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xca\xc4\xc4\xc4\xc4\xc4\xca\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xc7\xc4\xc7\xc7\xc7\xc7\xc4\xc4\xca\xc4\xc4\xc4\xc4\xc4\xc4\xc4\xca\xca\xc4\xca\xc4\xc4\xc4\xc4\xca\xc4\xc4\xca\xc4\xc4' -'\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc4\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xca\xc7\xc7\xc7\xc7\xca\xca\xca\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x95j\x95j\x95j\x95j\x95j\x95j\x95jVVVVVVVVVU' -'XXXXXXXXXWXXXXXXXXXW\xc7\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca' -'\xb7\xb6\xb6\xb7\xb7\x95j\xb6\xb7\xb7\xb6\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb6\xb6\xb6\xb7\xb7\xb7\xb7\x96k\x96k\x96k\x96k\x95j\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6' -'\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6' -'\xb6\xb6\xb6\x95j\x96k\x95j\x95j\x95j\x95j\x95j\x95j\x95j\x95j\x95j\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb6\xb6\xb6\xb6\xb6\xb6\xb6' -'\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb7\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb6\xb6\x95j\x95j\xb7\xb6\xb6\xb6\xb6\xb7\xb6\xb7\xb7\xb7\xb6\xb6\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\x95j\xb6\xb6' -'\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb7\xb7\xb6\xb6\xb7\xb6\xb7\xb6\xb6\xb7\xb6\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb6' -'\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb6\xb6\xb7\xb7\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7' -'\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7' -'\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb7\xb6\xb7\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb6\xb7\xb7\xb7\xb6\xb6\xb6\xb6\xb7\xb6\xb6\xb6\xb7\xb7\xb7\xb7\xb7\xb6\xb7\xb6\xb6' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6\xb6' -'\xb6\xb6\xb6\xb6\xb6\xc7\xc7\xb6\xb6\xb6\xb6\xb6\xb6\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xca\xc4\xc4\xc4\xc4\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc8\x15' -'55555555555555555555555555555555555555555555555\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x155\x1b555\x1b\x1b5\x1b5\x1b5\x1b5555\x1b5\x1b\x1b5\x1b\x1b\x1b\x1b\x1b\x1b##55' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b' -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b\xc7\xc7\xc7\xc7\xc7\xc75\x1b5\x1b===5\x1b\x15\x15\x15\x15\x15\x8a\x8a\x8a\x8aW\x8a\x8a' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x1b\x15\x15\x15\x15\x15\x1b\x15\x15................' -'........................................\x15\x15\x15\x15\x15\x15\x15#\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15=' -'.......................\x15\x15\x15\x15\x15\x15\x15\x15\x15.......\x15.......\x15.......\x15.......\x15' -'.......\x15.......\x15.......\x15.......\x15================================' -'\x8a\x8atptp\x8a\x8a\x8atp\x8atp\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8ad\x8a\x8ad\x8atp\x8a\x8atp\x95j\x95j\x95j\x95j\x8a\x8a\x8a\x8a\x8a&\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8add\x8a\x8a\x8a\x8a' -'d\x8a\x94\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'@@@@:00000000000000000000000000000000000000000000000@:@@@@@:@:::' +'::@::0000000\x15\x15\x15\x15GGGGGGGGGG\x89\x89\x89\x89\x89\x89\x89\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca@@@@@@@@@\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15' +'@@:000000000000000000000000000000:@@@@::@@:@@@00GGGGGGGGGG000000' +'00000000000000000000000000000000000000@:@@:::@:@@@::\x15\x15\x15\x15\x15\x15\x15\x15\x89\x89\x89\x89' +'000000000000000000000000000000000000::::::::@@@@@@@@::@@\x15\x15\x15\x89\x89\x89\x89\x89' +'GGGGGGGGGG\x15\x15\x15000GGGGGGGGGG000000000000000000000000000000$$$$$$\x89\x89' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x15\x15\x157777777777777777777777777777777777777777777\x15\x15777' +'\x89\x89\x89\x89\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15@@@\x89@@@@@@@@@@@@@:@@@@@@@0000 at 0000::@00:@@\x15\x15\x15\x15\x15\x15' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b%%%%%%%%%%%%%%%%%%%%' +'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b%\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%' +'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\x15@@@@@' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15777777\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777' +'\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15777777\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x157\x157\x157\x157\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b44444444\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b44444444\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b44444444\x1b\x1b\x1b\x1b\x1b\x15\x1b\x1b77774\xab\x1b\xab' +'\xab\xab\x1b\x1b\x1b\x15\x1b\x1b77774\xab\xab\xab\x1b\x1b\x1b\x1b\x15\x15\x1b\x1b7777\x15\xab\xab\xab\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777\xab\xab\xab\x15\x15\x1b\x1b\x1b\x15\x1b\x1b77774\xab\xab\x15' +'\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\xd8\x08\x08\x08\n\x11ijjiii\x8a\x90xu\x9aywt\x9ay\x8a\x8a\x8a\x90\x8b\x8a\x8a\x8b\xd4\xd5\x0b\x12\x0f\r\x14\xd6\x84\x86\x84\x84\x86\x8a\x90\x90\x90zv\x8a\x90\x90\x8ac' +'c\x90\x90\x90\xaf\x9bp\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xbc\x90c\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xd8\x08\x08\x08\x08\x08\x15\x0c\x13\t\x10\x08\x08\x08\x08\x08\x08V%\x15\x15TVVVVV\xb1\xb1\xbc\x9bp ' +'VTTTTVVVVV\xb1\xb1\xbc\x9bp\x15%%%%%%%%%%%%%\x15\x15\x15\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa2\xa3\xa3\xa0\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15@@@@@@@@@@@@@<<<<@<<<@@@@@@@@@@@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf7\xcc\xcf\xcc\xcf7\xcf\xcc\x1b777\x1b\x1b777\x19\xcf7\xcc\xcf\xbe77777\xcf\xcf\xcf\xcc\xcc\xcf7\xcf5\xcf7\xcf7577\xc6\x1b7777\x1b0000\x1b\xcf\xcf\x1b\x1b77' +'\xbd\xbc\xbc\xbc\xbc7\x1b\x1b\x1b\x1b\xcf\xbc\xcf\xcf\x1b\xca]]][[]]]]]][[[[]IIIIIIIIIIIILLLLJJJJJJJJJJMMMMMM' +'KKK7\x1bKKKK[\xcf\xcf\x15\x15\x15\x15\xb7\xb7\xb7\xb7\xb7\xcc\xcc\xcc\xcc\xcc\xbc\xbc\xcf\xcf\xcf\xcf\xbc\xcf\xcf\xbc\xcf\xcf\xbc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xbc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xbc\xbc\xcf\xcf\xb7\xcf\xb7\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc' +'\xb7\xbd\xb8\xb8\xbd\xbc\xbc\xb7\xb8\xbd\xbd\xb8\xbd\xbd\xbc\xb7\xbc\xb8\xb1\xb5\xbc\xb8\xbd\xbc\xbc\xbc\xb8\xbd\xbd\xb8\xb7\xb8\xb8\xbd\xbd\xb7\xbd\xb7\xbd\xb7\xb7\xb7\xb7\xb8\xb8\xbd\xb8\xbd\xbd\xbd\xbd\xbd\xb7\xb7\xb7\xb7\xbc\xbd\xbc\xbd\xb8\xb8\xbd\xbd' +'\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xb8\xbd\xbd\xbd\xb8\xbc\xbc\xbc\xbc\xbc\xb8\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xb8\xb7\xbd\xbc\xb8\xb8\xb8\xb8\xbd\xbd\xb8\xb8\xbc\xbc\xb8\xb8\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd' +'\xbd\xbd\xb8\xb8\xbd\xbd\xb8\xb8\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbd\xbd\xbd\xbd\xbc\xbc\xb7\xbc\xbc\xbd\xb7\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbc\xb7\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbd\xb8' +'\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbd\xbd\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x9bp\x9bp\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xcf\xcf\xcf\xcf\xbd\xbd\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x9es\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xcf\xbc\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xca\xcf\xcf\xcf\xcf\xcf\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xbc\xbc\xbc\xbc\xbc\xbc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xd2\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\\\\\\\\\\\\\\\\\\[[[[[[[[[[[\\\\\\\\\\\\\\\\\\[[[' +'[[[[[[[[TTTTTTTTTSSSSSSSSSSS\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8' +'\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9\xc9^[[[[[[[[[[\\\\\\\\\\\\\\\\\\[\\' +'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc' +'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcf\xcf\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcf\xcc\xb7\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcf' +'\xcc\xb7\xcf\xcf\xcf\xcf\xcc\xcc\xcc\xcf\xcf\xcc\xcf\xcf\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xbc\xbc\xbc\xbc\xbc\xc1\xc1\xbc' +'\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcf\xcc\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcf\xcf\xcf\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcf\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcc\xcf\xcc\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xcc\xcc\xcc\xcf\xcc\xcc\xcc\xcc\xcf\xcc\xcc\xcf\xb7\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcc\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xca\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xcc' +'\xcf\xcf\xcf\xcf\xd2\xd2\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xd2\xcc\xcc\xcc\xcc\xcc\xd2\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcf\xcc\xcf\xcf\xcf\xcf\xcc\xcc\xd2\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xd2\xd2\xcc\xd2\xcc\xcc\xcc\xcc\xd2\xcc\xcc\xd2\xcc\xcc' +'\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcc\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xd2\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x9bp\x9bp\x9bp\x9bp\x9bp\x9bp\x9bp\\\\\\\\\\\\\\\\\\[' +'^^^^^^^^^]^^^^^^^^^]\xcf\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2' +'\xbd\xbc\xbc\xbd\xbd\x9bp\xbc\xbd\xbd\xbc\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbc\xbc\xbc\xbd\xbd\xbd\xbd\x9cq\x9cq\x9cq\x9cq\x9bp\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc' '\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' '\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' '\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15' -'\xcf\x8e\x8e\x8e\xca$/H\x98m\x98m\x98m\x98m\x98m\xca\xca\x98m\x98m\x98m\x98me\x97ll\xcaHHHHHHHHH????99e$$$$$\xca\xcaHHH$/\x8e\xca\xc7' -'\x15///////////////////////////////////////////////////////////////' -'///////////////////////\x15\x15??\xa7\xa7$$/e///////////////////////////////' -'///////////////////////////////////////////////////////////\x8e$$$/' -'\x15\x15\x15\x15\x15///////////////////////////////////////////\x15///////////////' -'////////////////////////////////////////////////////////////////' -'///////////////\x15\xc3\xc3TTTT\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3///////////////////////////\x15\x15\x15\x15\x15' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15////////////////' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xca\xca\x15TTTTTTTTTT\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3QQQQQQQQ\xcaYYYYYYYYYYYYYYY\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xca\xca\xca\xc3' -'TTTTTTTTTT\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3YYYYYYYYYYYYYYY' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xca\xca\xca\xca\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\x15' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xca\xca\xca\xca\xc3\xc3\xc3\xc3\xc3' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xca\xca\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xca' -'/////0//////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'///0////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////0/////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/////////////0//////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'0//0///0/0//////////////////////////////////////////////////////' -'/////////////////////////////0//////////////////////////////////' -'////////////0///////0/0////////////////////////////////////////0' -'0//////////////////////////////0////////0///////////////////////' -'/////////////0//////////////////////////////////////////////////' -'////////////////////////////////////////////////0///////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////0///////////////////////////////////////////////////////////' -'//////0//////////////////////////////////0/0/0//////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/0/000//////0///////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/0000///////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'///////////////////////////0////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/////////////////////////////////////////////////0///////0//////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////////////0/////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////////////////00' -'////////////000/0///////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////////////////0/' -'////////////////////////////////////////////////////////////////' -'////////////0///////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////0/////////////////////////////////////////////' -'//////0/////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////0/////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////////////////0/' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////0/////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////0///////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////0////0////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////0///////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/////////////////////////////////0//////////////////////////////' -'//////0/////0///////////////////////////////////////////0///////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////////0/////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'/////////////////////$//////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/////////////\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15........................................######\x83\x83' -'............#\x8a\x8a\x8a................DDDDDDDDDD..\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -"5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b.=:::\x8a==========\x8a'" -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b##==................................' -'......................................GGGGGGGGGG==\x83\x83\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15' -"\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5\xa5'''''''''\xa5\xa55\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b\x1b\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b" -'5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b#\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b5\x1b5\x1b55\x1b' -"5\x1b5\x1b5\x1b5\x1b'\xa2\xa25\x1b5\x1b.5\x1b5\x1b\x1b\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b5\x1b55555\x1b55555\x1b5\x1b5\x1b\x15\x15\x15\x15\x15\x15" -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15.##\x1b.....' -'..=...=....=.......................88==8\xc7\xc7\xc7\xc7\x15\x15\x15\x15RRRRRR\xc2\xc2\x9d\xbf\x15\x15\x15\x15\x15\x15' -'....................................................\x8a\x8a\x8a\x8a\x15\x15\x15\x15\x15\x15\x15\x15' -'88..................................................888888888888' -'8888==\x15\x15\x15\x15\x15\x15\x15\x15\x83\x83DDDDDDDDDD\x15\x15\x15\x15\x15\x15==================......\x83\x83\x83.\x83..=' -'DDDDDDDDDD............................========\x83\x83................' -'.......===========88\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x83/////////////////////////////\x15\x15\x15' -'===8...............................................=88====88=888' -'8\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x15#DDDDDDDDDD\x15\x15\x15\x15\x83\x83.....=#.........DDDDDDDDDD.....\x15' -'.........................................======88==88==\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...=........=8\x15\x15DDDDDDDDDD\x15\x15\x83\x83\x83\x83................#......\xc2\xc2\xc2.8=8..' -'................................................=.===..==.....==' -'.=.\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15..#\x83\x83...........8==88\x83\x83.##8=\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15......\x15\x15......\x15\x15......\x15\x15\x15\x15\x15\x15\x15\x15\x15.......\x15.......\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xa2####\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc' +'\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc' +'\xbc\xbc\xbc\x9bp\x9cq\x9bp\x9bp\x9bp\x9bp\x9bp\x9bp\x9bp\x9bp\x9bp\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbc\xbc\xbc\xbc\xbc\xbc\xbc' +'\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbd\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbc\xbd\xbd\xbc\xbc\x9bp\x9bp\xbd\xbc\xbc\xbc\xbc\xbd\xbc\xbd\xbd\xbd\xbc\xbc\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\x9bp\xbc\xbc' +'\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbd\xbd\xbd\xbd\xbc\xbc\xbd\xbc\xbd\xbc\xbc\xbd\xbc\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbc' +'\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbc\xbd\xbd\xbc\xbc\xbd\xbd\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd' +'\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd' +'\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbd\xbc\xbd\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbc\xbd\xbd\xbd\xbc\xbc\xbc\xbc\xbd\xbc\xbc\xbc\xbd\xbd\xbd\xbd\xbd\xbc\xbd\xbc\xbc' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc\xbc' +'\xbc\xbc\xbc\xbc\xbc\xcf\xcf\xbc\xbc\xbc\xbc\xbc\xbc\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xd2\xcc\xcc\xcc\xcc\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd0\x15' +'77777777777777777777777777777777777777777777777\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x157\x1b777\x1b\x1b7\x1b7\x1b7\x1b7777\x1b7\x1b\x1b7\x1b\x1b\x1b\x1b\x1b\x1b%%77' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b\xcf\xcf\xcf\xcf\xcf\xcf7\x1b7\x1b@@@7\x1b\x15\x15\x15\x15\x15\x90\x90\x90\x90]\x90\x90' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x1b\x15\x15\x15\x15\x15\x1b\x15\x150000000000000000' +'0000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15$\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15@' +'00000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x150000000\x150000000\x150000000\x150000000\x15' +'0000000\x150000000\x150000000\x150000000\x15@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' +'\x90\x90zvzv\x90\x90\x90zv\x90zv\x90\x90\x90\x90\x90\x90\x90\x90\x90j\x90\x90j\x90zv\x90\x90zv\x9bp\x9bp\x9bp\x9bp\x90\x90\x90\x90\x90(\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90jj\x90\x90\x90\x90' +'j\x90\x9a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15' +'\xd7\x94\x94\x94\xd2&1N\x9es\x9es\x9es\x9es\x9es\xd2\xd2\x9es\x9es\x9es\x9esk\x9drr\xd2NNNNNNNNNBBBB;;k&&&&&\xd2\xd2NNN&1\x94\xd2\xcf' +'\x15111111111111111111111111111111111111111111111111111111111111111' +'11111111111111111111111\x15\x15BB\xad\xad&&1k1111111111111111111111111111111' +'11111111111111111111111111111111111111111111111111111111111\x94&&&1' +'\x15\x15\x15\x15\x151111111111111111111111111111111111111111111\x15111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111\x15\xcb\xcbZZZZ\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb111111111111111111111111111\x15\x15\x15\x15\x15' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x151111111111111111' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xd2\xd2\x15ZZZZZZZZZZ\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcbWWWWWWWW\xd2_______________\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xd2\xd2\xd2\xcb' +'ZZZZZZZZZZ\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb_______________' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xd2\xd2\xd2\xd2\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\x15' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xd2\xd2\xd2\xd2\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xd2\xd2\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xd2' +'1111121111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1112111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111112111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111211111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'2112111212111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111121111111111111111111111111111111111' +'1111111111112111111121211111111111111111111111111111111111111112' +'2111111111111111111111111111111211111111211111111111111111111111' +'1111111111111211111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111112111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111211111111111111111111111111111111111111111111111111111111111' +'1111112111111111111111111111111111111111121212111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1212221111112111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1222211111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111112111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111211111112111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111211111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111122' +'1111111111112221211111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111121' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111112111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111112111111111111111111111111111111111111111111111' +'1111112111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111211111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111121' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111112111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111121111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111211112111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111112111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111112111111111111111111111111111111' +'1111112111112111111111111111111111111111111111111111111121111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111112111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'111111111111111111111&111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111\x15\x15\x15\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x150000000000000000000000000000000000000000$$$$$$\x89\x89' +'000000000000$\x90\x90\x900000000000000000GGGGGGGGGG00\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b0@<<<\x90@@@@@@@@@@\x90)' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b%%@@00000000000000000000000000000000' +'00000000000000000000000000000000000000KKKKKKKKKK@@\x89\x89\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15' +'\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab\xab)))))))))\xab\xab7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b\x1b\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b' +'7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b%\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b7\x1b7\x1b77\x1b' +'7\x1b7\x1b7\x1b7\x1b)\xa8\xa87\x1b7\x1b07\x1b7\x1b\x1b\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b7\x1b77777\x1b77777\x1b7\x1b7\x1b\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x150%%\x1b00000' +'00 at 000@0000 at 00000000000000000000000::@@:\xcf\xcf\xcf\xcf\x15\x15\x15\x15XXXXXX\xca\xca\xa3\xc5\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000\x90\x90\x90\x90\x15\x15\x15\x15\x15\x15\x15\x15' +'::00000000000000000000000000000000000000000000000000::::::::::::' +'::::@@\x15\x15\x15\x15\x15\x15\x15\x15\x89\x89GGGGGGGGGG\x15\x15\x15\x15\x15\x15@@@@@@@@@@@@@@@@@@000000\x89\x89\x890\x8900@' +'GGGGGGGGGG0000000000000000000000000000@@@@@@@@\x89\x890000000000000000' +'0000000@@@@@@@@@@@::\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x8911111111111111111111111111111\x15\x15\x15' +'@@@:00000000000000000000000000000000000000000000000@::@@@@::@:::' +':\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x15$GGGGGGGGGG\x15\x15\x15\x15\x89\x8900000@$000000000GGGGGGGGGG00000\x15' +'00000000000000000000000000000000000000000@@@@@@::@@::@@\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000 at 00000000@:\x15\x15GGGGGGGGGG\x15\x15\x89\x89\x89\x890000000000000000$000000\xca\xca\xca0:@:00' +'000000000000000000000000000000000000000000000000 at 0@@@00@@00000@@' +'0 at 0\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1500$\x89\x8900000000000:@@::\x89\x890$$:@\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15000000\x15\x15000000\x15\x15000000\x15\x15\x15\x15\x15\x15\x15\x15\x150000000\x150000000\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xa8%%%%\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' '\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'...................................88=88=88\x838=\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15................' -'.......\x15\x15\x15\x15.................................................\x15\x15\x15\x15' +'00000000000000000000000000000000000::@::@::\x89:@\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111111111\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x150000000000000000' +'0000000\x15\x15\x15\x150000000000000000000000000000000000000000000000000\x15\x15\x15\x15' '\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18' '\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18' '\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18' @@ -61857,367 +61865,367 @@ '\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17' '\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17' '\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17' -'////////////////////////////////////////////////////////////////' -'///////////////////////////////////////////0///////0////0///////' -'//////////////////////////////////////////////////0/////////////' -'/////////////////0/0/////////////////////////////////////////0//' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////\x16\x16////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x151=1111111111\xab1111111111111\x1511111\x151\x15' -'11\x1511\x151111111111************************************************' -'**************************************************\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1\xa1' -'\xa1\xa1\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15*********************************************' -'****************************************************************' -'******************************))))))****************************' -'****************************************************************' -'****************************************************************' -'**************************************************************i\x94' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15************************************************' -'****************\x15\x15**********************************************' -'********\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15**********))\x99\xc7\x15\x15' -'<<<<<<<<<<<<<<<<\x8e\x8e\x8e\x8f\x8e\x8e\x8e\x97l\x8e\x15\x15\x15\x15\x15\x15================\x8eee__\x97l\x97l\x97l\x97l\x97l\x97' -'l\x97l\x97l\x8e\x8e\x97l\x8e\x8e\x8e\x8e___|\x8e}\x15\x8e}\x8e\x8ee\x98m\x98m\x98m\x82\x8e\x8e\xadb\xbc\xbc\xbb\x15\x8e\x9f\x82\x8e\x15\x15\x15\x15)*)*)\x15)*)*)*)*)*' -'****************************************************************' -'*************************************************************\x15\x15\x08' -'\x15\x87\x87\x7f\x9b\x7f\x87\x88\x92g\x87\xaaw`xwAAAAAAAAAAx\x87\xb4\xb3\xb4\x87\x8744444444444444444444444444\x92\x87g\xa4\\' -'\xa4\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x92\xb3g\xb3\x92g\x89\x93h\x89\x89,,,,,,,,,,!,,,,,,,,,,,,,,,' -',,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x15' -'\x15\x15,,,,,,\x15\x15,,,,,,\x15\x15,,,,,,\x15\x15,,,\x15\x15\x15\x9b\x9b\xb3\xa4\xc5\x9b\x9b\x15\xc6\xb5\xb5\xb5\xb5\xc6\xc6\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x0e\x0e\x0e\xc7\xc4\x15\x15' -'............\x15..........................\x15...................\x15..\x15.' -'..............\x15\x15..............\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................................' -'...........................................................\x15\x15\x15\x15\x15' -'\x83\x8a\x83\x15\x15\x15\x15RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR\x15\x15\x15\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIWWWW\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7WW\xc7\xc2\xc2\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2=\x15\x15' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111211111112111121111111' +'1111111111111111111111111111111111111111111111111121111111111111' +'1111111111111111121211111111111111111111111111111111111111111211' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111\x16\x161111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'11111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15\x153 at 3333333333\xb13333333333333\x1533333\x153\x15' +'33\x1533\x153333333333,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7\xa7' +'\xa7\xa7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++++++,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,o\x9a' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,\x15\x15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15,,,,,,,,,,++\x9f\xcf\x15\x15' +'>>>>>>>>>>>>>>>>\x94\x94\x94\x95\x94\x94\x94\x9dr\x94\x15\x15\x15\x15\x15\x15@@@@@@@@@@@@@@@@\x94kkee\x9dr\x9dr\x9dr\x9dr\x9dr\x9d' +'r\x9dr\x9dr\x94\x94\x9dr\x94\x94\x94\x94eee\x82\x94\x83\x15\x94\x83\x94\x94k\x9es\x9es\x9es\x88\x94\x94\xb3h\xc2\xc2\xc1\x15\x94\xa5\x88\x94\x15\x15\x15\x15+,+,+\x15+,+,+,+,+,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\x15\x15\x08' +'\x15\x8d\x8d\x85\xa1\x85\x8d\x8e\x98m\x8d\xb0}f~}DDDDDDDDDD~\x8d\xba\xb9\xba\x8d\x8d66666666666666666666666666\x98\x8dm\xaab' +'\xaa\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x1a\x98\xb9m\xb9\x98m\x8f\x99n\x8f\x8f.........."...............' +'..............................!!...............................\x15' +'\x15\x15......\x15\x15......\x15\x15......\x15\x15...\x15\x15\x15\xa1\xa1\xb9\xaa\xcd\xa1\xa1\x15\xce\xbb\xbb\xbb\xbb\xce\xce\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x0e\x0e\x0e\xcf\xcc\x15\x15' +'000000000000\x1500000000000000000000000000\x150000000000000000000\x1500\x150' +'00000000000000\x15\x1500000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000000000000' +'00000000000000000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15' +'\x89\x90\x89\x15\x15\x15\x15XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO]]]]\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf]]\xcf\xca\xca\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca@\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.............................\x15\x15\x15................................' -'.................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15=OOOOOOOOOOOOOOOOOOOOOOOOOOO\x15\x15\x15\x15' -'................................RRRR\x15\x15\x15\x15\x15\x15\x15\x15\x15...................' -'.G........G\x15\x15\x15\x15\x15......................................=====\x15\x15\x15\x15\x15' -'..............................\x15\x83................................' -'....\x15\x15\x15\x15........\x83GGGGG\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'5555555555555555555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b................................................' -'..............................\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x155555555555555555' -'55555555555555555555\x15\x15\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15' -'........................................\x15\x15\x15\x15\x15\x15\x15\x15................' -'....................................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'00000000000000000000000000000\x15\x15\x1500000000000000000000000000000000' +'00000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15 at UUUUUUUUUUUUUUUUUUUUUUUUUUU\x15\x15\x15\x15' +'00000000000000000000000000000000XXXX\x15\x15\x15\x15\x15\x15\x15\x15\x150000000000000000000' +'0K00000000K\x15\x15\x15\x15\x1500000000000000000000000000000000000000@@@@@\x15\x15\x15\x15\x15' +'000000000000000000000000000000\x15\x8900000000000000000000000000000000' +'0000\x15\x15\x15\x1500000000\x89KKKKK\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'7777777777777777777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b000000000000000000000000000000000000000000000000' +'000000000000000000000000000000\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x157777777777777777' +'77777777777777777777\x15\x15\x15\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15\x15\x15' +'0000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x150000000000000000' +'000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.......................................................\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'......................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15........\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1500000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'111111\x15\x151\x1511111111111111111111111111111111111111111111\x1511\x15\x15\x151\x15\x151' -'1111111111111111111111\x15\x90ZZZZZZZZ11111111111111111111111\xcb\xcbZZZZZZZ' -'1111111111111111111111111111111\x15\x15\x15\x15\x15\x15\x15\x15ZZZZZZZZZ\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x151111111111111111111\x1511\x15\x15\x15\x15\x15ZZZZZ' -'1111111111111111111111ZZZZZZ\x15\x15\x15\x8a11111111111111111111111111\x15\x15\x15\x15\x15\x90' +'333333\x15\x153\x1533333333333333333333333333333333333333333333\x1533\x15\x15\x153\x15\x153' +'3333333333333333333333\x15\x96````````33333333333333333333333\xd3\xd3```````' +'3333333333333333333333333333333\x15\x15\x15\x15\x15\x15\x15\x15`````````\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x153333333333333333333\x1533\x15\x15\x15\x15\x15`````' +'3333333333333333333333``````\x15\x15\x15\x9033333333333333333333333333\x15\x15\x15\x15\x15\x96' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'11111111111111111111111111111111111111111111111111111111\x15\x15\x15\x15ZZ11' -'ZZZZZZZZZZZZZZZZ\x15\x15ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ' -'1===\x15==\x15\x15\x15\x15\x15====1111\x15111\x1511111111111111111111111111111\x15\x15===\x15\x15\x15\x15=' -'[[[[ZZZZZ\x15\x15\x15\x15\x15\x15\x15\x90\x90\x90\x90\x90\x90\x90\x90\x90\x15\x15\x15\x15\x15\x15\x1511111111111111111111111111111ZZ\x90' -'11111111111111111111111111111ZZZ\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'11111111\xcb1111111111111111111111111111==\x15\x15\x15\x15ZZZZZ\x90\x90\x90\x90\x90\x90\x90\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'111111111111111111111111111111111111111111111111111111\x15\x15\x15\x8a\x8a\x8a\x8a\x8a\x8a\x8a' -'1111111111111111111111\x15\x15ZZZZZZZZ1111111111111111111\x15\x15\x15\x15\x15ZZZZZZZZ' -'111111111111111111\x15\x15\x15\x15\x15\x15\x15\x90\x90\x90\x90\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15ZZZZZZZ\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'33333333333333333333333333333333333333333333333333333333\x15\x15\x15\x15``33' +'````````````````\x15\x15``````````````````````````````````````````````' +'3@@@\x15@@\x15\x15\x15\x15\x15@@@@3333\x15333\x1533333333333333333333333333333\x15\x15@@@\x15\x15\x15\x15@' +'aaaa`````\x15\x15\x15\x15\x15\x15\x15\x96\x96\x96\x96\x96\x96\x96\x96\x96\x15\x15\x15\x15\x15\x15\x1533333333333333333333333333333``\x96' +'33333333333333333333333333333```\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'33333333\xd33333333333333333333333333333@@\x15\x15\x15\x15`````\x96\x96\x96\x96\x96\x96\x96\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'333333333333333333333333333333333333333333333333333333\x15\x15\x15\x90\x90\x90\x90\x90\x90\x90' +'3333333333333333333333\x15\x15````````3333333333333333333\x15\x15\x15\x15\x15````````' +'333333333333333333\x15\x15\x15\x15\x15\x15\x15\x96\x96\x96\x96\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15```````\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'1111111111111111111111111111111111111111111111111111111111111111' -'111111111\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'777777777777777777777777777777777777777777777777777\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x15\x15\x15\x15\x15\x15\x15ZZZZZZ' -'************************************====\x15\x15\x15\x15\x15\x15\x15\x15@@@@@@@@@@\x15\x15\x15\x15\x15\x15' +'3333333333333333333333333333333333333333333333333333333333333333' +'333333333\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'999999999999999999999999999999999999999999999999999\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x15\x15\x15\x15\x15\x15\x15``````' +',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,@@@@\x15\x15\x15\x15\x15\x15\x15\x15CCCCCCCCCC\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15LLLLLLLLLKKKKKKKKKKKKKKKKKKKKKK\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15RRRRRRRRRQQQQQQQQQQQQQQQQQQQQQQ\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'11111111111111111111111111111ZZZZZZZZZZ1\x15\x15\x15\x15\x15\x15\x15\x15****************' -'******===========JJJJuuuuu\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'33333333333333333333333333333``````````3\x15\x15\x15\x15\x15\x15\x15\x15,,,,,,,,,,,,,,,,' +',,,,,,@@@@@@@@@@@PPPP{{{{{\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'8=8.....................................................========' -'=======\x83\x83\x83\x83\x83\x83\x83\x15\x15\x15\x15XXXXXXXXXWWWWWWWWWWWDDDDDDDDDD\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15=' -'==8.............................................888====88==\x83\x83\n\x83\x83' -'\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\n\x15\x15.........................\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15' -'===....................................=====8========\x15DDDDDDDDDD' -'\x83\x83\x83\x83.88\x15\x15\x15\x15\x15\x15\x15\x15\x15...................................=\x83\x83.\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'==8................................................888=========8' -'8....\x83\x83\x83\x83====\x83\x15\x15DDDDDDDDDD.\x83.\x83\x83\x83\x15RRRRRRRRRRRRRRRRRRRR\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'..................\x15.........................888===88=8==\x83\x83\x83\x83\x83\x83=\x15' +':@:00000000000000000000000000000000000000000000000000000@@@@@@@@' +'@@@@@@@\x89\x89\x89\x89\x89\x89\x89\x15\x15\x15\x15^^^^^^^^^]]]]]]]]]]]GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15@' +'@@:000000000000000000000000000000000000000000000:::@@@@::@@\x89\x89\n\x89\x89' +'\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\n\x15\x150000000000000000000000000\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15' +'@@@000000000000000000000000000000000000@@@@@:@@@@@@@@\x15GGGGGGGGGG' +'\x89\x89\x89\x890::\x15\x15\x15\x15\x15\x15\x15\x15\x1500000000000000000000000000000000000@\x89\x890\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'@@:000000000000000000000000000000000000000000000000:::@@@@@@@@@:' +':0000\x89\x89\x89\x89@@@@\x89\x15\x15GGGGGGGGGG0\x890\x89\x89\x89\x15XXXXXXXXXXXXXXXXXXXX\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000\x150000000000000000000000000:::@@@::@:@@\x89\x89\x89\x89\x89\x89@\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.......\x15.\x15....\x15...............\x15..........\x83\x15\x15\x15\x15\x15\x15................' -'...............................=888========\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15' -'==88\x15........\x15\x15..\x15\x15......................\x15.......\x15..\x15.....\x15==.88' -'=8888\x15\x1588\x15\x15888\x15\x15.\x15\x15\x15\x15\x15\x158\x15\x15\x15\x15\x15.....88\x15\x15=======\x15\x15\x15=====\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000\x150\x150000\x15000000000000000\x150000000000\x89\x15\x15\x15\x15\x15\x150000000000000000' +'0000000000000000000000000000000@:::@@@@@@@@\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15' +'@@::\x1500000000\x15\x1500\x15\x150000000000000000000000\x150000000\x1500\x1500000\x15@@0::' +'@::::\x15\x15::\x15\x15:::\x15\x150\x15\x15\x15\x15\x15\x15:\x15\x15\x15\x15\x1500000::\x15\x15@@@@@@@\x15\x15\x15@@@@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.....................................................888========' -'88===8=....\x83\x83\x83\x83\x83DDDDDDDDDD\x15\x83\x15\x83=\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................888======8=8888=' -'=8==..\x83.\x15\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'00000000000000000000000000000000000000000000000000000:::@@@@@@@@' +'::@@@:@0000\x89\x89\x89\x89\x89GGGGGGGGGG\x15\x89\x15\x89@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000000000000000000000000000000000:::@@@@@@:@::::@' +'@:@@00\x890\x15\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...............................................888====\x15\x158888==8=' -'=\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83\x83....==\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................888========88=8=' -'=\x83\x83\x83.\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x8a\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...........................................=8=88======8=\x15\x15\x15\x15\x15\x15\x15\x15' -'DDDDDDDDDD\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...........................\x15\x15===88====8=====\x15\x15\x15\x15DDDDDDDDDDRR\x83\x83\x83\xc2' +'00000000000000000000000000000000000000000000000:::@@@@\x15\x15::::@@:@' +'@\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x89\x890000@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000000000000000000000000000000000:::@@@@@@@@::@:@' +'@\x89\x89\x890\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000@:@::@@@@@@:@\x15\x15\x15\x15\x15\x15\x15\x15' +'GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000000000000\x15\x15@@@::@@@@:@@@@@\x15\x15\x15\x15GGGGGGGGGGXX\x89\x89\x89\xca' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'............................................888=========8==\x83\x15\x15\x15\x15' +'00000000000000000000000000000000000000000000:::@@@@@@@@@:@@\x89\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1555555555555555555555555555555555' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1bDDDDDDDDDDRRRRRRRRR\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15.' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x1577777777777777777777777777777777' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1bGGGGGGGGGGXXXXXXXXX\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x150' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.======;;==........................................======8.====\x83' -'\x83\x83\x83\x83\x83\x83\x83=\x15\x15\x15\x15\x15\x15\x15\x15.======88===....................................' -'....\x15\x15....=============8==\x83\x83\x83.\x83\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.........................................................\x15\x15\x15\x15\x15\x15\x15' -'.........\x15.....................................8=======\x15======8;' -'.\x83\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDDRRRRRRRRRRRRRRRRRRR\x15\x15\x15\x83\x83..............' -'................\x15\x15======================\x158=======8==8==\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0@@@@@@==@@0000000000000000000000000000000000000000@@@@@@:0@@@@\x89' +'\x89\x89\x89\x89\x89\x89\x89@\x15\x15\x15\x15\x15\x15\x15\x150@@@@@@::@@@000000000000000000000000000000000000' +'0000\x15\x150000@@@@@@@@@@@@@:@@\x89\x89\x890\x89\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15' +'000000000\x150000000000000000000000000000000000000:@@@@@@@\x15@@@@@@:=' +'0\x89\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGGXXXXXXXXXXXXXXXXXXX\x15\x15\x15\x89\x8900000000000000' +'0000000000000000\x15\x15@@@@@@@@@@@@@@@@@@@@@@\x15:@@@@@@@:@@:@@\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.......\x15..\x15......................................======\x15\x15\x15=\x15==\x15=' -'======.=\x15\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15......\x15..\x15......................' -'..........88888\x15==\x1588=8=.\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000\x1500\x1500000000000000000000000000000000000000@@@@@@\x15\x15\x15@\x15@@\x15@' +'@@@@@@0@\x15\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15000000\x1500\x150000000000000000000000' +'0000000000:::::\x15@@\x15::@:@0\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15...................==88\x83\x83\x15\x15\x15\x15\x15\x15\x15' -'................................................................' -'................................................................' -'..........................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x150000000000000000000@@::\x89\x89\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'00000000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG' -'GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\x15\x83\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................................' -'................................................................' -'................................................................' -'....\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK' +'KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK\x15\x89\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'...............................................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'00000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................................' -'.......\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'.........................................................\x15\x15\x15\x15\x15\x15\x15' -'...............................\x15DDDDDDDDDD\x15\x15\x15\x15\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000000000000000000000000000000000000000000\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000\x15GGGGGGGGGG\x15\x15\x15\x15\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15..............................\x15\x15=====\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................=======\x83\x83\x83\x83\x83\xc2\xc2\xc2\xc2' -'####\x83\xc2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15DDDDDDDDDD\x15RRRRRRR\x15.....................\x15\x15\x15\x15\x15...' -'................\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15000000000000000000000000000000\x15\x15@@@@@\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'000000000000000000000000000000000000000000000000@@@@@@@\x89\x89\x89\x89\x89\xca\xca\xca\xca' +'$$$$\x89\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15GGGGGGGGGG\x15XXXXXXX\x15000000000000000000000\x15\x15\x15\x15\x15000' +'0000000000000000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'55555555555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'RRRRRRRRRRRRRRRRRRRRRRR\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'77777777777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'XXXXXXXXXXXXXXXXXXXXXXX\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'................................................................' -'.....\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15.8888888888888888888888888888888888888888888888\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15====#############\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15$$\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////////////\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'///////////////////////////////////////////////////\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'///////////////////////////////\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////\x15\x15\x15\x15' -'................................................................' -'...........................................\x15\x15\x15\x15\x15.............\x15\x15\x15' -'.........\x15\x15\x15\x15\x15\x15\x15..........\x15\x15\xc2==\x83\x08\x08\x08\x08\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000000000000' +'00000\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x150::::::::::::::::::::::::::::::::::::::::::::::\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15@@@@$$$$$$$$$$$$$\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15&&\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'11111111111111111111111111111111111111111111111111\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111111111111111111111111\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'1111111111111111111111111111111\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x151111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111111111111111111111111111111111\x15\x15\x15\x15' +'0000000000000000000000000000000000000000000000000000000000000000' +'0000000000000000000000000000000000000000000\x15\x15\x15\x15\x150000000000000\x15\x15\x15' +'000000000\x15\x15\x15\x15\x15\x15\x150000000000\x15\x15\xca@@\x89\x08\x08\x08\x08\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\x15\x15\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc288===\xc2\xc2\xc2888888\x08\x08\x08\x08\x08\x08\x08\x08=====' -'===\xc2\xc2=======\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2====\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7===\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca::@@@\xca\xca\xca::::::\x08\x08\x08\x08\x08\x08\x08\x08@@@@@' +'@@@\xca\xca@@@@@@@\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca@@@@\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf@@@\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15RRRRRRRRRRRRRRRRRRRR\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15RRRRRRRRRRRRRRRRRRRRRRRRR\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15XXXXXXXXXXXXXXXXXXXX\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15XXXXXXXXXXXXXXXXXXXXXXXXX\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'55555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b555555555555' -'55555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b555555555555555555555555' -'55\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b5\x1555\x15\x155\x15\x1555\x15\x155555\x1555555555\x1b\x1b\x1b\x1b\x15\x1b\x15\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b55\x155555\x15\x1555555555\x155555555\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55\x155555\x15' -'55555\x155\x15\x15\x155555555\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555555555555555' -'555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b55555555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b5555' -'5555555555555555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b5555555555555555' -'5555555555\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15555555555555555555555555' -'5\xb0\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xb7\x1b\x1b\x1b\x1b\x1b\x1b5555555555555555555555555\xb0\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xb7\x1b\x1b\x1b\x1b\x1b\x1b5555555555555555555555555\xb0\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xb7\x1b\x1b\x1b\x1b\x1b\x1b5555555555555555555555555\xb0\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xb7\x1b\x1b\x1b\x1b\x1b\x1b5555555555555555555555555\xb0\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' -'\x1b\x1b\x1b\xb7\x1b\x1b\x1b\x1b\x1b\x1b5\x1b\x15\x15BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' -'=======================================================\xc2\xc2\xc2\xc2=====' -'=============================================\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2=\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc2\xc2\xc2\xc2=\xc2\xc2\x83\x83\x83\x83\x83\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15=====\x15===============\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'77777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b777777777777' +'77777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b777777777777777777777777' +'77\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b7\x1577\x15\x157\x15\x1577\x15\x157777\x1577777777\x1b\x1b\x1b\x1b\x15\x1b\x15\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b77\x157777\x15\x1577777777\x157777777\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77\x157777\x15' +'77777\x157\x15\x15\x157777777\x15\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777777777777777' +'777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b77777777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b7777' +'7777777777777777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b7777777777777777' +'7777777777\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x15\x15777777777777777777777777' +'7\xb6\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xbd\x1b\x1b\x1b\x1b\x1b\x1b7777777777777777777777777\xb6\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xbd\x1b\x1b\x1b\x1b\x1b\x1b7777777777777777777777777\xb6\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xbd\x1b\x1b\x1b\x1b\x1b\x1b7777777777777777777777777\xb6\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\xbd\x1b\x1b\x1b\x1b\x1b\x1b7777777777777777777777777\xb6\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b\x1b' +'\x1b\x1b\x1b\xbd\x1b\x1b\x1b\x1b\x1b\x1b7\x1b\x15\x15EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' +'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\xca\xca\xca\xca@@@@@' +'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\xca\xca\xca\xca\xca\xca\xca\xca@\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xca\xca\xca\xca@\xca\xca\x89\x89\x89\x89\x89\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15@@@@@\x15@@@@@@@@@@@@@@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'=======\x15=================\x15\x15=======\x15==\x15=====\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'@@@@@@@\x15@@@@@@@@@@@@@@@@@\x15\x15@@@@@@@\x15@@\x15@@@@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'1111111111111111111111111111111111111111111111111111111111111111' -'1111111111111111111111111111111111111111111111111111111111111111' -'1111111111111111111111111111111111111111111111111111111111111111' -'11111\x15\x15ZZZZZZZZZ=======\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'7777777777777777777777777777777777\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' -'\x1d\x1d\x1d\x1d=======\x15\x15\x15\x15\x15EEEEEEEEEE\x15\x15\x15\x15\x90\x90\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'3333333333333333333333333333333333333333333333333333333333333333' +'3333333333333333333333333333333333333333333333333333333333333333' +'3333333333333333333333333333333333333333333333333333333333333333' +'33333\x15\x15`````````@@@@@@@\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'9999999999999999999999999999999999\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d\x1d' +'\x1d\x1d\x1d\x1d@@@@@@@\x15\x15\x15\x15\x15HHHHHHHHHH\x15\x15\x15\x15\x96\x96\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15JJJJJJJJJJJJJJJ' -'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ\xbdJJJ\x99JJJJ\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15PPPPPPPPPPPPPPP' +'PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP\xc3PPP\x9fPPPP\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'****\x15***************************\x15**\x15*\x15\x15*\x15**********\x15****\x15*\x15*\x15\x15\x15\x15' -'\x15\x15*\x15\x15\x15\x15*\x15*\x15*\x15***\x15**\x15*\x15\x15*\x15*\x15*\x15*\x15*\x15**\x15*\x15\x15****\x15*******\x15****\x15****\x15*\x15' -'**********\x15*****************\x15\x15\x15\x15\x15***\x15*****\x15*****************\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xb6\xb6\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'NNNNNNNNNNNWW\x15\x15\x15\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc2\xc7\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1' -'\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc7\xc7\x15\x15\x15\x15\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1' -'\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc3\xc1\xc1\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\xc1\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2\xc2' -'\xc3\xc3\xc3\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\x15\x15\x15\x15' -'\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\xc3\x15\x15\x15\x15\x15\x15\x15\xc3\xc3\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +',,,,\x15,,,,,,,,,,,,,,,,,,,,,,,,,,,\x15,,\x15,\x15\x15,\x15,,,,,,,,,,\x15,,,,\x15,\x15,\x15\x15\x15\x15' +'\x15\x15,\x15\x15\x15\x15,\x15,\x15,\x15,,,\x15,,\x15,\x15\x15,\x15,\x15,\x15,\x15,\x15,,\x15,\x15\x15,,,,\x15,,,,,,,\x15,,,,\x15,,,,\x15,\x15' +',,,,,,,,,,\x15,,,,,,,,,,,,,,,,,\x15\x15\x15\x15\x15,,,\x15,,,,,\x15,,,,,,,,,,,,,,,,,\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xbc\xbc\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'TTTTTTTTTTT]]\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xcf\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8' +'\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc7\xc7\xc7\xc7\xc7\xc7\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xcf\xcf\x15\x15\x15\x15\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8' +'\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc8\xc7\xc7\xc7\xc7\xcb\xc7\xc7\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xcb\xcb\xcb\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\x15\x15\x15\x15' +'\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\xcb\x15\x15\x15\x15\x15\x15\x15\xcb\xcb\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xca\xc7\xc7\xc7\xca\xca\xca\xa7\xa7\xa7\xa7\xa7' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7' -'\xca\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xc7\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xc7\xc7\xc7\xc7\xc7\xc7\xca\xc7\xc7\xc7\xca\xca\xca\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xca\xca\x15\x15\x15\xc7\xc7\xc7\xc7\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xd2\xd2\xd2\xad\xad\xad\xad\xad' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf' +'\xd2\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xcf\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xcf\xcf\xcf\xd2\xd2\xd2\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xd2\xd2\x15\x15\x15\xcf\xcf\xcf\xcf\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\xca\xca\xca\xca\x15\x15\x15\xca\x15\xca\xca\xca\xca' -'\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\x15\x15\x15\x15\x15\x15' -'\xca\xca\xca\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca\xca' +'\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\xd2\xd2\xd2\xd2\x15\x15\x15\xd2\x15\xd2\xd2\xd2\xd2' +'\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15' +'\xd2\xd2\xd2\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2\xd2' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\xc7\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\xcf\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'/0//////////////////////////////////////////////////////////////' -'////////////////////////////////////0///////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////0/////////////////////////////' -'/////////////////////////////////0//////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////0/////////////////////' -'////////////////////////////////////////////////////////////////' -'///0////////0///////////////0///////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////////////0//////////////////0//' -'/////////////////////////0//////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////0///////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////0///////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'///////////////////////////0////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/////////////////////////////////////////////0//////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'///////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'/////////////////////////////////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////\x16\x16////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'//////////////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'////////////////////////////////////////////////////////////////' -'/////////////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'1211111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111112111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111211111111111111111111111111111' +'1111111111111111111111111111111112111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111112111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1112111111112111111111111111211111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111112111111111111111111211' +'1111111111111111111111111211111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111211111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111112111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111112111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111112111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'11111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'11111111111111111111111111111111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111\x16\x1611111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x161111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'1111111111111111111111111111111111111111111111111111111111111111' +'111111111111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' -'//////////////////////////////\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' +'111111111111111111111111111111\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' '\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16' @@ -62229,10 +62237,10 @@ '\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' -'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<' -'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<' -'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<' -'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' +'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' +'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' +'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' +'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15\x15' '\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17' '\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17' '\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17\x17' @@ -64468,109 +64476,6 @@ } _special_casing_corrected = { -223: None, -304: None, -329: None, -496: None, -912: None, -944: None, -1415: None, -7830: None, -7831: None, -7832: None, -7833: None, -7834: None, -8016: None, -8018: None, -8020: None, -8022: None, -8064: None, -8065: None, -8066: None, -8067: None, -8068: None, -8069: None, -8070: None, -8071: None, -8072: None, -8073: None, -8074: None, -8075: None, -8076: None, -8077: None, -8078: None, -8079: None, -8080: None, -8081: None, -8082: None, -8083: None, -8084: None, -8085: None, -8086: None, -8087: None, -8088: None, -8089: None, -8090: None, -8091: None, -8092: None, -8093: None, -8094: None, -8095: None, -8096: None, -8097: None, -8098: None, -8099: None, -8100: None, -8101: None, -8102: None, -8103: None, -8104: None, -8105: None, -8106: None, -8107: None, -8108: None, -8109: None, -8110: None, -8111: None, -8114: None, -8115: None, -8116: None, -8118: None, -8119: None, -8124: None, -8130: None, -8131: None, -8132: None, -8134: None, -8135: None, -8140: None, -8146: None, -8147: None, -8150: None, -8151: None, -8162: None, -8163: None, -8164: None, -8166: None, -8167: None, -8178: None, -8179: None, -8180: None, -8182: None, -8183: None, -8188: None, -64256: None, -64257: None, -64258: None, -64259: None, -64260: None, -64261: None, From pypy.commits at gmail.com Wed Jan 8 07:48:15 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 04:48:15 -0800 (PST) Subject: [pypy-commit] pypy py3.7: merge py3.6 Message-ID: <5e15cf8f.1c69fb81.a89ff.ff2c@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98489:2779449dd1d5 Date: 2020-01-08 13:04 +0100 http://bitbucket.org/pypy/pypy/changeset/2779449dd1d5/ Log: merge py3.6 diff --git a/lib-python/3/asyncio/compat.py b/lib-python/3/asyncio/compat.py new file mode 100644 --- /dev/null +++ b/lib-python/3/asyncio/compat.py @@ -0,0 +1,18 @@ +"""Compatibility helpers for the different Python versions.""" + +import sys + +PY34 = sys.version_info >= (3, 4) +PY35 = sys.version_info >= (3, 5) +PY352 = sys.version_info >= (3, 5, 2) + + +def flatten_list_bytes(list_of_data): + """Concatenate a sequence of bytes-like objects.""" + if not PY34: + # On Python 3.3 and older, bytes.join() doesn't handle + # memoryview. + list_of_data = ( + bytes(data) if isinstance(data, memoryview) else data + for data in list_of_data) + return b''.join(list_of_data) diff --git a/lib-python/3/asyncio/test_utils.py b/lib-python/3/asyncio/test_utils.py new file mode 100644 --- /dev/null +++ b/lib-python/3/asyncio/test_utils.py @@ -0,0 +1,537 @@ +"""Utilities shared by tests.""" + +import collections +import contextlib +import io +import logging +import os +import re +import socket +import socketserver +import sys +import tempfile +import threading +import time +import unittest +import weakref + +from unittest import mock + +from http.server import HTTPServer +from wsgiref.simple_server import WSGIRequestHandler, WSGIServer + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +from . import base_events +from . import compat +from . import events +from . import futures +from . import selectors +from . import tasks +from .coroutines import coroutine +from .log import logger +from test import support + + +if sys.platform == 'win32': # pragma: no cover + from .windows_utils import socketpair +else: + from socket import socketpair # pragma: no cover + + +def data_file(filename): + if hasattr(support, 'TEST_HOME_DIR'): + fullname = os.path.join(support.TEST_HOME_DIR, filename) + if os.path.isfile(fullname): + return fullname + fullname = os.path.join(os.path.dirname(os.__file__), 'test', filename) + if os.path.isfile(fullname): + return fullname + raise FileNotFoundError(filename) + + +ONLYCERT = data_file('ssl_cert.pem') +ONLYKEY = data_file('ssl_key.pem') + + +def dummy_ssl_context(): + if ssl is None: + return None + else: + return ssl.SSLContext(ssl.PROTOCOL_SSLv23) + + +def run_briefly(loop): + @coroutine + def once(): + pass + gen = once() + t = loop.create_task(gen) + # Don't log a warning if the task is not done after run_until_complete(). + # It occurs if the loop is stopped or if a task raises a BaseException. + t._log_destroy_pending = False + try: + loop.run_until_complete(t) + finally: + gen.close() + + +def run_until(loop, pred, timeout=30): + deadline = time.time() + timeout + while not pred(): + if timeout is not None: + timeout = deadline - time.time() + if timeout <= 0: + raise futures.TimeoutError() + loop.run_until_complete(tasks.sleep(0.001, loop=loop)) + + +def run_once(loop): + """Legacy API to run once through the event loop. + + This is the recommended pattern for test code. It will poll the + selector once and run all callbacks scheduled in response to I/O + events. + """ + loop.call_soon(loop.stop) + loop.run_forever() + + +class SilentWSGIRequestHandler(WSGIRequestHandler): + + def get_stderr(self): + return io.StringIO() + + def log_message(self, format, *args): + pass + + +class SilentWSGIServer(WSGIServer): + + request_timeout = 2 + + def get_request(self): + request, client_addr = super().get_request() + request.settimeout(self.request_timeout) + return request, client_addr + + def handle_error(self, request, client_address): + pass + + +class SSLWSGIServerMixin: + + def finish_request(self, request, client_address): + # The relative location of our test directory (which + # contains the ssl key and certificate files) differs + # between the stdlib and stand-alone asyncio. + # Prefer our own if we can find it. + keyfile = ONLYKEY + certfile = ONLYCERT + context = ssl.SSLContext() + context.load_cert_chain(certfile, keyfile) + + ssock = context.wrap_socket(request, server_side=True) + try: + self.RequestHandlerClass(ssock, client_address, self) + ssock.close() + except OSError: + # maybe socket has been closed by peer + pass + + +class SSLWSGIServer(SSLWSGIServerMixin, SilentWSGIServer): + pass + + +def _run_test_server(*, address, use_ssl=False, server_cls, server_ssl_cls): + + def app(environ, start_response): + status = '200 OK' + headers = [('Content-type', 'text/plain')] + start_response(status, headers) + return [b'Test message'] + + # Run the test WSGI server in a separate thread in order not to + # interfere with event handling in the main thread + server_class = server_ssl_cls if use_ssl else server_cls + httpd = server_class(address, SilentWSGIRequestHandler) + httpd.set_app(app) + httpd.address = httpd.server_address + server_thread = threading.Thread( + target=lambda: httpd.serve_forever(poll_interval=0.05)) + server_thread.start() + try: + yield httpd + finally: + httpd.shutdown() + httpd.server_close() + server_thread.join() + + +if hasattr(socket, 'AF_UNIX'): + + class UnixHTTPServer(socketserver.UnixStreamServer, HTTPServer): + + def server_bind(self): + socketserver.UnixStreamServer.server_bind(self) + self.server_name = '127.0.0.1' + self.server_port = 80 + + + class UnixWSGIServer(UnixHTTPServer, WSGIServer): + + request_timeout = 2 + + def server_bind(self): + UnixHTTPServer.server_bind(self) + self.setup_environ() + + def get_request(self): + request, client_addr = super().get_request() + request.settimeout(self.request_timeout) + # Code in the stdlib expects that get_request + # will return a socket and a tuple (host, port). + # However, this isn't true for UNIX sockets, + # as the second return value will be a path; + # hence we return some fake data sufficient + # to get the tests going + return request, ('127.0.0.1', '') + + + class SilentUnixWSGIServer(UnixWSGIServer): + + def handle_error(self, request, client_address): + pass + + + class UnixSSLWSGIServer(SSLWSGIServerMixin, SilentUnixWSGIServer): + pass + + + def gen_unix_socket_path(): + with tempfile.NamedTemporaryFile() as file: + return file.name + + + @contextlib.contextmanager + def unix_socket_path(): + path = gen_unix_socket_path() + try: + yield path + finally: + try: + os.unlink(path) + except OSError: + pass + + + @contextlib.contextmanager + def run_test_unix_server(*, use_ssl=False): + with unix_socket_path() as path: + yield from _run_test_server(address=path, use_ssl=use_ssl, + server_cls=SilentUnixWSGIServer, + server_ssl_cls=UnixSSLWSGIServer) + + + at contextlib.contextmanager +def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): + yield from _run_test_server(address=(host, port), use_ssl=use_ssl, + server_cls=SilentWSGIServer, + server_ssl_cls=SSLWSGIServer) + + +def make_test_protocol(base): + dct = {} + for name in dir(base): + if name.startswith('__') and name.endswith('__'): + # skip magic names + continue + dct[name] = MockCallback(return_value=None) + return type('TestProtocol', (base,) + base.__bases__, dct)() + + +class TestSelector(selectors.BaseSelector): + + def __init__(self): + self.keys = {} + + def register(self, fileobj, events, data=None): + key = selectors.SelectorKey(fileobj, 0, events, data) + self.keys[fileobj] = key + return key + + def unregister(self, fileobj): + return self.keys.pop(fileobj) + + def select(self, timeout): + return [] + + def get_map(self): + return self.keys + + +class TestLoop(base_events.BaseEventLoop): + """Loop for unittests. + + It manages self time directly. + If something scheduled to be executed later then + on next loop iteration after all ready handlers done + generator passed to __init__ is calling. + + Generator should be like this: + + def gen(): + ... + when = yield ... + ... = yield time_advance + + Value returned by yield is absolute time of next scheduled handler. + Value passed to yield is time advance to move loop's time forward. + """ + + def __init__(self, gen=None): + super().__init__() + + if gen is None: + def gen(): + yield + self._check_on_close = False + else: + self._check_on_close = True + + self._gen = gen() + next(self._gen) + self._time = 0 + self._clock_resolution = 1e-9 + self._timers = [] + self._selector = TestSelector() + + self.readers = {} + self.writers = {} + self.reset_counters() + + self._transports = weakref.WeakValueDictionary() + + def time(self): + return self._time + + def advance_time(self, advance): + """Move test time forward.""" + if advance: + self._time += advance + + def close(self): + super().close() + if self._check_on_close: + try: + self._gen.send(0) + except StopIteration: + pass + else: # pragma: no cover + raise AssertionError("Time generator is not finished") + + def _add_reader(self, fd, callback, *args): + self.readers[fd] = events.Handle(callback, args, self) + + def _remove_reader(self, fd): + self.remove_reader_count[fd] += 1 + if fd in self.readers: + del self.readers[fd] + return True + else: + return False + + def assert_reader(self, fd, callback, *args): + if fd not in self.readers: + raise AssertionError(f'fd {fd} is not registered') + handle = self.readers[fd] + if handle._callback != callback: + raise AssertionError( + f'unexpected callback: {handle._callback} != {callback}') + if handle._args != args: + raise AssertionError( + f'unexpected callback args: {handle._args} != {args}') + + def assert_no_reader(self, fd): + if fd in self.readers: + raise AssertionError(f'fd {fd} is registered') + + def _add_writer(self, fd, callback, *args): + self.writers[fd] = events.Handle(callback, args, self) + + def _remove_writer(self, fd): + self.remove_writer_count[fd] += 1 + if fd in self.writers: + del self.writers[fd] + return True + else: + return False + + def assert_writer(self, fd, callback, *args): + assert fd in self.writers, 'fd {} is not registered'.format(fd) + handle = self.writers[fd] + assert handle._callback == callback, '{!r} != {!r}'.format( + handle._callback, callback) + assert handle._args == args, '{!r} != {!r}'.format( + handle._args, args) + + def _ensure_fd_no_transport(self, fd): + try: + transport = self._transports[fd] + except KeyError: + pass + else: + raise RuntimeError( + 'File descriptor {!r} is used by transport {!r}'.format( + fd, transport)) + + def add_reader(self, fd, callback, *args): + """Add a reader callback.""" + self._ensure_fd_no_transport(fd) + return self._add_reader(fd, callback, *args) + + def remove_reader(self, fd): + """Remove a reader callback.""" + self._ensure_fd_no_transport(fd) + return self._remove_reader(fd) + + def add_writer(self, fd, callback, *args): + """Add a writer callback..""" + self._ensure_fd_no_transport(fd) + return self._add_writer(fd, callback, *args) + + def remove_writer(self, fd): + """Remove a writer callback.""" + self._ensure_fd_no_transport(fd) + return self._remove_writer(fd) + + def reset_counters(self): + self.remove_reader_count = collections.defaultdict(int) + self.remove_writer_count = collections.defaultdict(int) + + def _run_once(self): + super()._run_once() + for when in self._timers: + advance = self._gen.send(when) + self.advance_time(advance) + self._timers = [] + + def call_at(self, when, callback, *args): + self._timers.append(when) + return super().call_at(when, callback, *args) + + def _process_events(self, event_list): + return + + def _write_to_self(self): + pass + + +def MockCallback(**kwargs): + return mock.Mock(spec=['__call__'], **kwargs) + + +class MockPattern(str): + """A regex based str with a fuzzy __eq__. + + Use this helper with 'mock.assert_called_with', or anywhere + where a regex comparison between strings is needed. + + For instance: + mock_call.assert_called_with(MockPattern('spam.*ham')) + """ + def __eq__(self, other): + return bool(re.search(str(self), other, re.S)) + + +def get_function_source(func): + source = events._get_function_source(func) + if source is None: + raise ValueError("unable to get the source of %r" % (func,)) + return source + + +class TestCase(unittest.TestCase): + @staticmethod + def close_loop(loop): + executor = loop._default_executor + if executor is not None: + executor.shutdown(wait=True) + loop.close() + + def set_event_loop(self, loop, *, cleanup=True): + assert loop is not None + # ensure that the event loop is passed explicitly in asyncio + events.set_event_loop(None) + if cleanup: + self.addCleanup(self.close_loop, loop) + + def new_test_loop(self, gen=None): + loop = TestLoop(gen) + self.set_event_loop(loop) + return loop + + def unpatch_get_running_loop(self): + events._get_running_loop = self._get_running_loop + + def setUp(self): + self._get_running_loop = events._get_running_loop + events._get_running_loop = lambda: None + self._thread_cleanup = support.threading_setup() + + def tearDown(self): + self.unpatch_get_running_loop() + + events.set_event_loop(None) + + # Detect CPython bug #23353: ensure that yield/yield-from is not used + # in an except block of a generator + self.assertEqual(sys.exc_info(), (None, None, None)) + + self.doCleanups() + support.threading_cleanup(*self._thread_cleanup) + support.reap_children() + + if not compat.PY34: + # Python 3.3 compatibility + def subTest(self, *args, **kwargs): + class EmptyCM: + def __enter__(self): + pass + def __exit__(self, *exc): + pass + return EmptyCM() + + + at contextlib.contextmanager +def disable_logger(): + """Context manager to disable asyncio logger. + + For example, it can be used to ignore warnings in debug mode. + """ + old_level = logger.level + try: + logger.setLevel(logging.CRITICAL+1) + yield + finally: + logger.setLevel(old_level) + + +def mock_nonblocking_socket(proto=socket.IPPROTO_TCP, type=socket.SOCK_STREAM, + family=socket.AF_INET): + """Create a mock of a non-blocking socket.""" + sock = mock.MagicMock(socket.socket) + sock.proto = proto + sock.type = type + sock.family = family + sock.gettimeout.return_value = 0.0 + return sock + + +def force_legacy_ssl_support(): + return mock.patch('asyncio.sslproto._is_sslproto_available', + return_value=False) diff --git a/lib-python/3/idlelib/_pyclbr.py b/lib-python/3/idlelib/_pyclbr.py new file mode 100644 --- /dev/null +++ b/lib-python/3/idlelib/_pyclbr.py @@ -0,0 +1,402 @@ +# A private copy of 3.7.0a1 pyclbr for use by idlelib.browser +"""Parse a Python module and describe its classes and functions. + +Parse enough of a Python file to recognize imports and class and +function definitions, and to find out the superclasses of a class. + +The interface consists of a single function: + readmodule_ex(module, path=None) +where module is the name of a Python module, and path is an optional +list of directories where the module is to be searched. If present, +path is prepended to the system search path sys.path. The return value +is a dictionary. The keys of the dictionary are the names of the +classes and functions defined in the module (including classes that are +defined via the from XXX import YYY construct). The values are +instances of classes Class and Function. One special key/value pair is +present for packages: the key '__path__' has a list as its value which +contains the package search path. + +Classes and Functions have a common superclass: _Object. Every instance +has the following attributes: + module -- name of the module; + name -- name of the object; + file -- file in which the object is defined; + lineno -- line in the file where the object's definition starts; + parent -- parent of this object, if any; + children -- nested objects contained in this object. +The 'children' attribute is a dictionary mapping names to objects. + +Instances of Function describe functions with the attributes from _Object. + +Instances of Class describe classes with the attributes from _Object, +plus the following: + super -- list of super classes (Class instances if possible); + methods -- mapping of method names to beginning line numbers. +If the name of a super class is not recognized, the corresponding +entry in the list of super classes is not a class instance but a +string giving the name of the super class. Since import statements +are recognized and imported modules are scanned as well, this +shouldn't happen often. +""" + +import io +import sys +import importlib.util +import tokenize +from token import NAME, DEDENT, OP + +__all__ = ["readmodule", "readmodule_ex", "Class", "Function"] + +_modules = {} # Initialize cache of modules we've seen. + + +class _Object: + "Informaton about Python class or function." + def __init__(self, module, name, file, lineno, parent): + self.module = module + self.name = name + self.file = file + self.lineno = lineno + self.parent = parent + self.children = {} + + def _addchild(self, name, obj): + self.children[name] = obj + + +class Function(_Object): + "Information about a Python function, including methods." + def __init__(self, module, name, file, lineno, parent=None): + _Object.__init__(self, module, name, file, lineno, parent) + + +class Class(_Object): + "Information about a Python class." + def __init__(self, module, name, super, file, lineno, parent=None): + _Object.__init__(self, module, name, file, lineno, parent) + self.super = [] if super is None else super + self.methods = {} + + def _addmethod(self, name, lineno): + self.methods[name] = lineno + + +def _nest_function(ob, func_name, lineno): + "Return a Function after nesting within ob." + newfunc = Function(ob.module, func_name, ob.file, lineno, ob) + ob._addchild(func_name, newfunc) + if isinstance(ob, Class): + ob._addmethod(func_name, lineno) + return newfunc + +def _nest_class(ob, class_name, lineno, super=None): + "Return a Class after nesting within ob." + newclass = Class(ob.module, class_name, super, ob.file, lineno, ob) + ob._addchild(class_name, newclass) + return newclass + +def readmodule(module, path=None): + """Return Class objects for the top-level classes in module. + + This is the original interface, before Functions were added. + """ + + res = {} + for key, value in _readmodule(module, path or []).items(): + if isinstance(value, Class): + res[key] = value + return res + +def readmodule_ex(module, path=None): + """Return a dictionary with all functions and classes in module. + + Search for module in PATH + sys.path. + If possible, include imported superclasses. + Do this by reading source, without importing (and executing) it. + """ + return _readmodule(module, path or []) + +def _readmodule(module, path, inpackage=None): + """Do the hard work for readmodule[_ex]. + + If inpackage is given, it must be the dotted name of the package in + which we are searching for a submodule, and then PATH must be the + package search path; otherwise, we are searching for a top-level + module, and path is combined with sys.path. + """ + # Compute the full module name (prepending inpackage if set). + if inpackage is not None: + fullmodule = "%s.%s" % (inpackage, module) + else: + fullmodule = module + + # Check in the cache. + if fullmodule in _modules: + return _modules[fullmodule] + + # Initialize the dict for this module's contents. + tree = {} + + # Check if it is a built-in module; we don't do much for these. + if module in sys.builtin_module_names and inpackage is None: + _modules[module] = tree + return tree + + # Check for a dotted module name. + i = module.rfind('.') + if i >= 0: + package = module[:i] + submodule = module[i+1:] + parent = _readmodule(package, path, inpackage) + if inpackage is not None: + package = "%s.%s" % (inpackage, package) + if not '__path__' in parent: + raise ImportError('No package named {}'.format(package)) + return _readmodule(submodule, parent['__path__'], package) + + # Search the path for the module. + f = None + if inpackage is not None: + search_path = path + else: + search_path = path + sys.path + spec = importlib.util._find_spec_from_path(fullmodule, search_path) + _modules[fullmodule] = tree + # Is module a package? + if spec.submodule_search_locations is not None: + tree['__path__'] = spec.submodule_search_locations + try: + source = spec.loader.get_source(fullmodule) + if source is None: + return tree + except (AttributeError, ImportError): + # If module is not Python source, we cannot do anything. + return tree + + fname = spec.loader.get_filename(fullmodule) + return _create_tree(fullmodule, path, fname, source, tree, inpackage) + + +def _create_tree(fullmodule, path, fname, source, tree, inpackage): + """Return the tree for a particular module. + + fullmodule (full module name), inpackage+module, becomes o.module. + path is passed to recursive calls of _readmodule. + fname becomes o.file. + source is tokenized. Imports cause recursive calls to _readmodule. + tree is {} or {'__path__': }. + inpackage, None or string, is passed to recursive calls of _readmodule. + + The effect of recursive calls is mutation of global _modules. + """ + f = io.StringIO(source) + + stack = [] # Initialize stack of (class, indent) pairs. + + g = tokenize.generate_tokens(f.readline) + try: + for tokentype, token, start, _end, _line in g: + if tokentype == DEDENT: + lineno, thisindent = start + # Close previous nested classes and defs. + while stack and stack[-1][1] >= thisindent: + del stack[-1] + elif token == 'def': + lineno, thisindent = start + # Close previous nested classes and defs. + while stack and stack[-1][1] >= thisindent: + del stack[-1] + tokentype, func_name, start = next(g)[0:3] + if tokentype != NAME: + continue # Skip def with syntax error. + cur_func = None + if stack: + cur_obj = stack[-1][0] + cur_func = _nest_function(cur_obj, func_name, lineno) + else: + # It is just a function. + cur_func = Function(fullmodule, func_name, fname, lineno) + tree[func_name] = cur_func + stack.append((cur_func, thisindent)) + elif token == 'class': + lineno, thisindent = start + # Close previous nested classes and defs. + while stack and stack[-1][1] >= thisindent: + del stack[-1] + tokentype, class_name, start = next(g)[0:3] + if tokentype != NAME: + continue # Skip class with syntax error. + # Parse what follows the class name. + tokentype, token, start = next(g)[0:3] + inherit = None + if token == '(': + names = [] # Initialize list of superclasses. + level = 1 + super = [] # Tokens making up current superclass. + while True: + tokentype, token, start = next(g)[0:3] + if token in (')', ',') and level == 1: + n = "".join(super) + if n in tree: + # We know this super class. + n = tree[n] + else: + c = n.split('.') + if len(c) > 1: + # Super class form is module.class: + # look in module for class. + m = c[-2] + c = c[-1] + if m in _modules: + d = _modules[m] + if c in d: + n = d[c] + names.append(n) + super = [] + if token == '(': + level += 1 + elif token == ')': + level -= 1 + if level == 0: + break + elif token == ',' and level == 1: + pass + # Only use NAME and OP (== dot) tokens for type name. + elif tokentype in (NAME, OP) and level == 1: + super.append(token) + # Expressions in the base list are not supported. + inherit = names + if stack: + cur_obj = stack[-1][0] + cur_class = _nest_class( + cur_obj, class_name, lineno, inherit) + else: + cur_class = Class(fullmodule, class_name, inherit, + fname, lineno) + tree[class_name] = cur_class + stack.append((cur_class, thisindent)) + elif token == 'import' and start[1] == 0: + modules = _getnamelist(g) + for mod, _mod2 in modules: + try: + # Recursively read the imported module. + if inpackage is None: + _readmodule(mod, path) + else: + try: + _readmodule(mod, path, inpackage) + except ImportError: + _readmodule(mod, []) + except: + # If we can't find or parse the imported module, + # too bad -- don't die here. + pass + elif token == 'from' and start[1] == 0: + mod, token = _getname(g) + if not mod or token != "import": + continue + names = _getnamelist(g) + try: + # Recursively read the imported module. + d = _readmodule(mod, path, inpackage) + except: + # If we can't find or parse the imported module, + # too bad -- don't die here. + continue + # Add any classes that were defined in the imported module + # to our name space if they were mentioned in the list. + for n, n2 in names: + if n in d: + tree[n2 or n] = d[n] + elif n == '*': + # Don't add names that start with _. + for n in d: + if n[0] != '_': + tree[n] = d[n] + except StopIteration: + pass + + f.close() + return tree + + +def _getnamelist(g): + """Return list of (dotted-name, as-name or None) tuples for token source g. + + An as-name is the name that follows 'as' in an as clause. + """ + names = [] + while True: + name, token = _getname(g) + if not name: + break + if token == 'as': + name2, token = _getname(g) + else: + name2 = None + names.append((name, name2)) + while token != "," and "\n" not in token: + token = next(g)[1] + if token != ",": + break + return names + + +def _getname(g): + "Return (dotted-name or None, next-token) tuple for token source g." + parts = [] + tokentype, token = next(g)[0:2] + if tokentype != NAME and token != '*': + return (None, token) + parts.append(token) + while True: + tokentype, token = next(g)[0:2] + if token != '.': + break + tokentype, token = next(g)[0:2] + if tokentype != NAME: + break + parts.append(token) + return (".".join(parts), token) + + +def _main(): + "Print module output (default this file) for quick visual check." + import os + try: + mod = sys.argv[1] + except: + mod = __file__ + if os.path.exists(mod): + path = [os.path.dirname(mod)] + mod = os.path.basename(mod) + if mod.lower().endswith(".py"): + mod = mod[:-3] + else: + path = [] + tree = readmodule_ex(mod, path) + lineno_key = lambda a: getattr(a, 'lineno', 0) + objs = sorted(tree.values(), key=lineno_key, reverse=True) + indent_level = 2 + while objs: + obj = objs.pop() + if isinstance(obj, list): + # Value is a __path__ key. + continue + if not hasattr(obj, 'indent'): + obj.indent = 0 + + if isinstance(obj, _Object): + new_objs = sorted(obj.children.values(), + key=lineno_key, reverse=True) + for ob in new_objs: + ob.indent = obj.indent + indent_level + objs.extend(new_objs) + if isinstance(obj, Class): + print("{}class {} {} {}" + .format(' ' * obj.indent, obj.name, obj.super, obj.lineno)) + elif isinstance(obj, Function): + print("{}def {} {}".format(' ' * obj.indent, obj.name, obj.lineno)) + +if __name__ == "__main__": + _main() diff --git a/lib-python/3/macurl2path.py b/lib-python/3/macurl2path.py new file mode 100644 --- /dev/null +++ b/lib-python/3/macurl2path.py @@ -0,0 +1,77 @@ +"""Macintosh-specific module for conversion between pathnames and URLs. + +Do not import directly; use urllib instead.""" + +import urllib.parse +import os + +__all__ = ["url2pathname","pathname2url"] + +def url2pathname(pathname): + """OS-specific conversion from a relative URL of the 'file' scheme + to a file system path; not recommended for general use.""" + # + # XXXX The .. handling should be fixed... + # + tp = urllib.parse.splittype(pathname)[0] + if tp and tp != 'file': + raise RuntimeError('Cannot convert non-local URL to pathname') + # Turn starting /// into /, an empty hostname means current host + if pathname[:3] == '///': + pathname = pathname[2:] + elif pathname[:2] == '//': + raise RuntimeError('Cannot convert non-local URL to pathname') + components = pathname.split('/') + # Remove . and embedded .. + i = 0 + while i < len(components): + if components[i] == '.': + del components[i] + elif components[i] == '..' and i > 0 and \ + components[i-1] not in ('', '..'): + del components[i-1:i+1] + i = i-1 + elif components[i] == '' and i > 0 and components[i-1] != '': + del components[i] + else: + i = i+1 + if not components[0]: + # Absolute unix path, don't start with colon + rv = ':'.join(components[1:]) + else: + # relative unix path, start with colon. First replace + # leading .. by empty strings (giving ::file) + i = 0 + while i < len(components) and components[i] == '..': + components[i] = '' + i = i + 1 + rv = ':' + ':'.join(components) + # and finally unquote slashes and other funny characters + return urllib.parse.unquote(rv) + +def pathname2url(pathname): + """OS-specific conversion from a file system path to a relative URL + of the 'file' scheme; not recommended for general use.""" + if '/' in pathname: + raise RuntimeError("Cannot convert pathname containing slashes") + components = pathname.split(':') + # Remove empty first and/or last component + if components[0] == '': + del components[0] + if components[-1] == '': + del components[-1] + # Replace empty string ('::') by .. (will result in '/../' later) + for i in range(len(components)): + if components[i] == '': + components[i] = '..' + # Truncate names longer than 31 bytes + components = map(_pncomp2url, components) + + if os.path.isabs(pathname): + return '/' + '/'.join(components) + else: + return '/'.join(components) + +def _pncomp2url(component): + # We want to quote slashes + return urllib.parse.quote(component[:31], safe='') diff --git a/lib-python/3/test/bisect.py b/lib-python/3/test/bisect.py new file mode 100755 --- /dev/null +++ b/lib-python/3/test/bisect.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +""" +Command line tool to bisect failing CPython tests. + +Find the test_os test method which alters the environment: + + ./python -m test.bisect --fail-env-changed test_os + +Find a reference leak in "test_os", write the list of failing tests into the +"bisect" file: + + ./python -m test.bisect -o bisect -R 3:3 test_os + +Load an existing list of tests from a file using -i option: + + ./python -m test --list-cases -m FileTests test_os > tests + ./python -m test.bisect -i tests test_os +""" + +import argparse +import datetime +import os.path +import math +import random +import subprocess +import sys +import tempfile +import time + + +def write_tests(filename, tests): + with open(filename, "w") as fp: + for name in tests: + print(name, file=fp) + fp.flush() + + +def write_output(filename, tests): + if not filename: + return + print("Writing %s tests into %s" % (len(tests), filename)) + write_tests(filename, tests) + return filename + + +def format_shell_args(args): + return ' '.join(args) + + +def list_cases(args): + cmd = [sys.executable, '-m', 'test', '--list-cases'] + cmd.extend(args.test_args) + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + universal_newlines=True) + exitcode = proc.returncode + if exitcode: + cmd = format_shell_args(cmd) + print("Failed to list tests: %s failed with exit code %s" + % (cmd, exitcode)) + sys.exit(exitcode) + tests = proc.stdout.splitlines() + return tests + + +def run_tests(args, tests, huntrleaks=None): + tmp = tempfile.mktemp() + try: + write_tests(tmp, tests) + + cmd = [sys.executable, '-m', 'test', '--matchfile', tmp] + cmd.extend(args.test_args) + print("+ %s" % format_shell_args(cmd)) + proc = subprocess.run(cmd) + return proc.returncode + finally: + if os.path.exists(tmp): + os.unlink(tmp) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-i', '--input', + help='Test names produced by --list-tests written ' + 'into a file. If not set, run --list-tests') + parser.add_argument('-o', '--output', + help='Result of the bisection') + parser.add_argument('-n', '--max-tests', type=int, default=1, + help='Maximum number of tests to stop the bisection ' + '(default: 1)') + parser.add_argument('-N', '--max-iter', type=int, default=100, + help='Maximum number of bisection iterations ' + '(default: 100)') + # FIXME: document that following arguments are test arguments + + args, test_args = parser.parse_known_args() + args.test_args = test_args + return args + + +def main(): + args = parse_args() + + if args.input: + with open(args.input) as fp: + tests = [line.strip() for line in fp] + else: + tests = list_cases(args) + + print("Start bisection with %s tests" % len(tests)) + print("Test arguments: %s" % format_shell_args(args.test_args)) + print("Bisection will stop when getting %s or less tests " + "(-n/--max-tests option), or after %s iterations " + "(-N/--max-iter option)" + % (args.max_tests, args.max_iter)) + output = write_output(args.output, tests) + print() + + start_time = time.monotonic() + iteration = 1 + try: + while len(tests) > args.max_tests and iteration <= args.max_iter: + ntest = len(tests) + ntest = max(ntest // 2, 1) + subtests = random.sample(tests, ntest) + + print("[+] Iteration %s: run %s tests/%s" + % (iteration, len(subtests), len(tests))) + print() + + exitcode = run_tests(args, subtests) + + print("ran %s tests/%s" % (ntest, len(tests))) + print("exit", exitcode) + if exitcode: + print("Tests failed: continuing with this subtest") + tests = subtests + output = write_output(args.output, tests) + else: + print("Tests succeeded: skipping this subtest, trying a new subset") + print() + iteration += 1 + except KeyboardInterrupt: + print() + print("Bisection interrupted!") + print() + + print("Tests (%s):" % len(tests)) + for test in tests: + print("* %s" % test) + print() + + if output: + print("Output written into %s" % output) + + dt = math.ceil(time.monotonic() - start_time) + if len(tests) <= args.max_tests: + print("Bisection completed in %s iterations and %s" + % (iteration, datetime.timedelta(seconds=dt))) + sys.exit(1) + else: + print("Bisection failed after %s iterations and %s" + % (iteration, datetime.timedelta(seconds=dt))) + + +if __name__ == "__main__": + main() diff --git a/lib-python/3/test/pystone.py b/lib-python/3/test/pystone.py new file mode 100755 --- /dev/null +++ b/lib-python/3/test/pystone.py @@ -0,0 +1,277 @@ +#! /usr/bin/env python3 + +""" +"PYSTONE" Benchmark Program + +Version: Python/1.2 (corresponds to C/1.1 plus 3 Pystone fixes) + +Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013. + + Translated from ADA to C by Rick Richardson. + Every method to preserve ADA-likeness has been used, + at the expense of C-ness. + + Translated from C to Python by Guido van Rossum. + +Version History: + + Version 1.1 corrects two bugs in version 1.0: + + First, it leaked memory: in Proc1(), NextRecord ends + up having a pointer to itself. I have corrected this + by zapping NextRecord.PtrComp at the end of Proc1(). + + Second, Proc3() used the operator != to compare a + record to None. This is rather inefficient and not + true to the intention of the original benchmark (where + a pointer comparison to None is intended; the != + operator attempts to find a method __cmp__ to do value + comparison of the record). Version 1.1 runs 5-10 + percent faster than version 1.0, so benchmark figures + of different versions can't be compared directly. + + Version 1.2 changes the division to floor division. + + Under Python 3 version 1.1 would use the normal division + operator, resulting in some of the operations mistakenly + yielding floats. Version 1.2 instead uses floor division + making the benchmark an integer benchmark again. + +""" + +LOOPS = 50000 + +from time import time + +__version__ = "1.2" + +[Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6) + +class Record: + + def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0, + IntComp = 0, StringComp = 0): + self.PtrComp = PtrComp + self.Discr = Discr + self.EnumComp = EnumComp + self.IntComp = IntComp + self.StringComp = StringComp + + def copy(self): + return Record(self.PtrComp, self.Discr, self.EnumComp, + self.IntComp, self.StringComp) + +TRUE = 1 +FALSE = 0 + +def main(loops=LOOPS): + benchtime, stones = pystones(loops) + print("Pystone(%s) time for %d passes = %g" % \ + (__version__, loops, benchtime)) + print("This machine benchmarks at %g pystones/second" % stones) + + +def pystones(loops=LOOPS): + return Proc0(loops) + +IntGlob = 0 +BoolGlob = FALSE +Char1Glob = '\0' +Char2Glob = '\0' +Array1Glob = [0]*51 +Array2Glob = [x[:] for x in [Array1Glob]*51] +PtrGlb = None +PtrGlbNext = None + +def Proc0(loops=LOOPS): + global IntGlob + global BoolGlob + global Char1Glob + global Char2Glob + global Array1Glob + global Array2Glob + global PtrGlb + global PtrGlbNext + + starttime = time() + for i in range(loops): + pass + nulltime = time() - starttime + + PtrGlbNext = Record() + PtrGlb = Record() + PtrGlb.PtrComp = PtrGlbNext + PtrGlb.Discr = Ident1 + PtrGlb.EnumComp = Ident3 + PtrGlb.IntComp = 40 + PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING" + String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING" + Array2Glob[8][7] = 10 + + starttime = time() + + for i in range(loops): + Proc5() + Proc4() + IntLoc1 = 2 + IntLoc2 = 3 + String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING" + EnumLoc = Ident2 + BoolGlob = not Func2(String1Loc, String2Loc) + while IntLoc1 < IntLoc2: + IntLoc3 = 5 * IntLoc1 - IntLoc2 + IntLoc3 = Proc7(IntLoc1, IntLoc2) + IntLoc1 = IntLoc1 + 1 + Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3) + PtrGlb = Proc1(PtrGlb) + CharIndex = 'A' + while CharIndex <= Char2Glob: + if EnumLoc == Func1(CharIndex, 'C'): + EnumLoc = Proc6(Ident1) + CharIndex = chr(ord(CharIndex)+1) + IntLoc3 = IntLoc2 * IntLoc1 + IntLoc2 = IntLoc3 // IntLoc1 + IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1 + IntLoc1 = Proc2(IntLoc1) + + benchtime = time() - starttime - nulltime + if benchtime == 0.0: + loopsPerBenchtime = 0.0 + else: + loopsPerBenchtime = (loops / benchtime) + return benchtime, loopsPerBenchtime + +def Proc1(PtrParIn): + PtrParIn.PtrComp = NextRecord = PtrGlb.copy() + PtrParIn.IntComp = 5 + NextRecord.IntComp = PtrParIn.IntComp + NextRecord.PtrComp = PtrParIn.PtrComp + NextRecord.PtrComp = Proc3(NextRecord.PtrComp) + if NextRecord.Discr == Ident1: + NextRecord.IntComp = 6 + NextRecord.EnumComp = Proc6(PtrParIn.EnumComp) + NextRecord.PtrComp = PtrGlb.PtrComp + NextRecord.IntComp = Proc7(NextRecord.IntComp, 10) + else: + PtrParIn = NextRecord.copy() + NextRecord.PtrComp = None + return PtrParIn + +def Proc2(IntParIO): + IntLoc = IntParIO + 10 + while 1: + if Char1Glob == 'A': + IntLoc = IntLoc - 1 + IntParIO = IntLoc - IntGlob + EnumLoc = Ident1 + if EnumLoc == Ident1: + break + return IntParIO + +def Proc3(PtrParOut): + global IntGlob + + if PtrGlb is not None: + PtrParOut = PtrGlb.PtrComp + else: + IntGlob = 100 + PtrGlb.IntComp = Proc7(10, IntGlob) + return PtrParOut + +def Proc4(): + global Char2Glob + + BoolLoc = Char1Glob == 'A' + BoolLoc = BoolLoc or BoolGlob + Char2Glob = 'B' + +def Proc5(): + global Char1Glob + global BoolGlob + + Char1Glob = 'A' + BoolGlob = FALSE + +def Proc6(EnumParIn): + EnumParOut = EnumParIn + if not Func3(EnumParIn): + EnumParOut = Ident4 + if EnumParIn == Ident1: + EnumParOut = Ident1 + elif EnumParIn == Ident2: + if IntGlob > 100: + EnumParOut = Ident1 + else: + EnumParOut = Ident4 + elif EnumParIn == Ident3: + EnumParOut = Ident2 + elif EnumParIn == Ident4: + pass + elif EnumParIn == Ident5: + EnumParOut = Ident3 + return EnumParOut + +def Proc7(IntParI1, IntParI2): + IntLoc = IntParI1 + 2 + IntParOut = IntParI2 + IntLoc + return IntParOut + +def Proc8(Array1Par, Array2Par, IntParI1, IntParI2): + global IntGlob + + IntLoc = IntParI1 + 5 + Array1Par[IntLoc] = IntParI2 + Array1Par[IntLoc+1] = Array1Par[IntLoc] + Array1Par[IntLoc+30] = IntLoc + for IntIndex in range(IntLoc, IntLoc+2): + Array2Par[IntLoc][IntIndex] = IntLoc + Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1 + Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc] + IntGlob = 5 + +def Func1(CharPar1, CharPar2): + CharLoc1 = CharPar1 + CharLoc2 = CharLoc1 + if CharLoc2 != CharPar2: + return Ident1 + else: + return Ident2 + +def Func2(StrParI1, StrParI2): + IntLoc = 1 + while IntLoc <= 1: + if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1: + CharLoc = 'A' + IntLoc = IntLoc + 1 + if CharLoc >= 'W' and CharLoc <= 'Z': + IntLoc = 7 + if CharLoc == 'X': + return TRUE + else: + if StrParI1 > StrParI2: + IntLoc = IntLoc + 7 + return TRUE + else: + return FALSE + +def Func3(EnumParIn): + EnumLoc = EnumParIn + if EnumLoc == Ident3: return TRUE + return FALSE + +if __name__ == '__main__': + import sys + def error(msg): + print(msg, end=' ', file=sys.stderr) + print("usage: %s [number_of_loops]" % sys.argv[0], file=sys.stderr) + sys.exit(100) + nargs = len(sys.argv) - 1 + if nargs > 1: + error("%d arguments are too many;" % nargs) + elif nargs == 1: + try: loops = int(sys.argv[1]) + except ValueError: + error("Invalid argument %r;" % sys.argv[1]) + else: + loops = LOOPS + main(loops) diff --git a/lib-python/3/test/test_macurl2path.py b/lib-python/3/test/test_macurl2path.py new file mode 100644 --- /dev/null +++ b/lib-python/3/test/test_macurl2path.py @@ -0,0 +1,31 @@ +import macurl2path +import unittest + +class MacUrl2PathTestCase(unittest.TestCase): + def test_url2pathname(self): + self.assertEqual(":index.html", macurl2path.url2pathname("index.html")) + self.assertEqual(":bar:index.html", macurl2path.url2pathname("bar/index.html")) + self.assertEqual("foo:bar:index.html", macurl2path.url2pathname("/foo/bar/index.html")) + self.assertEqual("foo:bar", macurl2path.url2pathname("/foo/bar/")) + self.assertEqual("", macurl2path.url2pathname("/")) + self.assertRaises(RuntimeError, macurl2path.url2pathname, "http://foo.com") + self.assertEqual("index.html", macurl2path.url2pathname("///index.html")) + self.assertRaises(RuntimeError, macurl2path.url2pathname, "//index.html") + self.assertEqual(":index.html", macurl2path.url2pathname("./index.html")) + self.assertEqual(":index.html", macurl2path.url2pathname("foo/../index.html")) + self.assertEqual("::index.html", macurl2path.url2pathname("../index.html")) + + def test_pathname2url(self): + self.assertEqual("drive", macurl2path.pathname2url("drive:")) + self.assertEqual("drive/dir", macurl2path.pathname2url("drive:dir:")) + self.assertEqual("drive/dir/file", macurl2path.pathname2url("drive:dir:file")) + self.assertEqual("drive/file", macurl2path.pathname2url("drive:file")) + self.assertEqual("file", macurl2path.pathname2url("file")) + self.assertEqual("file", macurl2path.pathname2url(":file")) + self.assertEqual("dir", macurl2path.pathname2url(":dir:")) + self.assertEqual("dir/file", macurl2path.pathname2url(":dir:file")) + self.assertRaises(RuntimeError, macurl2path.pathname2url, "/") + self.assertEqual("dir/../file", macurl2path.pathname2url("dir::file")) + +if __name__ == "__main__": + unittest.main() diff --git a/pypy/interpreter/test/test_nestedscope.py b/pypy/interpreter/test/apptest_nestedscope.py rename from pypy/interpreter/test/test_nestedscope.py rename to pypy/interpreter/test/apptest_nestedscope.py --- a/pypy/interpreter/test/test_nestedscope.py +++ b/pypy/interpreter/test/apptest_nestedscope.py @@ -1,171 +1,169 @@ +from pytest import raises +def test_nested_scope(): + x = 42 + def f(): return x + assert f() == 42 -class AppTestNestedScope: +def test_nested_scope2(): + x = 42 + y = 3 + def f(): return x + assert f() == 42 - def test_nested_scope(self): - x = 42 - def f(): return x - assert f() == 42 +def test_nested_scope3(): + x = 42 + def f(): + def g(): + return x + return g + assert f()() == 42 - def test_nested_scope2(self): - x = 42 - y = 3 - def f(): return x - assert f() == 42 +def test_nested_scope4(): + def f(): + x = 3 + def g(): + return x + a = g() + x = 4 + b = g() + return (a, b) + assert f() == (3, 4) - def test_nested_scope3(self): - x = 42 - def f(): - def g(): - return x - return g - assert f()() == 42 +def test_nested_scope_locals(): + def f(): + x = 3 + def g(): + i = x + return locals() + return g() + d = f() + assert d == {'i':3, 'x':3} - def test_nested_scope4(self): - def f(): - x = 3 - def g(): - return x - a = g() - x = 4 - b = g() - return (a, b) - assert f() == (3, 4) - - def test_nested_scope_locals(self): - def f(): - x = 3 - def g(): +def test_deeply_nested_scope_locals(): + def f(): + x = 3 + def g(): + def h(): i = x return locals() - return g() - d = f() - assert d == {'i':3, 'x':3} + return locals(), h() + return g() + outer_locals, inner_locals = f() + assert inner_locals == {'i':3, 'x':3} + keys = sorted(outer_locals.keys()) + assert keys == ['h', 'x'] - def test_deeply_nested_scope_locals(self): - def f(): - x = 3 - def g(): - def h(): - i = x - return locals() - return locals(), h() - return g() - outer_locals, inner_locals = f() - assert inner_locals == {'i':3, 'x':3} - keys = sorted(outer_locals.keys()) - assert keys == ['h', 'x'] +def test_lambda_in_genexpr(): + assert [x() for x in (lambda: x for x in range(10))] == list(range(10)) - def test_lambda_in_genexpr(self): - assert [x() for x in (lambda: x for x in range(10))] == list(range(10)) +def test_cell_repr(): + import re + from reprlib import repr as r # Don't shadow builtin repr - def test_cell_repr(self): - import re - from reprlib import repr as r # Don't shadow builtin repr + def get_cell(): + x = 42 + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'', repr(x)) + assert re.match(r'', r(x)) - def get_cell(): + def get_cell(): + if False: x = 42 - def inner(): + def inner(): + return x + return inner + x = get_cell().__closure__[0] + assert re.match(r'', repr(x)) + +def test_cell_contents(): + def f(x): + def f(y): + return x + y + return f + + g = f(10) + assert g.__closure__[0].cell_contents == 10 + +def test_empty_cell_contents(): + + def f(): + def f(y): + return x + y + return f + x = 1 + + g = f() + with raises(ValueError): + g.__closure__[0].cell_contents + +def test_compare_cells(): + def f(n): + if n: + x = n + def f(y): + return x + y + return f + + empty_cell_1 = f(0).__closure__[0] + empty_cell_2 = f(0).__closure__[0] + g1 = f(1).__closure__[0] + g2 = f(2).__closure__[0] + assert g1 < g2 + assert g1 <= g2 + assert g2 > g1 + assert g2 >= g1 + assert not g1 == g2 + assert g1 != g2 + # + assert empty_cell_1 == empty_cell_2 + assert not empty_cell_1 != empty_cell_2 + assert empty_cell_1 < g1 + +def test_leaking_class_locals(): + def f(x): + class X: + x = 12 + def f(self): return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'', repr(x)) - assert re.match(r'', r(x)) + locals() + return X + assert f(1).x == 12 - def get_cell(): - if False: - x = 42 - def inner(): - return x - return inner - x = get_cell().__closure__[0] - assert re.match(r'', repr(x)) +def test_nested_scope_locals_mutating_cellvars(): + def f(): + x = 12 + def m(): + locals() + x + locals() + return x + return m + assert f()() == 12 - def test_cell_contents(self): - def f(x): - def f(y): - return x + y - return f - g = f(10) - assert g.__closure__[0].cell_contents == 10 +def test_unbound_local_after_del(): + """ + # #4617: It is now legal to delete a cell variable. + # The following functions must obviously compile, + # and give the correct error when accessing the deleted name. + def errorInOuter(): + y = 1 + del y + print(y) + def inner(): + return y - def test_empty_cell_contents(self): + def errorInInner(): + def inner(): + return y + y = 1 + del y + inner() - def f(): - def f(y): - return x + y - return f - x = 1 - - g = f() - with raises(ValueError): - g.__closure__[0].cell_contents - - def test_compare_cells(self): - def f(n): - if n: - x = n - def f(y): - return x + y - return f - - empty_cell_1 = f(0).__closure__[0] - empty_cell_2 = f(0).__closure__[0] - g1 = f(1).__closure__[0] - g2 = f(2).__closure__[0] - assert g1 < g2 - assert g1 <= g2 - assert g2 > g1 - assert g2 >= g1 - assert not g1 == g2 - assert g1 != g2 - # - assert empty_cell_1 == empty_cell_2 - assert not empty_cell_1 != empty_cell_2 - assert empty_cell_1 < g1 - - def test_leaking_class_locals(self): - def f(x): - class X: - x = 12 - def f(self): - return x - locals() - return X - assert f(1).x == 12 - - def test_nested_scope_locals_mutating_cellvars(self): - def f(): - x = 12 - def m(): - locals() - x - locals() - return x - return m - assert f()() == 12 - - - def test_unbound_local_after_del(self): - """ - # #4617: It is now legal to delete a cell variable. - # The following functions must obviously compile, - # and give the correct error when accessing the deleted name. - def errorInOuter(): - y = 1 - del y - print(y) - def inner(): - return y - - def errorInInner(): - def inner(): - return y - y = 1 - del y - inner() - - raises(UnboundLocalError, "errorInOuter()") - raises(NameError, "errorInInner()") - """ + raises(UnboundLocalError, "errorInOuter()") + raises(NameError, "errorInInner()") + """ From pypy.commits at gmail.com Wed Jan 8 07:48:18 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 04:48:18 -0800 (PST) Subject: [pypy-commit] pypy py3.7: make cell contents writable Message-ID: <5e15cf92.1c69fb81.53b4a.02fb@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98490:1787f589a543 Date: 2020-01-08 13:23 +0100 http://bitbucket.org/pypy/pypy/changeset/1787f589a543/ Log: make cell contents writable diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py --- a/pypy/interpreter/nestedscope.py +++ b/pypy/interpreter/nestedscope.py @@ -85,3 +85,6 @@ return self.get() except ValueError: raise oefmt(space.w_ValueError, "Cell is empty") + + def descr_set_cell_contents(self, space, w_value): + return self.set(w_value) diff --git a/pypy/interpreter/test/apptest_nestedscope.py b/pypy/interpreter/test/apptest_nestedscope.py --- a/pypy/interpreter/test/apptest_nestedscope.py +++ b/pypy/interpreter/test/apptest_nestedscope.py @@ -88,6 +88,19 @@ g = f(10) assert g.__closure__[0].cell_contents == 10 +def test_set_cell_contents(): + def f(x): + def g(y): + return x + y + return g + + g10 = f(10) + assert g10(5) == 15 + assert g10.__closure__[0].cell_contents == 10 + g10.__closure__[0].cell_contents = 20 + assert g10.__closure__[0].cell_contents == 20 + assert g10(5) == 25 + def test_empty_cell_contents(): def f(): diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -943,7 +943,7 @@ __reduce__ = interp2app(Cell.descr__reduce__), __repr__ = interp2app(Cell.descr__repr__), __setstate__ = interp2app(Cell.descr__setstate__), - cell_contents= GetSetProperty(Cell.descr__cell_contents, cls=Cell), + cell_contents= GetSetProperty(Cell.descr__cell_contents, Cell.descr_set_cell_contents, cls=Cell), ) assert not Cell.typedef.acceptable_as_base_class # no __new__ From pypy.commits at gmail.com Wed Jan 8 07:48:20 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 04:48:20 -0800 (PST) Subject: [pypy-commit] pypy default: run functions in apptest_* files in definition order Message-ID: <5e15cf94.1c69fb81.b5f90.3064@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98491:d7bd679b8a6e Date: 2020-01-08 13:24 +0100 http://bitbucket.org/pypy/pypy/changeset/d7bd679b8a6e/ Log: run functions in apptest_* files in definition order diff --git a/pypy/tool/pytest/apptest2.py b/pypy/tool/pytest/apptest2.py --- a/pypy/tool/pytest/apptest2.py +++ b/pypy/tool/pytest/apptest2.py @@ -46,6 +46,7 @@ if not isinstance(w_obj, pypy.interpreter.function.Function): continue items.append(AppTestFunction(name, self, w_obj)) + items.sort(key=lambda item: item.reportinfo()[:2]) return items def setup(self): From pypy.commits at gmail.com Wed Jan 8 08:06:27 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 05:06:27 -0800 (PST) Subject: [pypy-commit] pypy default: test for the problem in e300fd927c59 Message-ID: <5e15d3d3.1c69fb81.d872c.188f@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98492:4c97894c1026 Date: 2020-01-08 14:01 +0100 http://bitbucket.org/pypy/pypy/changeset/4c97894c1026/ Log: test for the problem in e300fd927c59 diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -645,6 +645,16 @@ assert a == [] assert b == [(True, 9)] + def test_groupby_crash(self): + # see http://bugs.python.org/issue30347 + from itertools import groupby + def f(n): + if n == 5: + list(b) + return n != 6 + for (k, b) in groupby(range(10), f): + list(b) # shouldn't crash + def test_iterables(self): import itertools From pypy.commits at gmail.com Wed Jan 8 08:06:29 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 05:06:29 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5e15d3d5.1c69fb81.73bba.0618@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98493:66a00f2388c3 Date: 2020-01-08 14:05 +0100 http://bitbucket.org/pypy/pypy/changeset/66a00f2388c3/ Log: merge default diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -541,6 +541,16 @@ assert a == [] assert b == [(True, 9)] + def test_groupby_crash(self): + # see http://bugs.python.org/issue30347 + from itertools import groupby + def f(n): + if n == 5: + list(b) + return n != 6 + for (k, b) in groupby(range(10), f): + list(b) # shouldn't crash + def test_iterables(self): import itertools diff --git a/pypy/tool/pytest/apptest2.py b/pypy/tool/pytest/apptest2.py --- a/pypy/tool/pytest/apptest2.py +++ b/pypy/tool/pytest/apptest2.py @@ -46,6 +46,7 @@ if not isinstance(w_obj, pypy.interpreter.function.Function): continue items.append(AppTestFunction(name, self, w_obj)) + items.sort(key=lambda item: item.reportinfo()[:2]) return items def setup(self): From pypy.commits at gmail.com Wed Jan 8 08:06:31 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 05:06:31 -0800 (PST) Subject: [pypy-commit] pypy py3.6: re-do e300fd927c59 which got lost in a merge somewhere Message-ID: <5e15d3d7.1c69fb81.dec0c.30ae@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98494:8ab16affda0a Date: 2020-01-08 14:05 +0100 http://bitbucket.org/pypy/pypy/changeset/8ab16affda0a/ Log: re-do e300fd927c59 which got lost in a merge somewhere diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -1068,7 +1068,8 @@ w_newkey = w_newvalue else: w_newkey = space.call_function(groupby.w_keyfunc, w_newvalue) - assert groupby.w_currvalue is None + #assert groupby.w_currvalue is None + # ^^^ check disabled, see http://bugs.python.org/issue30347 groupby.w_currkey = w_newkey groupby.w_currvalue = w_newvalue From pypy.commits at gmail.com Wed Jan 8 08:06:33 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 08 Jan 2020 05:06:33 -0800 (PST) Subject: [pypy-commit] pypy py3.7: merge py3.6 Message-ID: <5e15d3d9.1c69fb81.84682.0da7@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98495:9d31a887ead7 Date: 2020-01-08 14:05 +0100 http://bitbucket.org/pypy/pypy/changeset/9d31a887ead7/ Log: merge py3.6 diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -1071,7 +1071,8 @@ w_newkey = w_newvalue else: w_newkey = space.call_function(groupby.w_keyfunc, w_newvalue) - assert groupby.w_currvalue is None + #assert groupby.w_currvalue is None + # ^^^ check disabled, see http://bugs.python.org/issue30347 groupby.w_currkey = w_newkey groupby.w_currvalue = w_newvalue diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -553,6 +553,16 @@ assert a == [] assert b == [(True, 9)] + def test_groupby_crash(self): + # see http://bugs.python.org/issue30347 + from itertools import groupby + def f(n): + if n == 5: + list(b) + return n != 6 + for (k, b) in groupby(range(10), f): + list(b) # shouldn't crash + def test_iterables(self): import itertools diff --git a/pypy/tool/pytest/apptest2.py b/pypy/tool/pytest/apptest2.py --- a/pypy/tool/pytest/apptest2.py +++ b/pypy/tool/pytest/apptest2.py @@ -46,6 +46,7 @@ if not isinstance(w_obj, pypy.interpreter.function.Function): continue items.append(AppTestFunction(name, self, w_obj)) + items.sort(key=lambda item: item.reportinfo()[:2]) return items def setup(self): From pypy.commits at gmail.com Wed Jan 8 19:51:31 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 08 Jan 2020 16:51:31 -0800 (PST) Subject: [pypy-commit] pypy.org nikola: adjust theme, css for header, footer alignment Message-ID: <5e167913.1c69fb81.655cc.dd76@mx.google.com> Author: Matti Picus Branch: nikola Changeset: r972:2a10a45f9acf Date: 2020-01-09 08:51 +0800 http://bitbucket.org/pypy/pypy.org/changeset/2a10a45f9acf/ Log: adjust theme, css for header, footer alignment diff --git a/conf.py b/conf.py --- a/conf.py +++ b/conf.py @@ -137,9 +137,11 @@ # with a ``/``, otherwise end them with ``/index.html`` — or # else they won’t be highlighted when active. +# PyPy templates out the logo into a div, so it is not here + NAVIGATION_LINKS = { DEFAULT_LANG: ( - ('/index.html', 'PyPy'), + ( ( ('/features.html', 'What is PyPy?'), @@ -955,9 +957,15 @@ # A small copyright notice for the page footer (in HTML). # (translatable) CONTENT_FOOTER = """ -PyPy Logo Contents © -{date} {author} Powered by Nikola {license} +
    +
    + PyPy Logo +
    +
    +  Contents © {date} {author} + Powered by Nikola {license} +
    +
    """ # Things that will be passed to CONTENT_FOOTER.format(). This is done diff --git a/public/archive.html b/public/archive.html --- a/public/archive.html +++ b/public/archive.html @@ -26,10 +26,13 @@ -
    +
    - PyPy - +
    +
  • Enter the goal directory:

    -
    cd pypy/pypy/goal
    +
    cd pypy/pypy/goal
     
  • Run the rpython script. Here are the common combinations of options (works also with python instead of pypy; requires CPython 2.7 or PyPy 2, even to build PyPy 3):

    -
    # get the JIT version
    -pypy ../../rpython/bin/rpython -Ojit targetpypystandalone
    -# get the no-jit version
    -pypy ../../rpython/bin/rpython -O2 targetpypystandalone
    -# get the sandbox version
    -pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone
    +
    # get the JIT version
    +pypy ../../rpython/bin/rpython -Ojit targetpypystandalone
    +# get the no-jit version
    +pypy ../../rpython/bin/rpython -O2 targetpypystandalone
    +# get the sandbox version
    +pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone
     
  • Enjoy Mandelbrot :-) It takes on the order of half an hour to @@ -320,9 +323,9 @@ call it with ...pypy-c ../../rpython/bin/rpython -Ojit.

    2. if even using PyPy instead of CPython is not enough, try to tweak some internal parameters. Example (slower but saves around 400MB):

    -
    PYPY_DONT_RUN_SUBPROCESS=1 PYPY_GC_MAX_DELTA=200MB \
    -pypy --jit loop_longevity=300 ../../rpython/bin/rpython -Ojit --source
    -# then read the next point about --source
    +
    PYPY_DONT_RUN_SUBPROCESS=1 PYPY_GC_MAX_DELTA=200MB \
    +pypy --jit loop_longevity=300 ../../rpython/bin/rpython -Ojit --source
    +# then read the next point about --source
     
  • You can run translations with --source, which only builds the C @@ -343,9 +346,9 @@

    Once PyPy is translated from source the binary package similar to those provided in the section Default (with a JIT Compiler) above could be easily created with package.py script:

    -
    cd ./pypy/pypy/tool/release/
    -python package.py --help #for information
    -python package.py --archive-name pypy-my-own-package-name
    +
    cd ./pypy/pypy/tool/release/
    +python package.py --help #for information
    +python package.py --archive-name pypy-my-own-package-name
     

    It is recommended to use package.py because custom scripts will invariably become out-of-date. If you want to write custom scripts @@ -454,9 +457,17 @@

    diff --git a/public/features.html b/public/features.html --- a/public/features.html +++ b/public/features.html @@ -33,10 +33,13 @@ -
    +
    - PyPy - +
    + diff --git a/public/index.html b/public/index.html --- a/public/index.html +++ b/public/index.html @@ -20,12 +20,15 @@ - + +On average, PyPy is 4.4 times faster than CPython + + +PyP"> @@ -37,10 +40,13 @@ -
    +
    - PyPy - +
    +
  • +
  • + The benchmark results page contains json + files from the benchmark runs, used for + speed.pypy.org +
  • The Waterfall Display will give you a From pypy.commits at gmail.com Mon Jan 27 16:33:38 2020 From: pypy.commits at gmail.com (mattip) Date: Mon, 27 Jan 2020 13:33:38 -0800 (PST) Subject: [pypy-commit] buildbot default: branch was None by default Message-ID: <5e2f5732.1c69fb81.98d92.09e3@mx.google.com> Author: Matti Picus Branch: Changeset: r1129:9984670940a2 Date: 2020-01-27 23:33 +0200 http://bitbucket.org/pypy/buildbot/changeset/9984670940a2/ Log: branch was None by default diff --git a/bot2/pypybuildbot/builds.py b/bot2/pypybuildbot/builds.py --- a/bot2/pypybuildbot/builds.py +++ b/bot2/pypybuildbot/builds.py @@ -933,6 +933,8 @@ exe = os.path.split(target)[-1][:-2] rev = props.getProperty('got_revision') branch = props.getProperty('branch') + if branch == 'None' or branch is None: + branch = 'default' command=["python", "runner.py", '--output-filename', 'result.json', '--changed', target, '--baseline', target, From pypy.commits at gmail.com Tue Jan 28 15:55:59 2020 From: pypy.commits at gmail.com (mattip) Date: Tue, 28 Jan 2020 12:55:59 -0800 (PST) Subject: [pypy-commit] pypy py3.6: issue 3160: include structseq.h (needed for PyStructSequence_InitType2 in NumPy) Message-ID: <5e309fdf.1c69fb81.5b32e.0446@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r98589:95ba888acdd6 Date: 2020-01-28 22:54 +0200 http://bitbucket.org/pypy/pypy/changeset/95ba888acdd6/ Log: issue 3160: include structseq.h (needed for PyStructSequence_InitType2 in NumPy) diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -123,6 +123,7 @@ #include "sliceobject.h" #include "genobject.h" #include "datetime.h" +#include "structseq.h" #include "pystate.h" #include "fileobject.h" #include "pysignals.h" From pypy.commits at gmail.com Wed Jan 29 12:22:17 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 29 Jan 2020 09:22:17 -0800 (PST) Subject: [pypy-commit] pypy py3.6: add missing value to config_vars, from cibuildwheel PR #185 Message-ID: <5e31bf49.1c69fb81.3e520.dcfd@mx.google.com> Author: Matti Picus Branch: py3.6 Changeset: r98590:cb567ed9c7ec Date: 2020-01-29 19:21 +0200 http://bitbucket.org/pypy/pypy/changeset/cb567ed9c7ec/ Log: add missing value to config_vars, from cibuildwheel PR #185 diff --git a/lib_pypy/_sysconfigdata.py b/lib_pypy/_sysconfigdata.py --- a/lib_pypy/_sysconfigdata.py +++ b/lib_pypy/_sysconfigdata.py @@ -47,4 +47,5 @@ build_time_vars['CC'] += ' -arch %s' % (arch,) if "CXX" in build_time_vars: build_time_vars['CXX'] += ' -arch %s' % (arch,) + build_time_vars['MACOSX_DEPLOYMENT_TARGET'] = '10.7' From pypy.commits at gmail.com Wed Jan 29 13:59:20 2020 From: pypy.commits at gmail.com (stevie_92) Date: Wed, 29 Jan 2020 10:59:20 -0800 (PST) Subject: [pypy-commit] pypy cpyext-gc-cycle: Added rrc gc tests to improve code coverage Message-ID: <5e31d608.1c69fb81.2c207.fafd@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r98591:e8295913b0ef Date: 2020-01-29 19:58 +0100 http://bitbucket.org/pypy/pypy/changeset/e8295913b0ef/ Log: Added rrc gc tests to improve code coverage diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_4.dot copy from rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot copy to rpython/memory/gc/test/dot/free_cpython_weakref_simple_4.dot --- a/rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot +++ b/rpython/memory/gc/test/dot/free_cpython_weakref_simple_4.dot @@ -1,7 +1,8 @@ digraph G { "a" [type=C, alive=n]; "b" [type=C, alive=n]; + "c" [type=C, alive=n]; "a" -> "b"; - "b" -> "a"; + "b" -> "c"; "a" -> "b" [weakref=y, callback=y, clear_callback=y]; } diff --git a/rpython/memory/gc/test/dot/free_finalizer_simple_1a.dot b/rpython/memory/gc/test/dot/free_finalizer_simple_2.dot copy from rpython/memory/gc/test/dot/free_finalizer_simple_1a.dot copy to rpython/memory/gc/test/dot/free_finalizer_simple_2.dot --- a/rpython/memory/gc/test/dot/free_finalizer_simple_1a.dot +++ b/rpython/memory/gc/test/dot/free_finalizer_simple_2.dot @@ -1,10 +1,10 @@ digraph G { - "a" [type=P, alive=n]; - "b" [type=B, alive=n]; + "a" [type=C, alive=n]; + "b" [type=C, alive=n]; "c" [type=C, alive=n, finalizer=modern]; "d" [type=C, alive=n]; - "e" [type=B, alive=n]; - "f" [type=P, alive=n]; + "e" [type=C, alive=n]; + "f" [type=C, alive=n]; "a" -> "b"; "b" -> "c"; "c" -> "d"; diff --git a/rpython/memory/gc/test/dot/keep_cpython_inc_3b.dot b/rpython/memory/gc/test/dot/keep_cpython_inc_5.dot copy from rpython/memory/gc/test/dot/keep_cpython_inc_3b.dot copy to rpython/memory/gc/test/dot/keep_cpython_inc_5.dot --- a/rpython/memory/gc/test/dot/keep_cpython_inc_3b.dot +++ b/rpython/memory/gc/test/dot/keep_cpython_inc_5.dot @@ -1,15 +1,10 @@ digraph G { "a" [type=B, alive=y, ext_refcnt=1]; - "b" [type=P, alive=n]; - "c" [type=P, alive=y]; - "d" [type=B, alive=y]; - "e" [type=C, alive=y]; - "f" [type=C, alive=y, ext_refcnt=1, added=after_snap]; - "g" [type=B, alive=y, added=linked_after_snap, gc=n]; - "a" -> "b" [removed=after_snap]; + "b" [type=P, alive=y]; + "c" [type=B, alive=y, added=linked_after_snap]; + "d" [type=C, alive=y]; + "a" -> "b"; "b" -> "c"; - "c" -> "d"; - "d" -> "e"; - "f" -> "g" [added=after_snap]; - "g" -> "c" [added=after_snap]; + "c" -> "d" [added=after_snap]; + "d" -> "a"; } diff --git a/rpython/memory/gc/test/dot/keep_cpython_inc_3b.dot b/rpython/memory/gc/test/dot/keep_cpython_inc_6.dot copy from rpython/memory/gc/test/dot/keep_cpython_inc_3b.dot copy to rpython/memory/gc/test/dot/keep_cpython_inc_6.dot --- a/rpython/memory/gc/test/dot/keep_cpython_inc_3b.dot +++ b/rpython/memory/gc/test/dot/keep_cpython_inc_6.dot @@ -1,15 +1,10 @@ digraph G { - "a" [type=B, alive=y, ext_refcnt=1]; - "b" [type=P, alive=n]; - "c" [type=P, alive=y]; - "d" [type=B, alive=y]; - "e" [type=C, alive=y]; - "f" [type=C, alive=y, ext_refcnt=1, added=after_snap]; - "g" [type=B, alive=y, added=linked_after_snap, gc=n]; - "a" -> "b" [removed=after_snap]; + "a" [type=C, alive=y, ext_refcnt=1]; + "b" [type=C, alive=y]; + "c" [type=C, alive=y, removed=after_snap]; + "d" [type=C, alive=n]; + "a" -> "b"; "b" -> "c"; - "c" -> "d"; - "d" -> "e"; - "f" -> "g" [added=after_snap]; - "g" -> "c" [added=after_snap]; + "c" -> "d" [removed=after_snap]; + "d" -> "a"; } diff --git a/rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot b/rpython/memory/gc/test/dot/keep_cpython_weakref_simple_1.dot copy from rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot copy to rpython/memory/gc/test/dot/keep_cpython_weakref_simple_1.dot --- a/rpython/memory/gc/test/dot/free_cpython_weakref_simple_1.dot +++ b/rpython/memory/gc/test/dot/keep_cpython_weakref_simple_1.dot @@ -1,7 +1,10 @@ digraph G { - "a" [type=C, alive=n]; - "b" [type=C, alive=n]; + "a" [type=C, alive=y, ext_refcnt=1]; + "b" [type=C, alive=y]; + "c" [type=C, alive=n]; + "d" [type=C, alive=n]; "a" -> "b"; - "b" -> "a"; - "a" -> "b" [weakref=y, callback=y, clear_callback=y]; + "c" -> "d"; + "d" -> "c"; + "b" -> "c" [weakref=y, callback=y, clear_callback=n]; } diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py --- a/rpython/memory/gc/test/test_rawrefcount.py +++ b/rpython/memory/gc/test/test_rawrefcount.py @@ -25,18 +25,57 @@ ('prev', lltype.Ptr(S)), ('next', lltype.Ptr(S)))) - class TestRawRefCount(BaseDirectGCTest): GCClass = IncMiniMark RRCGCClass = RawRefCountIncMarkGC #RRCGCClass = RawRefCountMarkGC + # do cleanup after collection (clear all dead pyobjects) + def finalize_modern(self, pyobj): + index = self.pyobjs.index(pyobj) + if not self.pyobj_finalizer.has_key(index) or \ + self.pyobj_finalizer[index] != \ + RAWREFCOUNT_FINALIZER_MODERN: + return + if self.pyobj_finalized.has_key(index): + return + self.pyobj_finalized[index] = True + if self.pyobj_resurrect.has_key(index): + resurrect = self.pyobj_resurrect[index] + for r in resurrect: + r.c_ob_refcnt += 1 + if self.pyobj_delete.has_key(index): + delete = self.pyobj_delete[index] + for r in delete: + self.pyobj_refs[index].remove(r) + self.decref(r, None) + + def decref_children(self, pyobj): + self.gc.rrc_gc.tp_traverse(pyobj, self.decref, None) + + def decref(self, pyobj, ignore): + pyobj.c_ob_refcnt -= 1 + if pyobj.c_ob_refcnt == 0: + self.finalize_modern(pyobj) + if pyobj.c_ob_refcnt == 0: + gchdr = self.gc.rrc_gc.pyobj_as_gc(pyobj) + if gchdr != lltype.nullptr(PYOBJ_GC_HDR) and \ + gchdr.c_gc_refs != RAWREFCOUNT_REFS_UNTRACKED: + next = gchdr.c_gc_next + next.c_gc_prev = gchdr.c_gc_prev + gchdr.c_gc_prev.c_gc_next = next + self.decref_children(pyobj) + self.pyobjs[self.pyobjs.index(pyobj)] = \ + lltype.nullptr(PYOBJ_HDR_PTR.TO) + lltype.free(pyobj, flavor='raw') + def setup_method(self, method): BaseDirectGCTest.setup_method(self, method) self.trigger = [] self.gcobjs = [] self.pyobjs = [] + self.pyobjs_removed_count = [] self.pyobj_refs = [] self.pyobj_weakrefs = [] self.pyobj_finalizer = {} @@ -123,6 +162,14 @@ refs.append(pyobj_to) pyobj_to.c_ob_refcnt += 1 + def _rawrefcount_removeref(self, pyobj_from, pyobj_to): + refs = self.pyobj_refs[self.pyobjs.index(pyobj_from)] + refs.remove(pyobj_to) + self.decref(pyobj_to, None) + + def _get_removed_count(self, pyobj): + return self.pyobjs_removed_count[self.pyobjs.index(pyobj)] + def _rawrefcount_addweakref(self, pyobj_from, weakref): refs = self.pyobj_weakrefs[self.pyobjs.index(pyobj_from)] refs.append(weakref) @@ -169,6 +216,7 @@ self.tupletypes.append(tuple_type) self.pyobjs.append(r1) + self.pyobjs_removed_count.append(0) self.is_pygc.append(is_gc) self.pyobj_refs.append([]) self.pyobj_weakrefs.append([]) @@ -220,6 +268,7 @@ self.tupletypes.append(tuple_type) self.pyobjs.append(r1) + self.pyobjs_removed_count.append(0) self.is_pygc.append(is_gc) self.pyobj_refs.append([]) self.pyobj_weakrefs.append([]) @@ -729,44 +778,12 @@ garbage_pypy = [] garbage_pyobj = [] def cleanup(): - # do cleanup after collection (clear all dead pyobjects) - def finalize_modern(pyobj): - index = self.pyobjs.index(pyobj) - if not self.pyobj_finalizer.has_key(index) or \ - self.pyobj_finalizer[index] != \ - RAWREFCOUNT_FINALIZER_MODERN: - return - if self.pyobj_finalized.has_key(index): - return - self.pyobj_finalized[index] = True - if self.pyobj_resurrect.has_key(index): - resurrect = self.pyobj_resurrect[index] - for r in resurrect: - r.c_ob_refcnt += 1 - if self.pyobj_delete.has_key(index): - delete = self.pyobj_delete[index] - for r in delete: - self.pyobj_refs[index].remove(r) - decref(r, None) - - def decref_children(pyobj): - self.gc.rrc_gc.tp_traverse(pyobj, decref, None) def decref(pyobj, ignore): - pyobj.c_ob_refcnt -= 1 - if pyobj.c_ob_refcnt == 0: - finalize_modern(pyobj) - if pyobj.c_ob_refcnt == 0: - gchdr = self.gc.rrc_gc.pyobj_as_gc(pyobj) - if gchdr != lltype.nullptr(PYOBJ_GC_HDR) and \ - gchdr.c_gc_refs != RAWREFCOUNT_REFS_UNTRACKED: - next = gchdr.c_gc_next - next.c_gc_prev = gchdr.c_gc_prev - gchdr.c_gc_prev.c_gc_next = next - decref_children(pyobj) - self.pyobjs[self.pyobjs.index(pyobj)] = \ - lltype.nullptr(PYOBJ_HDR_PTR.TO) - lltype.free(pyobj, flavor='raw') + self.decref(pyobj, ignore) + + def finalize_modern(pyobj): + self.finalize_modern(pyobj) next_dead = self.gc.rawrefcount_next_dead() while next_dead <> llmemory.NULL: @@ -901,8 +918,11 @@ remove[2].p.prev = remove[2].p else: assert False, "not yet supported" - else: - assert False, "not yet supported" + elif remove[0] == "C": + source = remove[1] + dest = remove[2] + self._rawrefcount_removeref(source.r, dest.r) + after_snap = True self.gc.rrc_gc.invoke_callback() @@ -925,7 +945,8 @@ if n.info.type == "P": n.check_alive() else: - n.check_alive(n.info.ext_refcnt) + removed_refs = self._get_removed_count(n.r) + n.check_alive(n.info.ext_refcnt - removed_refs) print "Node", name, "is alive." else: print "Node", name, "should be dead." From pypy.commits at gmail.com Wed Jan 29 15:08:49 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 29 Jan 2020 12:08:49 -0800 (PST) Subject: [pypy-commit] pypy py3.7: merge py3.6 into branch Message-ID: <5e31e651.1c69fb81.9802.0c6a@mx.google.com> Author: Matti Picus Branch: py3.7 Changeset: r98594:55e4d78197be Date: 2020-01-29 22:05 +0200 http://bitbucket.org/pypy/pypy/changeset/55e4d78197be/ Log: merge py3.6 into branch diff --git a/lib-python/3/test/test_curses.py b/lib-python/3/test/test_curses.py --- a/lib-python/3/test/test_curses.py +++ b/lib-python/3/test/test_curses.py @@ -15,7 +15,8 @@ import tempfile import unittest -from test.support import requires, import_module, verbose, SaveSignals +from test.support import (requires, import_module, verbose, SaveSignals, + cpython_only) # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u @@ -315,6 +316,7 @@ msg='userptr should fail since not set'): p.userptr() + @cpython_only @requires_curses_func('panel') def test_userptr_memory_leak(self): w = curses.newwin(10, 10) @@ -328,6 +330,7 @@ self.assertEqual(sys.getrefcount(obj), nrefs, "set_userptr leaked references") + @cpython_only @requires_curses_func('panel') def test_userptr_segfault(self): w = curses.newwin(10, 10) @@ -420,20 +423,20 @@ # we will need to rewrite this test. try: signature = inspect.signature(stdscr.addch) - self.assertFalse(signature) except ValueError: - # not generating a signature is fine. - pass - # So. No signature for addch. - # But Argument Clinic gave us a human-readable equivalent - # as the first line of the docstring. So we parse that, - # and ensure that the parameters appear in the correct order. - # Since this is parsing output from Argument Clinic, we can - # be reasonably certain the generated parsing code will be - # correct too. - human_readable_signature = stdscr.addch.__doc__.split("\n")[0] - self.assertIn("[y, x,]", human_readable_signature) + # So. No signature for addch. + # But Argument Clinic gave us a human-readable equivalent + # as the first line of the docstring. So we parse that, + # and ensure that the parameters appear in the correct order. + # Since this is parsing output from Argument Clinic, we can + # be reasonably certain the generated parsing code will be + # correct too. + human_readable_signature = stdscr.addch.__doc__.split("\n")[0] + self.assertIn("[y, x,]", human_readable_signature) + else: + params = list(signature.parameters.keys()) + self.assertTrue(params.index('y') < params.index('x')) def test_issue13051(self): stdscr = self.stdscr diff --git a/lib-python/3/venv/__init__.py b/lib-python/3/venv/__init__.py --- a/lib-python/3/venv/__init__.py +++ b/lib-python/3/venv/__init__.py @@ -187,6 +187,9 @@ logger.warning('Unable to symlink %r to %r', src, dst) force_copy = True if force_copy: + if os.path.isdir(src): + shutil.copytree(src, dst) + else: shutil.copyfile(src, dst) else: def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -4,6 +4,7 @@ if sys.platform == 'win32': #This module does not exist in windows raise ImportError('No module named _curses') +import locale from functools import wraps from _curses_cffi import ffi, lib @@ -57,7 +58,7 @@ if key_n == b"UNKNOWN KEY": continue if not isinstance(key_n, str): # python 3 - key_n = key_n.decode() + key_n = key_n.decode('utf-8') key_n = key_n.replace('(', '').replace(')', '') globals()[key_n] = key @@ -83,7 +84,9 @@ def _ensure_initialised_color(): - if not _initialised and _initialised_color: + if not _initialised: + raise error("must call initscr() first") + if not _initialised_color: raise error("must call start_color() first") @@ -173,6 +176,40 @@ raise TypeError("bytes or str expected, got a '%s' object" % (type(text).__name__,)) +def _convert_to_chtype(win, obj): + if isinstance(obj, bytes) and len(obj) == 1: + value = ord(obj) + elif isinstance(obj, str): + if len(obj) != 1: + raise TypeError("expect bytes or str of length 1 or int, " + "got a str of length %d", len(obj)) + value = ord(obj) + if (128 < value): + if win: + encoding = win.encoding + else: + encoding = screen_encoding + b = obj.encode(encoding) + if len(bytes) == 1: + value = ord(b) + else: + OverflowError("byte doesn't fit in chtype") + elif isinstance(obj, int): + value = obj + else: + raise TypeError('expect bytes or str of length 1, or int, got %s' % type(obj)) + return value + +def _convert_to_string(win, obj): + if isinstance(obj, str): + value = obj.encode(win.encoding) + elif isinstance(obj, bytes): + value = obj + else: + raise TypeError('expect bytes or str, got %s' % type(obj)) + if b'\0' in value: + raise ValueError('embedded null character') + return value def _extract_yx(args): if len(args) >= 2: @@ -216,8 +253,17 @@ class Window(object): - def __init__(self, window): + def __init__(self, window, encoding=None): + if encoding is None: + # CPython has a win32 branch here, but _curses is not supported + # on win32 + codeset = locale.nl_langinfo(locale.CODESET) + if codeset: + encoding = codeset + else: + encoding = 'utf-8' self._win = window + self._encoding = encoding def __del__(self): if self._win != lib.stdscr: @@ -286,7 +332,7 @@ @_argspec(1, 1, 2) def addstr(self, y, x, text, attr=None): - text = _bytestype(text) + text = _convert_to_string(self, text) if attr is not None: attr_old = lib.getattrs(self._win) lib.wattrset(self._win, attr) @@ -300,7 +346,7 @@ @_argspec(2, 1, 2) def addnstr(self, y, x, text, n, attr=None): - text = _bytestype(text) + text = _convert_to_string(self, text) if attr is not None: attr_old = lib.getattrs(self._win) lib.wattrset(self._win, attr) @@ -333,7 +379,15 @@ _chtype(tl), _chtype(tr), _chtype(bl), _chtype(br)) return None - def box(self, vertint=0, horint=0): + def box(self, *args): + if len(args) == 0: + vertint = 0 + horint = 0 + elif len(args) == 2: + vertint = _convert_to_chtype(self, args[0]) + horint = _convert_to_chtype(self, args[1]) + else: + raise TypeError('verch,horch required') lib.box(self._win, vertint, horint) return None @@ -434,11 +488,16 @@ val = lib.keyname(val) if val == ffi.NULL: return "" - return ffi.string(val) + key_n = ffi.string(val) + if not isinstance(key_n, str): + key_n = key_n.decode('utf-8') + return key_n @_argspec(0, 1, 2) def getstr(self, y, x, n=1023): n = min(n, 1023) + if n < 0: + raise ValueError("'n' must be nonnegative") buf = ffi.new("char[1024]") # /* This should be big enough.. I hope */ if y is None: @@ -481,6 +540,8 @@ @_argspec(0, 1, 2) def instr(self, y, x, n=1023): n = min(n, 1023) + if n < 0: + raise ValueError("'n' must be nonnegative") buf = ffi.new("char[1024]") # /* This should be big enough.. I hope */ if y is None: code = lib.winnstr(self._win, buf, n) @@ -493,7 +554,7 @@ @_argspec(1, 1, 2) def insstr(self, y, x, text, attr=None): - text = _bytestype(text) + text = _convert_to_string(self, text) if attr is not None: attr_old = lib.getattrs(self._win) lib.wattrset(self._win, attr) @@ -507,7 +568,7 @@ @_argspec(2, 1, 2) def insnstr(self, y, x, text, n, attr=None): - text = _bytestype(text) + text = _convert_to_string(self, text) if attr is not None: attr_old = lib.getattrs(self._win) lib.wattrset(self._win, attr) @@ -601,7 +662,7 @@ win = lib.subpad(self._win, nlines, ncols, begin_y, begin_x) else: win = lib.subwin(self._win, nlines, ncols, begin_y, begin_x) - return Window(_check_NULL(win)) + return Window(_check_NULL(win), self.encoding) def scroll(self, nlines=None): if nlines is None: @@ -625,6 +686,23 @@ _check_ERR(lib.wmove(self._win, y, x), "wmove") return _check_ERR(lib.wvline(self._win, ch | attr, n), "vline") + @property + def encoding(self): + return self._encoding + + @encoding.setter + def encoding(self, val): + if not val: + raise TypeError('encoding may not be deleted') + if not isinstance(val, str): + raise TypeError('setting encoding to a non-string') + encoding = val.encode('ascii') + self._encoding = val + + @encoding.deleter + def encoding(self): + raise TypeError('encoding may not be deleted') + beep = _mk_no_return("beep") def_prog_mode = _mk_no_return("def_prog_mode") @@ -812,7 +890,9 @@ globals()["LINES"] = lib.LINES globals()["COLS"] = lib.COLS - return Window(win) + window = Window(win) + globals()['screen_encoding'] = window.encoding + return window def setupterm(term=None, fd=-1): @@ -1021,7 +1101,13 @@ def unget_wch(ch): _ensure_initialised() - return _check_ERR(lib.unget_wch(_chtype(ch)), "unget_wch") + if isinstance(ch, str): + if len(ch) != 1: + raise TypeError("expect bytes or str of length1, or int, " + "got a str of length %d" % len(ch)) + elif isinstance(ch, int): + ch = chr(ch) + return _check_ERR(lib.unget_wch(ch), "unget_wch") def use_env(flag): diff --git a/lib_pypy/_sysconfigdata.py b/lib_pypy/_sysconfigdata.py --- a/lib_pypy/_sysconfigdata.py +++ b/lib_pypy/_sysconfigdata.py @@ -47,4 +47,5 @@ build_time_vars['CC'] += ' -arch %s' % (arch,) if "CXX" in build_time_vars: build_time_vars['CXX'] += ' -arch %s' % (arch,) + build_time_vars['MACOSX_DEPLOYMENT_TARGET'] = '10.7' diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -68,6 +68,11 @@ if not mode_A and not mode_D: # 'own' tests from rpython.conftest import LeakFinder config.pluginmanager.register(LeakFinder()) + if mode_A: + from pypy.tool.pytest.apptest import PythonInterpreter + config.applevel = PythonInterpreter(config.option.python) + else: + config.applevel = None def pytest_addoption(parser): group = parser.getgroup("pypy options") @@ -201,13 +206,17 @@ @pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(item): if isinstance(item, py.test.collect.Function): + config = item.config + if item.get_marker(name='pypy_only'): + if config.applevel is not None and not config.applevel.is_pypy: + pytest.skip('PyPy-specific test') appclass = item.getparent(py.test.Class) if appclass is not None: from pypy.tool.pytest.objspace import gettestobjspace # Make cls.space and cls.runappdirect available in tests. spaceconfig = getattr(appclass.obj, 'spaceconfig', {}) appclass.obj.space = gettestobjspace(**spaceconfig) - appclass.obj.runappdirect = option.runappdirect + appclass.obj.runappdirect = config.option.runappdirect def pytest_ignore_collect(path, config): if (config.getoption('direct_apptest') and not path.isdir() diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py --- a/pypy/interpreter/test/test_argument.py +++ b/pypy/interpreter/test/test_argument.py @@ -806,7 +806,7 @@ exc = raises(TypeError, '(lambda *, kw: 0)(1, kw=3)') assert str(exc.value) == "() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given" - @py.test.mark.skipif("config.option.runappdirect") + @pytest.mark.pypy_only def test_error_message_method(self): class A(object): def f0(): @@ -823,14 +823,14 @@ # does not contain the warning about missing self assert exc.value.args[0] == "f0() takes 0 positional arguments but 1 was given" - @py.test.mark.skipif("config.option.runappdirect") def test_error_message_module_function(self): import operator # use countOf because it's defined at applevel exc = raises(TypeError, lambda : operator.countOf(1, 2, 3)) - # does not contain the warning about missing self - assert exc.value.args[0] == "countOf() takes 2 positional arguments but 3 were given" + # does not contain the warning + # 'Did you forget 'self' in the function definition?' + assert 'self' not in str(exc.value) - @py.test.mark.skipif("config.option.runappdirect") + @pytest.mark.pypy_only def test_error_message_bound_method(self): class A(object): def f0(): diff --git a/pypy/module/__builtin__/test/test_abstractinst.py b/pypy/module/__builtin__/test/test_abstractinst.py --- a/pypy/module/__builtin__/test/test_abstractinst.py +++ b/pypy/module/__builtin__/test/test_abstractinst.py @@ -215,7 +215,7 @@ def test_dont_call_instancecheck_fast_path(self): called = [] - + class M(type): def __instancecheck__(self, obj): called.append("called") @@ -272,9 +272,30 @@ except Special: pass + def test_exception_bad_subclasscheck(self): + """ + import sys + class Meta(type): + def __subclasscheck__(cls, subclass): + raise ValueError() + + class MyException(Exception, metaclass=Meta): + pass + + try: + raise KeyError() + except MyException as e: + assert False, "exception should not be a MyException" + except KeyError: + pass + except: + assert False, "Should have raised KeyError" + else: + assert False, "Should have raised KeyError" + """ + def test_exception_contains_type_name(self): with raises(TypeError) as e: issubclass(type, None) print(e.value) assert "NoneType" in str(e.value) - diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -194,17 +194,23 @@ rffi.SSIZE_T) pypy_cjk_enc_getcodec = llexternal('pypy_cjk_enc_getcodec', [ENCODEBUF_P], MULTIBYTECODEC_P) +pypy_cjk_enc_copystate = llexternal('pypy_cjk_enc_copystate', + [ENCODEBUF_P, ENCODEBUF_P], lltype.Void) MBENC_FLUSH = 1 MBENC_RESET = 2 def encode(codec, unicodedata, length, errors="strict", errorcb=None, - namecb=None): + namecb=None, copystate=lltype.nullptr(ENCODEBUF_P.TO)): encodebuf = pypy_cjk_enc_new(codec) if not encodebuf: raise MemoryError + if copystate: + pypy_cjk_enc_copystate(encodebuf, copystate) try: return encodeex(encodebuf, unicodedata, length, errors, errorcb, namecb) finally: + if copystate: + pypy_cjk_enc_copystate(copystate, encodebuf) pypy_cjk_enc_free(encodebuf) def encodeex(encodebuf, utf8data, length, errors="strict", errorcb=None, @@ -257,22 +263,21 @@ raise EncodeDecodeError(start, end, reason) elif errors == "ignore": replace = "" + rettype = 'b' # != 'u' elif errors == "replace": - codec = pypy_cjk_enc_getcodec(encodebuf) - try: - replace = encode(codec, "?", 1) - except EncodeDecodeError: - replace = "?" + replace = "?" # utf-8 unicode + rettype = 'u' else: assert errorcb replace, end, rettype = errorcb(errors, namecb, reason, unicodedata, start, end) - if rettype == 'u': - codec = pypy_cjk_enc_getcodec(encodebuf) - lgt = rutf8.check_utf8(replace, False) - replace = encode(codec, replace, lgt) - lgt = len(replace) + if rettype == 'u': + codec = pypy_cjk_enc_getcodec(encodebuf) + lgt = rutf8.check_utf8(replace, False) + replace = encode(codec, replace, lgt, copystate=encodebuf) + #else: + # replace is meant to be a byte string already with rffi.scoped_nonmovingbuffer(replace) as inbuf: - r = pypy_cjk_enc_replace_on_error(encodebuf, inbuf, lgt, end) + r = pypy_cjk_enc_replace_on_error(encodebuf, inbuf, len(replace), end) if r == MBERR_NOMEMORY: raise MemoryError diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c --- a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c +++ b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.c @@ -135,6 +135,11 @@ return d; } +void pypy_cjk_enc_copystate(struct pypy_cjk_enc_s *dst, struct pypy_cjk_enc_s *src) +{ + dst->state = src->state; +} + Py_ssize_t pypy_cjk_enc_init(struct pypy_cjk_enc_s *d, Py_UNICODE *inbuf, Py_ssize_t inlen) { diff --git a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h --- a/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h +++ b/pypy/module/_multibytecodec/src/cjkcodecs/multibytecodec.h @@ -146,6 +146,8 @@ char *, pypymbc_ssize_t, pypymbc_ssize_t); RPY_EXTERN const MultibyteCodec *pypy_cjk_enc_getcodec(struct pypy_cjk_enc_s *); +RPY_EXTERN +void pypy_cjk_enc_copystate(struct pypy_cjk_enc_s *dst, struct pypy_cjk_enc_s *src); /* list of codecs defined in the .c files */ diff --git a/pypy/module/_multibytecodec/test/test_app_codecs.py b/pypy/module/_multibytecodec/test/test_app_codecs.py --- a/pypy/module/_multibytecodec/test/test_app_codecs.py +++ b/pypy/module/_multibytecodec/test/test_app_codecs.py @@ -126,3 +126,33 @@ lambda e: (b'\xc3', e.end)) result = "\uDDA1".encode("gbk", "test.test_encode_custom_error_handler_type") assert b'\xc3' in result + + def test_encode_replacement_with_state(self): + import codecs + s = u'\u4ee4\u477c\u4ee4'.encode("iso-2022-jp", errors="replace") + assert s == b'\x1b$BNa\x1b(B?\x1b$BNa\x1b(B' + + def test_streaming_codec(self): + test_0 = u'\uc5fc\u76d0\u5869\u9e7d\u477c\u4e3d/\u3012' + test_1 = u'\u4ee4\u477c\u3080\u304b\u3057\u3080\u304b\u3057\u3042\u308b\u3068\u3053\u308d\u306b' + test_2 = u' foo = "Quoted string ****\u4ee4\u477c" ' + + ereplace = {'errors': 'replace'} + exml = {'errors': 'xmlcharrefreplace'} + for codec in ("iso-2022-jp", "iso-2022-jp-ext", "iso-2022-jp-1", + "iso-2022-jp-2", "iso-2022-jp-3", "iso-2022-jp-2004", + "iso-2022-kr", + ): + + out_1 = test_1.encode(codec, **ereplace).decode(codec, **ereplace) + assert out_1.endswith(u'\u3080\u304b\u3057\u3080\u304b\u3057\u3042\u308b\u3068\u3053\u308d\u306b') + + out_0a = test_0.encode(codec, **ereplace).decode(codec, **ereplace) + for n, char in enumerate(out_0a): + assert char in (test_0[n], "?") + + out_0b = test_0.encode(codec, **exml).decode(codec, **ereplace) + assert "䝼" in out_0b + + out_2 = test_2.encode(codec, **ereplace).decode(codec, **ereplace) + assert out_2.count('"') == 2 diff --git a/pypy/module/cpyext/codecs.py b/pypy/module/cpyext/codecs.py --- a/pypy/module/cpyext/codecs.py +++ b/pypy/module/cpyext/codecs.py @@ -20,3 +20,12 @@ else: return space.call_method(w_codec, "incrementaldecoder") + at cpython_api([CONST_STRING], PyObject) +def PyCodec_Encoder(space, encoding): + w_codec = interp_codecs.lookup_codec(space, rffi.charp2str(encoding)) + return space.getitem(w_codec, space.newint(0)) + + at cpython_api([CONST_STRING], PyObject) +def PyCodec_Decoder(space, encoding): + w_codec = interp_codecs.lookup_codec(space, rffi.charp2str(encoding)) + return space.getitem(w_codec, space.newint(1)) diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -123,6 +123,7 @@ #include "sliceobject.h" #include "genobject.h" #include "datetime.h" +#include "structseq.h" #include "pystate.h" #include "fileobject.h" #include "pysignals.h" diff --git a/pypy/module/cpyext/test/test_codecs.py b/pypy/module/cpyext/test/test_codecs.py --- a/pypy/module/cpyext/test/test_codecs.py +++ b/pypy/module/cpyext/test/test_codecs.py @@ -2,7 +2,8 @@ from pypy.module.cpyext.test.test_api import BaseApiTest from rpython.rtyper.lltypesystem import rffi from pypy.module.cpyext.codecs import ( - PyCodec_IncrementalEncoder, PyCodec_IncrementalDecoder) + PyCodec_IncrementalEncoder, PyCodec_IncrementalDecoder, + PyCodec_Encoder, PyCodec_Decoder) class TestCodecs(BaseApiTest): def test_incremental(self, space): @@ -13,3 +14,13 @@ w_decoded = space.call_method(w_decoder, 'decode', w_encoded) assert space.utf8_w(w_decoded) == u'späm'.encode("utf-8") rffi.free_charp(utf8) + + def test_encoder_decoder(self, space): + utf8 = rffi.str2charp('utf-8') + w_encoder = PyCodec_Encoder(space, utf8) + w_decoder = PyCodec_Decoder(space, utf8) + rffi.free_charp(utf8) + space.appexec([w_encoder, w_decoder], r"""(encoder, decoder): + assert encoder(u"\u1234") == (b"\xe1\x88\xb4", 1) + assert decoder(b"\xe1\x88\xb4") == (u"\u1234", 3) + """) diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py --- a/pypy/tool/pytest/apptest.py +++ b/pypy/tool/pytest/apptest.py @@ -35,6 +35,24 @@ def __init__(self, excinfo): self.excinfo = excinfo +class PythonInterpreter(object): + def __init__(self, path): + self.path = path + self._is_pypy = None + + @property + def is_pypy(self): + if self._is_pypy is not None: + return self._is_pypy + CODE = "import sys; print('__pypy__' in sys.builtin_module_names)" + res, stdout, stderr = run_subprocess( self.path, ["-c", CODE]) + if res != 0: + raise ValueError("Invalid Python interpreter") + print stdout + is_pypy = stdout.strip() == 'True' + self._is_pypy = is_pypy + return is_pypy + def py3k_repr(value): "return the repr() that py3k would give for an object.""" @@ -120,7 +138,7 @@ pytest.fail("DID NOT RAISE") self.value = tp[1] return issubclass(tp[0], self.expected_exception) - + __builtins__.raises = raises class Test: pass From pypy.commits at gmail.com Wed Jan 29 15:08:51 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 29 Jan 2020 12:08:51 -0800 (PST) Subject: [pypy-commit] pypy py3.7: fix merge Message-ID: <5e31e653.1c69fb81.f72c7.474a@mx.google.com> Author: Matti Picus Branch: py3.7 Changeset: r98595:af1982e722d3 Date: 2020-01-29 22:07 +0200 http://bitbucket.org/pypy/pypy/changeset/af1982e722d3/ Log: fix merge diff --git a/lib-python/3/venv/__init__.py b/lib-python/3/venv/__init__.py --- a/lib-python/3/venv/__init__.py +++ b/lib-python/3/venv/__init__.py @@ -187,10 +187,10 @@ logger.warning('Unable to symlink %r to %r', src, dst) force_copy = True if force_copy: - if os.path.isdir(src): - shutil.copytree(src, dst) - else: - shutil.copyfile(src, dst) + if os.path.isdir(src): + shutil.copytree(src, dst) + else: + shutil.copyfile(src, dst) else: def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ From pypy.commits at gmail.com Wed Jan 29 15:47:24 2020 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 29 Jan 2020 12:47:24 -0800 (PST) Subject: [pypy-commit] pypy py3.7: way too much work: forbid "% %" % () and variants Message-ID: <5e31ef5c.1c69fb81.74c60.5290@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98598:a512d2966a9a Date: 2020-01-29 21:46 +0100 http://bitbucket.org/pypy/pypy/changeset/a512d2966a9a/ Log: way too much work: forbid "% %" % () and variants diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py --- a/pypy/objspace/std/formatting.py +++ b/pypy/objspace/std/formatting.py @@ -297,12 +297,20 @@ result.append_slice(fmt, i0, i) self.fmtpos = i + 1 + c = self.peekchr() + if c == '%': + self.forward() + self.result.append('%') + continue + # interpret the next formatter w_value = self.parse_fmt() c = self.peekchr() self.forward() if c == '%': - self.result.append('%') + # if we get here there were extra characters between the + # two %, forbidden now + self.two_percent_error(i + 1) continue # first check whether it's a invalid char, *then* call @@ -329,17 +337,29 @@ self.checkconsumed() return result.build() - def unknown_fmtchar(self): + def _get_error_info(self, pos): space = self.space if do_unicode: - cp = rutf8.codepoint_at_pos(self.fmt, self.fmtpos - 1) - pos = rutf8.codepoints_in_utf8(self.fmt, 0, self.fmtpos - 1) + cp = rutf8.codepoint_at_pos(self.fmt, pos) + pos = rutf8.codepoints_in_utf8(self.fmt, 0, pos) w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp), allow_surrogates=True), 1) else: - cp = ord(self.fmt[self.fmtpos - 1]) - pos = self.fmtpos - 1 + cp = ord(self.fmt[pos]) w_s = space.newbytes(chr(cp)) + return w_s, pos, cp + + def two_percent_error(self, pos): + space = self.space + w_s, pos, cp = self._get_error_info(pos) + raise oefmt(space.w_ValueError, + # hahahaha + "extra character %R (%s) before escaped '%%' at index %d, use '%%%%'", + w_s, hex(cp), pos) + + def unknown_fmtchar(self): + space = self.space + w_s, pos, cp = self._get_error_info(self.fmtpos - 1) raise oefmt(space.w_ValueError, "unsupported format character %R (%s) at index %d", w_s, hex(cp), pos) diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py --- a/pypy/objspace/std/test/test_stringformat.py +++ b/pypy/objspace/std/test/test_stringformat.py @@ -278,6 +278,11 @@ with raises(ValueError): "%?" % {} # not TypeError + def test_no_chars_between_percent(self): + with raises(ValueError) as exc: + "% %" % () + assert "extra character ' ' (0x20) before escaped '%' at index 1" in str(exc.value) + class AppTestWidthPrec: def test_width(self): a = 'a' From pypy.commits at gmail.com Wed Jan 29 16:01:29 2020 From: pypy.commits at gmail.com (mattip) Date: Wed, 29 Jan 2020 13:01:29 -0800 (PST) Subject: [pypy-commit] benchmarks default: update for cpython run via run_local.py Message-ID: <5e31f2a9.1c69fb81.bcb2.25ce@mx.google.com> Author: Matti Picus Branch: Changeset: r439:0a0be263be14 Date: 2020-01-29 23:01 +0200 http://bitbucket.org/pypy/benchmarks/changeset/0a0be263be14/ Log: update for cpython run via run_local.py diff --git a/benchmarks.py b/benchmarks.py --- a/benchmarks.py +++ b/benchmarks.py @@ -25,7 +25,7 @@ def _register_new_bm_twisted(name, bm_name, d, **opts): def Measure(python, options): def parser(line): - number = float(line.split(" ")[0]) + number = float(line.split(b" ")[0]) if name == 'tcp': return 100*1024*1024/number elif name == 'iteration': diff --git a/run_local.py b/run_local.py --- a/run_local.py +++ b/run_local.py @@ -16,12 +16,12 @@ --fast --args=ARGS arguments to give to pypy-c, must not contain a comma! """ - +from __future__ import print_function import sys, os import subprocess if len(sys.argv) < 2 or sys.argv[1].startswith('-'): - print __doc__ + print(__doc__) sys.exit(2) pypy_c = sys.argv[1] @@ -36,11 +36,11 @@ '--changed', os.path.join(localdir, 'nullpython.py'), '--full-store', ] + sys.argv[1:] -print -print 'Executing', cmdline -print +print('') +print('Executing', cmdline) +print('') r = subprocess.call(cmdline) if r: - print >> sys.stderr, '*** exit code %r ***' % (r,) + print('*** exit code %r ***' % (r,), file=sys.stderr) sys.exit(r) diff --git a/savecpython.py b/savecpython.py --- a/savecpython.py +++ b/savecpython.py @@ -21,12 +21,20 @@ res_type = b[1] results = b[2] value = 0 - if res_type == "SimpleComparisonResult" or res_type == 'RawResult': + if res_type == "SimpleComparisonResult" + if base: + value = results['base_time'] + else: + value = results['changed_time'] + if value is None: + continue + value = value[0] + elif res_type == 'RawResult': if base: value = results['base_times'] else: value = results['changed_times'] - if value is None: + if value is None or len(value) == 0: continue value = value[0] elif res_type == "ComparisonResult": @@ -92,6 +100,6 @@ print parser.usage sys.exit(1) results = json.load(open(args[1]))['results'] - save('cpython', options.revision, results, None, 'cpython', 'tannit', + save('cpython', options.revision, results, None, 'cpython', 'benchmarker', testing=False, base=options.base) From pypy.commits at gmail.com Thu Jan 30 05:39:29 2020 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 30 Jan 2020 02:39:29 -0800 (PST) Subject: [pypy-commit] pypy default: add missing reverse operations to set and frozenset objects Message-ID: <5e32b261.1c69fb81.b7a04.a9bc@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98599:67454ea967cb Date: 2020-01-30 11:34 +0100 http://bitbucket.org/pypy/pypy/changeset/67454ea967cb/ Log: add missing reverse operations to set and frozenset objects diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -254,10 +254,16 @@ return space.w_NotImplemented return self.difference(w_other) + def descr_rsub(self, space, w_other): + if not isinstance(w_other, W_BaseSetObject): + return space.w_NotImplemented + return w_other.difference(self) + def descr_and(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.intersect(w_other) + descr_rand = descr_and # symmetric def descr_or(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -265,11 +271,13 @@ w_copy = self.copy_real() w_copy.update(w_other) return w_copy + descr_ror = descr_or # symmetric def descr_xor(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.symmetric_difference(w_other) + descr_rxor = descr_xor # symmetric def descr_inplace_sub(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -541,9 +549,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), + __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), + __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), + __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), + __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # mutating operators __isub__ = gateway.interp2app(W_BaseSetObject.descr_inplace_sub), @@ -663,9 +675,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), + __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), + __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), + __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), + __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # non-mutating methods __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce), diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -610,6 +610,40 @@ assert type(t) is subset assert not hasattr(t, 'x') + def test_reverse_ops(self): + assert set.__rxor__ + assert frozenset.__rxor__ + assert set.__ror__ + assert frozenset.__ror__ + assert set.__rand__ + assert frozenset.__rand__ + assert set.__rsub__ + assert frozenset.__rsub__ + + # actual behaviour test + for base in [set, frozenset]: + class S(base): + def __xor__(self, other): + if type(other) is not S: + return NotImplemented + return 1 + __or__ = __and__ = __sub__ = __xor__ + assert S([1, 2, 3]) ^ S([2, 3, 4]) == 1 + assert S([1, 2, 3]) ^ {2, 3, 4} == {1, 4} + assert {1, 2, 3} ^ S([2, 3, 4]) == {1, 4} + + assert S([1, 2, 3]) & S([2, 3, 4]) == 1 + assert S([1, 2, 3]) & {2, 3, 4} == {2, 3} + assert {1, 2, 3} & S([2, 3, 4]) == {2, 3} + + assert S([1, 2, 3]) | S([2, 3, 4]) == 1 + assert S([1, 2, 3]) | {2, 3, 4} == {1, 2, 3, 4} + assert {1, 2, 3} | S([2, 3, 4]) == {1, 2, 3, 4} + + assert S([1, 2, 3]) - S([2, 3, 4]) == 1 + assert S([1, 2, 3]) - {2, 3, 4} == {1} + assert {1, 2, 3} - S([2, 3, 4]) == {1} + def test_isdisjoint(self): assert set([1,2,3]).isdisjoint(set([4,5,6])) assert set([1,2,3]).isdisjoint(frozenset([4,5,6])) From pypy.commits at gmail.com Thu Jan 30 06:01:50 2020 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 30 Jan 2020 03:01:50 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5e32b79e.1c69fb81.94c6.e79b@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98600:75200e919c58 Date: 2020-01-30 11:59 +0100 http://bitbucket.org/pypy/pypy/changeset/75200e919c58/ Log: merge default diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -247,10 +247,16 @@ return space.w_NotImplemented return self.difference(w_other) + def descr_rsub(self, space, w_other): + if not isinstance(w_other, W_BaseSetObject): + return space.w_NotImplemented + return w_other.difference(self) + def descr_and(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.intersect(w_other) + descr_rand = descr_and # symmetric def descr_or(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -258,11 +264,13 @@ w_copy = self.copy_real() w_copy.update(w_other) return w_copy + descr_ror = descr_or # symmetric def descr_xor(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.symmetric_difference(w_other) + descr_rxor = descr_xor # symmetric def descr_inplace_sub(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -528,9 +536,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), + __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), + __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), + __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), + __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # mutating operators __isub__ = gateway.interp2app(W_BaseSetObject.descr_inplace_sub), @@ -644,9 +656,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), + __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), + __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), + __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), + __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # non-mutating methods __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce), diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -650,6 +650,40 @@ assert type(t) is base assert not hasattr(t, 'x') + def test_reverse_ops(self): + assert set.__rxor__ + assert frozenset.__rxor__ + assert set.__ror__ + assert frozenset.__ror__ + assert set.__rand__ + assert frozenset.__rand__ + assert set.__rsub__ + assert frozenset.__rsub__ + + # actual behaviour test + for base in [set, frozenset]: + class S(base): + def __xor__(self, other): + if type(other) is not S: + return NotImplemented + return 1 + __or__ = __and__ = __sub__ = __xor__ + assert S([1, 2, 3]) ^ S([2, 3, 4]) == 1 + assert S([1, 2, 3]) ^ {2, 3, 4} == {1, 4} + assert {1, 2, 3} ^ S([2, 3, 4]) == {1, 4} + + assert S([1, 2, 3]) & S([2, 3, 4]) == 1 + assert S([1, 2, 3]) & {2, 3, 4} == {2, 3} + assert {1, 2, 3} & S([2, 3, 4]) == {2, 3} + + assert S([1, 2, 3]) | S([2, 3, 4]) == 1 + assert S([1, 2, 3]) | {2, 3, 4} == {1, 2, 3, 4} + assert {1, 2, 3} | S([2, 3, 4]) == {1, 2, 3, 4} + + assert S([1, 2, 3]) - S([2, 3, 4]) == 1 + assert S([1, 2, 3]) - {2, 3, 4} == {1} + assert {1, 2, 3} - S([2, 3, 4]) == {1} + def test_isdisjoint(self): assert set([1,2,3]).isdisjoint(set([4,5,6])) assert set([1,2,3]).isdisjoint(frozenset([4,5,6])) From pypy.commits at gmail.com Thu Jan 30 13:04:23 2020 From: pypy.commits at gmail.com (arigo) Date: Thu, 30 Jan 2020 10:04:23 -0800 (PST) Subject: [pypy-commit] extradoc extradoc: Update Message-ID: <5e331aa7.1c69fb81.c02aa.6333@mx.google.com> Author: Armin Rigo Branch: extradoc Changeset: r5985:85cb797d8a37 Date: 2020-01-30 19:04 +0100 http://bitbucket.org/pypy/extradoc/changeset/85cb797d8a37/ Log: Update diff --git a/sprintinfo/leysin-winter-2020/announcement.txt b/sprintinfo/leysin-winter-2020/announcement.txt --- a/sprintinfo/leysin-winter-2020/announcement.txt +++ b/sprintinfo/leysin-winter-2020/announcement.txt @@ -1,5 +1,5 @@ ===================================================================== -Leysin Winter sprint 2020: Feb 28 - March 7th +Leysin Winter sprint 2020: Feb 29 - March 8th ===================================================================== The next PyPy sprint will be in Leysin, Switzerland, for the fourteenth time. @@ -23,15 +23,13 @@ Times and accomodation ---------------------- -The sprint will occur for one week starting on Friday, the 28th of February, to -Friday or Saturday, the 6th or 7th of March 2020. It will occur in Les +The sprint will occur for one week starting on Saturday, the 29th of +February, to Sunday, the 8th of March 2020. It will occur in Les Airelles, a different bed-and-breakfast place from the traditional one in Leysin. It is a nice old house at the top of the village. -We have a 4- or 5-people room as well as up to three double-rooms. Please -register early! These rooms are not booked for the sprint in advance, and -might be already taken if you end up announcing yourself late. (But it is of -course always possible to book at a different place in Leysin.) +We have a booked room for up to 7 people (plus extra smaller rooms possible). +(Of course it is always possible to book at a different place in Leysin.) You can register by adding your name in people.txt here. For more information, write to me directly at armin.rigo at gmail.com. diff --git a/sprintinfo/leysin-winter-2020/people.txt b/sprintinfo/leysin-winter-2020/people.txt --- a/sprintinfo/leysin-winter-2020/people.txt +++ b/sprintinfo/leysin-winter-2020/people.txt @@ -15,3 +15,6 @@ Manuel Jacob Feb 29–Mar 8 Les Airelles Simon Cross Feb 27-Mar 6 Les Airelles, bringing partner ==================== ============== ======================= + +The big room is for up to 7 people, probably with some subdivisions. +It is booked for the Feb 29 - March 8 period. From pypy.commits at gmail.com Fri Jan 31 00:21:40 2020 From: pypy.commits at gmail.com (arigo) Date: Thu, 30 Jan 2020 21:21:40 -0800 (PST) Subject: [pypy-commit] cffi default: The point of this example is that it doesn't work with a variable, only with a Message-ID: <5e33b964.1c69fb81.1361c.dfbd@mx.google.com> Author: Armin Rigo Branch: Changeset: r3332:459f86e1d944 Date: 2020-01-31 06:20 +0100 http://bitbucket.org/cffi/cffi/changeset/459f86e1d944/ Log: The point of this example is that it doesn't work with a variable, only with a constant number. So don't use `n`. diff --git a/doc/source/ref.rst b/doc/source/ref.rst --- a/doc/source/ref.rst +++ b/doc/source/ref.rst @@ -37,7 +37,7 @@ allocate an instance according to the specified C type and return a pointer to it. The specified C type must be either a pointer or an array: ``new('X *')`` allocates an X and returns a pointer to it, -whereas ``new('X[n]')`` allocates an array of n X'es and returns an +whereas ``new('X[10]')`` allocates an array of 10 X'es and returns an array referencing it (which works mostly like a pointer, like in C). You can also use ``new('X[]', n)`` to allocate an array of a non-constant length n. See the `detailed documentation`__ for other From pypy.commits at gmail.com Fri Jan 31 00:21:54 2020 From: pypy.commits at gmail.com (rlamy) Date: Thu, 30 Jan 2020 21:21:54 -0800 (PST) Subject: [pypy-commit] pypy StringIO-perf: Store UnicodeIO data as a list of unichars instead of GC strings Message-ID: <5e33b972.1c69fb81.1602b.c10c@mx.google.com> Author: Ronan Lamy Branch: StringIO-perf Changeset: r98603:b53569f5531d Date: 2020-01-31 05:20 +0000 http://bitbucket.org/pypy/pypy/changeset/b53569f5531d/ Log: Store UnicodeIO data as a list of unichars instead of GC strings diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py --- a/pypy/module/_io/interp_stringio.py +++ b/pypy/module/_io/interp_stringio.py @@ -21,7 +21,7 @@ if len(self.data) > newlength: self.data = self.data[:newlength] if len(self.data) < newlength: - self.data.extend(['\0'] * (newlength - len(self.data))) + self.data.extend([u'\0'] * (newlength - len(self.data))) def read(self, size): start = self.pos @@ -34,7 +34,7 @@ end = len(self.data) assert 0 <= start <= end self.pos = end - return ''.join(self.data[start:end]) + return u''.join(self.data[start:end]).encode('utf-8') def _convert_limit(self, limit): if limit < 0 or limit > len(self.data) - self.pos: @@ -51,18 +51,18 @@ while pos < end: ch = self.data[pos] pos += 1 - if ch == '\n': + if ch == u'\n': break - if ch == '\r': + if ch == u'\r': if pos >= end: break - if self.data[pos] == '\n': + if self.data[pos] == u'\n': pos += 1 break else: break self.pos = pos - result = ''.join(self.data[start:pos]) + result = u''.join(self.data[start:pos]).encode('utf-8') return result def readline(self, marker, limit): @@ -70,6 +70,7 @@ limit = self._convert_limit(limit) end = start + limit found = False + marker = marker.decode('utf-8') for pos in range(start, end - len(marker) + 1): ch = self.data[pos] if ch == marker[0]: @@ -83,19 +84,17 @@ if not found: pos = end self.pos = pos - result = ''.join(self.data[start:pos]) + result = u''.join(self.data[start:pos]).encode('utf-8') return result def write(self, string): - length = codepoints_in_utf8(string) - if self.pos + length > len(self.data): - self.resize(self.pos + length) - pos = 0 - for i in range(length): - nextpos = next_codepoint_pos(string, pos) - self.data[self.pos + i] = string[pos:nextpos] - pos = nextpos - self.pos += length + ustr = string.decode('utf-8') + newlen = self.pos + len(ustr) + if newlen > len(self.data): + self.resize(newlen) + for i in range(len(ustr)): + self.data[self.pos + i] = ustr[i] + self.pos += len(ustr) def seek(self, pos): self.pos = pos @@ -105,7 +104,7 @@ self.resize(size) def getvalue(self): - return ''.join(self.data) + return u''.join(self.data).encode('utf-8') class W_StringIO(W_TextIOBase): From pypy.commits at gmail.com Fri Jan 31 08:11:56 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:11:56 -0800 (PST) Subject: [pypy-commit] pypy default: argh, fix bug in locale-specific string formatting: the thousands separator was always '.' :-( Message-ID: <5e34279c.1c69fb81.95024.84e3@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98604:b6af70ef2dfb Date: 2020-01-30 14:44 +0100 http://bitbucket.org/pypy/pypy/changeset/b6af70ef2dfb/ Log: argh, fix bug in locale-specific string formatting: the thousands separator was always '.' :-( diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -772,7 +772,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: - out.append(self._lit(".")[0]) + out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -389,6 +389,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') + def test_locale_german(self): + import locale + for name in ['de_DE', 'de_DE.utf8']: + try: + locale.setlocale(locale.LC_NUMERIC, name) + break + except locale.Error: + pass + else: + skip("no german locale") + x = 1234.567890 + try: + assert locale.format('%g', x, grouping=True) == '1.234,57' + assert format(x, 'n') == '1.234,57' + assert format(12345678901234, 'n') == '12.345.678.901.234' + finally: + locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 From pypy.commits at gmail.com Fri Jan 31 08:11:59 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:11:59 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5e34279f.1c69fb81.51edf.1345@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98605:0115587c02f4 Date: 2020-01-30 14:45 +0100 http://bitbucket.org/pypy/pypy/changeset/0115587c02f4/ Log: merge default diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -802,7 +802,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: - out.append(self._lit(".")[0]) + out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -404,6 +404,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') + def test_locale_german(self): + import locale + for name in ['de_DE', 'de_DE.utf8']: + try: + locale.setlocale(locale.LC_NUMERIC, name) + break + except locale.Error: + pass + else: + skip("no german locale") + x = 1234.567890 + try: + assert locale.format('%g', x, grouping=True) == '1.234,57' + assert format(x, 'n') == '1.234,57' + assert format(12345678901234, 'n') == '12.345.678.901.234' + finally: + locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 From pypy.commits at gmail.com Fri Jan 31 08:12:02 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:02 -0800 (PST) Subject: [pypy-commit] pypy py3.7: merge py3.6 Message-ID: <5e3427a2.1c69fb81.da928.677d@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98606:c5c4cd76ef44 Date: 2020-01-30 14:45 +0100 http://bitbucket.org/pypy/pypy/changeset/c5c4cd76ef44/ Log: merge py3.6 diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -802,7 +802,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: - out.append(self._lit(".")[0]) + out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -247,10 +247,16 @@ return space.w_NotImplemented return self.difference(w_other) + def descr_rsub(self, space, w_other): + if not isinstance(w_other, W_BaseSetObject): + return space.w_NotImplemented + return w_other.difference(self) + def descr_and(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.intersect(w_other) + descr_rand = descr_and # symmetric def descr_or(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -258,11 +264,13 @@ w_copy = self.copy_real() w_copy.update(w_other) return w_copy + descr_ror = descr_or # symmetric def descr_xor(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.symmetric_difference(w_other) + descr_rxor = descr_xor # symmetric def descr_inplace_sub(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -528,9 +536,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), + __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), + __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), + __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), + __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # mutating operators __isub__ = gateway.interp2app(W_BaseSetObject.descr_inplace_sub), @@ -644,9 +656,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), + __rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), + __rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), + __ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), + __rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # non-mutating methods __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce), diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -404,6 +404,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') + def test_locale_german(self): + import locale + for name in ['de_DE', 'de_DE.utf8']: + try: + locale.setlocale(locale.LC_NUMERIC, name) + break + except locale.Error: + pass + else: + skip("no german locale") + x = 1234.567890 + try: + assert locale.format('%g', x, grouping=True) == '1.234,57' + assert format(x, 'n') == '1.234,57' + assert format(12345678901234, 'n') == '12.345.678.901.234' + finally: + locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -650,6 +650,40 @@ assert type(t) is base assert not hasattr(t, 'x') + def test_reverse_ops(self): + assert set.__rxor__ + assert frozenset.__rxor__ + assert set.__ror__ + assert frozenset.__ror__ + assert set.__rand__ + assert frozenset.__rand__ + assert set.__rsub__ + assert frozenset.__rsub__ + + # actual behaviour test + for base in [set, frozenset]: + class S(base): + def __xor__(self, other): + if type(other) is not S: + return NotImplemented + return 1 + __or__ = __and__ = __sub__ = __xor__ + assert S([1, 2, 3]) ^ S([2, 3, 4]) == 1 + assert S([1, 2, 3]) ^ {2, 3, 4} == {1, 4} + assert {1, 2, 3} ^ S([2, 3, 4]) == {1, 4} + + assert S([1, 2, 3]) & S([2, 3, 4]) == 1 + assert S([1, 2, 3]) & {2, 3, 4} == {2, 3} + assert {1, 2, 3} & S([2, 3, 4]) == {2, 3} + + assert S([1, 2, 3]) | S([2, 3, 4]) == 1 + assert S([1, 2, 3]) | {2, 3, 4} == {1, 2, 3, 4} + assert {1, 2, 3} | S([2, 3, 4]) == {1, 2, 3, 4} + + assert S([1, 2, 3]) - S([2, 3, 4]) == 1 + assert S([1, 2, 3]) - {2, 3, 4} == {1} + assert {1, 2, 3} - S([2, 3, 4]) == {1} + def test_isdisjoint(self): assert set([1,2,3]).isdisjoint(set([4,5,6])) assert set([1,2,3]).isdisjoint(frozenset([4,5,6])) From pypy.commits at gmail.com Fri Jan 31 08:12:05 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:05 -0800 (PST) Subject: [pypy-commit] pypy py3.7: make get/set_coroutine_wrapper emit a DeprecationWarning Message-ID: <5e3427a5.1c69fb81.89256.004f@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98607:66293dfd6fd3 Date: 2020-01-30 15:41 +0100 http://bitbucket.org/pypy/pypy/changeset/66293dfd6fd3/ Log: make get/set_coroutine_wrapper emit a DeprecationWarning diff --git a/pypy/interpreter/test/apptest_coroutine.py b/pypy/interpreter/test/apptest_coroutine.py --- a/pypy/interpreter/test/apptest_coroutine.py +++ b/pypy/interpreter/test/apptest_coroutine.py @@ -123,6 +123,18 @@ sys.set_coroutine_wrapper(None) assert sys.get_coroutine_wrapper() is None +def test_get_set_coroutine_wrapper_deprecated(): + import warnings + def my_wrapper(cr): + return 1 + with warnings.catch_warnings(record=True) as l: + warnings.simplefilter('always', category=DeprecationWarning) + sys.get_coroutine_wrapper() + sys.set_coroutine_wrapper(my_wrapper) + sys.set_coroutine_wrapper(None) + print(l) + assert len(l) == 3 + def test_async_with(): seen = [] class X: diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -343,12 +343,14 @@ def get_coroutine_wrapper(space): "Return the wrapper for coroutine objects set by sys.set_coroutine_wrapper." + space.warn(space.newtext("get_coroutine_wrapper is deprecated"), space.w_DeprecationWarning) ec = space.getexecutioncontext() if ec.w_coroutine_wrapper_fn is None: return space.w_None return ec.w_coroutine_wrapper_fn def set_coroutine_wrapper(space, w_wrapper): + space.warn(space.newtext("set_coroutine_wrapper is deprecated"), space.w_DeprecationWarning) "Set a wrapper for coroutine objects." ec = space.getexecutioncontext() if space.is_w(w_wrapper, space.w_None): From pypy.commits at gmail.com Fri Jan 31 08:12:08 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:08 -0800 (PST) Subject: [pypy-commit] pypy py3.7: only async *generator* expressions should work, not other comprehensions! Message-ID: <5e3427a8.1c69fb81.4bd6c.7cdd@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98608:30f0db9aea2b Date: 2020-01-30 16:00 +0100 http://bitbucket.org/pypy/pypy/changeset/30f0db9aea2b/ Log: only async *generator* expressions should work, not other comprehensions! diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -1567,7 +1567,11 @@ def _compile_comprehension(self, node, name, sub_scope): is_async_function = self.scope.is_coroutine code, qualname = self.sub_scope(sub_scope, name, node, node.lineno) - is_async_generator = self.symbols.find_scope(node).is_coroutine + is_async_comprehension = self.symbols.find_scope(node).is_coroutine + if is_async_comprehension and not is_async_function: + if not isinstance(node, ast.GeneratorExp): + self.error("asynchronous comprehension outside of " + "an asynchronous function", node) self.update_position(node.lineno) self._make_function(code, qualname=qualname) @@ -1581,7 +1585,7 @@ else: self.emit_op(ops.GET_ITER) self.emit_op_arg(ops.CALL_FUNCTION, 1) - if is_async_generator and sub_scope is not GenExpCodeGenerator: + if is_async_comprehension and sub_scope is not GenExpCodeGenerator: self.emit_op(ops.GET_AWAITABLE) self.load_const(self.space.w_None) self.emit_op(ops.YIELD_FROM) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1231,6 +1231,33 @@ """ e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) + def test_async_in_nested(self): + source = """if 1: + async def foo(): + def bar(): + [i async for i in items] + """ + e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) + source = """if 1: + async def foo(): + def bar(): + {i async for i in items} + """ + e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) + source = """if 1: + async def foo(): + def bar(): + {i: i+1 async for i in items} + """ + e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) + source = """if 1: + async def foo(): + def bar(): + (i async for i in items) + """ + # ok! + self.simple_test(source, "None", None) + def test_load_classderef(self): source = """if 1: def f(): From pypy.commits at gmail.com Fri Jan 31 08:12:10 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:10 -0800 (PST) Subject: [pypy-commit] pypy default: issue #3065 strikes again! fix segfault in mmap Message-ID: <5e3427aa.1c69fb81.e5132.c347@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98609:d22a7659ed80 Date: 2020-01-31 14:04 +0100 http://bitbucket.org/pypy/pypy/changeset/d22a7659ed80/ Log: issue #3065 strikes again! fix segfault in mmap diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -177,8 +177,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) - for i in range(start, stop, step): - b.append(self.mmap.getitem(i)) + index = start + for i in range(length): + b.append(self.mmap.getitem(index)) + index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -433,6 +433,15 @@ m.close() f.close() + def test_get_crash(self): + import sys + from mmap import mmap + s = b'hallo!!!' + m = mmap(-1, len(s)) + m[:] = s + assert m[1:None:sys.maxsize] == b'a' + m.close() + def test_set_item(self): import mmap From pypy.commits at gmail.com Fri Jan 31 08:12:13 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:13 -0800 (PST) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5e3427ad.1c69fb81.771d8.43c7@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98610:f0843db5a3a6 Date: 2020-01-31 14:06 +0100 http://bitbucket.org/pypy/pypy/changeset/f0843db5a3a6/ Log: merge default diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -190,8 +190,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) - for i in range(start, stop, step): - b.append(self.mmap.getitem(i)) + index = start + for i in range(length): + b.append(self.mmap.getitem(index)) + index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -431,6 +431,15 @@ m.close() f.close() + def test_get_crash(self): + import sys + from mmap import mmap + s = b'hallo!!!' + m = mmap(-1, len(s)) + m[:] = s + assert m[1:None:sys.maxsize] == b'a' + m.close() + def test_set_item(self): import mmap From pypy.commits at gmail.com Fri Jan 31 08:12:15 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:15 -0800 (PST) Subject: [pypy-commit] pypy py3.7: merge py3.6 Message-ID: <5e3427af.1c69fb81.196fd.62c2@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98611:d024eab5de59 Date: 2020-01-31 14:07 +0100 http://bitbucket.org/pypy/pypy/changeset/d024eab5de59/ Log: merge py3.6 diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -190,8 +190,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) - for i in range(start, stop, step): - b.append(self.mmap.getitem(i)) + index = start + for i in range(length): + b.append(self.mmap.getitem(index)) + index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -431,6 +431,15 @@ m.close() f.close() + def test_get_crash(self): + import sys + from mmap import mmap + s = b'hallo!!!' + m = mmap(-1, len(s)) + m[:] = s + assert m[1:None:sys.maxsize] == b'a' + m.close() + def test_set_item(self): import mmap From pypy.commits at gmail.com Fri Jan 31 08:12:18 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 05:12:18 -0800 (PST) Subject: [pypy-commit] pypy default: merge heads Message-ID: <5e3427b2.1c69fb81.7a90e.0c4b@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98612:39bcfae01bee Date: 2020-01-31 14:10 +0100 http://bitbucket.org/pypy/pypy/changeset/39bcfae01bee/ Log: merge heads diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -177,8 +177,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) - for i in range(start, stop, step): - b.append(self.mmap.getitem(i)) + index = start + for i in range(length): + b.append(self.mmap.getitem(index)) + index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -433,6 +433,15 @@ m.close() f.close() + def test_get_crash(self): + import sys + from mmap import mmap + s = b'hallo!!!' + m = mmap(-1, len(s)) + m[:] = s + assert m[1:None:sys.maxsize] == b'a' + m.close() + def test_set_item(self): import mmap diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -772,7 +772,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: - out.append(self._lit(".")[0]) + out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -389,6 +389,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') + def test_locale_german(self): + import locale + for name in ['de_DE', 'de_DE.utf8']: + try: + locale.setlocale(locale.LC_NUMERIC, name) + break + except locale.Error: + pass + else: + skip("no german locale") + x = 1234.567890 + try: + assert locale.format('%g', x, grouping=True) == '1.234,57' + assert format(x, 'n') == '1.234,57' + assert format(12345678901234, 'n') == '12.345.678.901.234' + finally: + locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 From pypy.commits at gmail.com Fri Jan 31 09:48:02 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 06:48:02 -0800 (PST) Subject: [pypy-commit] pypy py3.7: generator_stop is not the default Message-ID: <5e343e22.1c69fb81.cb39e.31cd@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98613:cac6a157cae7 Date: 2020-01-31 15:37 +0100 http://bitbucket.org/pypy/pypy/changeset/cac6a157cae7/ Log: generator_stop is not the default diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -163,23 +163,14 @@ self.frame.w_yielding_from = w_delegate def _leak_stopiteration(self, e): - # Check for __future__ generator_stop and conditionally turn - # a leaking StopIteration into RuntimeError (with its cause - # set appropriately). + # turn a leaking StopIteration into RuntimeError (with its cause set + # appropriately). space = self.space - if self.pycode.co_flags & (consts.CO_FUTURE_GENERATOR_STOP | - consts.CO_COROUTINE | - consts.CO_ITERABLE_COROUTINE | - consts.CO_ASYNC_GENERATOR): - e2 = OperationError(space.w_RuntimeError, - space.newtext("%s raised StopIteration" % - self.KIND)) - e2.chain_exceptions_from_cause(space, e) - raise e2 - else: - space.warn(space.newtext("generator '%s' raised StopIteration" - % self.get_qualname()), - space.w_DeprecationWarning) + e2 = OperationError(space.w_RuntimeError, + space.newtext("%s raised StopIteration" % + self.KIND)) + e2.chain_exceptions_from_cause(space, e) + raise e2 def _leak_stopasynciteration(self, e): space = self.space diff --git a/pypy/interpreter/test/apptest_generator.py b/pypy/interpreter/test/apptest_generator.py --- a/pypy/interpreter/test/apptest_generator.py +++ b/pypy/interpreter/test/apptest_generator.py @@ -221,16 +221,6 @@ g = f() assert g.close() is None -def test_close2(): - def f(): - try: - yield 1 - except GeneratorExit: - raise StopIteration - g = f() - next(g) - assert g.close() is None - def test_close3(): def f(): try: @@ -275,21 +265,6 @@ with raises(TypeError): g.send(1) # not started, must send None -def test_generator_explicit_stopiteration(): - def f(): - yield 1 - raise StopIteration - g = f() - assert [x for x in g] == [1] - -def test_generator_propagate_stopiteration(): - def f(): - it = iter([1]) - while 1: - yield next(it) - g = f() - assert [x for x in g] == [1] - def test_generator_restart(): def g(): i = next(me) @@ -325,12 +300,6 @@ assert set(g) == set() assert set(i for i in range(0)) == set() -def test_explicit_stop_iteration_unpackiterable(): - def f(): - yield 1 - raise StopIteration - assert tuple(f()) == (1,) - def test_exception_is_cleared_by_yield(): def f(): try: @@ -826,34 +795,18 @@ assert isinstance(excinfo.value.__context__, ValueError) -def test_past_generator_stop(): - # how it works without 'from __future__' import generator_stop - def f(x): - raise StopIteration +def test_stopiteration_turned_into_runtime_error(): + def badgenerator(x): + if x == 5: + raise StopIteration yield x - with raises(StopIteration): - next(f(5)) - -def test_future_generator_stop(): - d = {} - exec("""from __future__ import generator_stop - -def f(x): - raise StopIteration - yield x -""", d) - f = d['f'] with raises(RuntimeError): - next(f(5)) + next(badgenerator(5)) def test_generator_stop_cause(): - d = {} - exec("""from __future__ import generator_stop - -def gen1(): - yield 42 -""", d) - my_gen = d['gen1']() + def gen1(): + yield 42 + my_gen = gen1() assert next(my_gen) == 42 stop_exc = StopIteration('spam') with raises(RuntimeError) as e: From pypy.commits at gmail.com Fri Jan 31 09:48:04 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 06:48:04 -0800 (PST) Subject: [pypy-commit] pypy py3.7: kill dead attributes Message-ID: <5e343e24.1c69fb81.e756c.960b@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98614:784f171f4094 Date: 2020-01-31 15:38 +0100 http://bitbucket.org/pypy/pypy/changeset/784f171f4094/ Log: kill dead attributes diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -301,7 +301,6 @@ class GeneratorIterator(GeneratorOrCoroutine): "An iterator created by a generator." KIND = "generator" - KIND_U = u"generator" def descr__iter__(self): """Implement iter(self).""" @@ -348,7 +347,6 @@ class Coroutine(GeneratorOrCoroutine): "A coroutine object." KIND = "coroutine" - KIND_U = u"coroutine" def descr__await__(self, space): return CoroutineWrapper(self) @@ -502,7 +500,6 @@ class AsyncGenerator(GeneratorOrCoroutine): "An async generator (i.e. a coroutine with a 'yield')" KIND = "async generator" - KIND_U = u"async_generator" def __init__(self, frame, name=None, qualname=None): self.hooks_inited = False From pypy.commits at gmail.com Fri Jan 31 14:34:00 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 11:34:00 -0800 (PST) Subject: [pypy-commit] pypy py3.7: implement coroutine origin tracking Message-ID: <5e348128.1c69fb81.98577.4d2b@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98615:5c1dc1c61dcc Date: 2020-01-31 20:28 +0100 http://bitbucket.org/pypy/pypy/changeset/5c1dc1c61dcc/ Log: implement coroutine origin tracking diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -45,6 +45,7 @@ self.w_asyncgen_firstiter_fn = None self.w_asyncgen_finalizer_fn = None self.contextvar_context = None + self.coroutine_origin_tracking_depth = 0 @staticmethod def _mark_thread_disappeared(space): diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -348,17 +348,42 @@ "A coroutine object." KIND = "coroutine" + def __init__(self, frame, name=None, qualname=None): + GeneratorOrCoroutine.__init__(self, frame, name, qualname) + self.w_cr_origin = self.space.w_None + + def capture_origin(self, ec): + if not ec.coroutine_origin_tracking_depth: + return + self._capture_origin(ec) + + def _capture_origin(self, ec): + space = self.space + frames_w = [] + frame = ec.gettopframe_nohidden() + for i in range(ec.coroutine_origin_tracking_depth): + frames_w.append( + space.newtuple([ + frame.pycode.w_filename, + frame.fget_f_lineno(space), + space.newtext(frame.pycode.co_name)])) + frame = ec.getnextframe_nohidden(frame) + if frame is None: + break + self.w_cr_origin = space.newtuple(frames_w) + def descr__await__(self, space): return CoroutineWrapper(self) def _finalize_(self): # If coroutine was never awaited on issue a RuntimeWarning. - if self.pycode is not None and \ - self.frame is not None and \ - self.frame.last_instr == -1: + if (self.pycode is not None and + self.frame is not None and + self.frame.last_instr == -1): space = self.space - msg = "coroutine '%s' was never awaited" % self.get_qualname() - space.warn(space.newtext(msg), space.w_RuntimeWarning) + w_mod = space.getbuiltinmodule("_warnings") + w_f = space.getattr(w_mod, space.newtext("_warn_unawaited_coroutine")) + space.call_function(w_f, self) GeneratorOrCoroutine._finalize_(self) diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -266,6 +266,7 @@ gen = Coroutine(self, name, qualname) ec = space.getexecutioncontext() w_wrapper = ec.w_coroutine_wrapper_fn + gen.capture_origin(ec) elif flags & pycode.CO_ASYNC_GENERATOR: from pypy.interpreter.generator import AsyncGenerator gen = AsyncGenerator(self, name, qualname) diff --git a/pypy/interpreter/test/apptest_coroutine.py b/pypy/interpreter/test/apptest_coroutine.py --- a/pypy/interpreter/test/apptest_coroutine.py +++ b/pypy/interpreter/test/apptest_coroutine.py @@ -840,3 +840,65 @@ assert finalized == 2 finally: sys.set_asyncgen_hooks(*old_hooks) + +def test_coroutine_capture_origin(): + import contextlib + + def here(): + f = sys._getframe().f_back + return (f.f_code.co_filename, f.f_lineno) + + try: + async def corofn(): + pass + + with contextlib.closing(corofn()) as coro: + assert coro.cr_origin is None + + sys.set_coroutine_origin_tracking_depth(1) + + fname, lineno = here() + with contextlib.closing(corofn()) as coro: + print(coro.cr_origin) + assert coro.cr_origin == ( + (fname, lineno + 1, "test_coroutine_capture_origin"),) + + + sys.set_coroutine_origin_tracking_depth(2) + + def nested(): + return (here(), corofn()) + fname, lineno = here() + ((nested_fname, nested_lineno), coro) = nested() + with contextlib.closing(coro): + print(coro.cr_origin) + assert coro.cr_origin == ( + (nested_fname, nested_lineno, "nested"), + (fname, lineno + 1, "test_coroutine_capture_origin")) + + # Check we handle running out of frames correctly + sys.set_coroutine_origin_tracking_depth(1000) + with contextlib.closing(corofn()) as coro: + print(coro.cr_origin) + assert 1 <= len(coro.cr_origin) < 1000 + finally: + sys.set_coroutine_origin_tracking_depth(0) + +def test_runtime_warning_origin_tracking(): + import gc, warnings # XXX: importing warnings is expensive untranslated + async def foobaz(): + pass + gc.collect() # emit warnings from unrelated older tests + with warnings.catch_warnings(record=True) as l: + foobaz() + gc.collect() + gc.collect() + gc.collect() + + assert len(l) == 1, repr(l) + w = l[0].message + assert isinstance(w, RuntimeWarning) + assert str(w).startswith("coroutine ") + assert str(w).endswith("foobaz' was never awaited") + assert "test_runtime_warning_origin_tracking" in str(w) + diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -865,6 +865,7 @@ cr_frame = GetSetProperty(Coroutine.descr_gicr_frame), cr_code = interp_attrproperty_w('pycode', cls=Coroutine), cr_await=GetSetProperty(Coroutine.descr_delegate), + cr_origin = interp_attrproperty_w('w_cr_origin', cls=Coroutine), __name__ = GetSetProperty(Coroutine.descr__name__, Coroutine.descr_set__name__, doc="name of the coroutine"), diff --git a/pypy/module/_warnings/app_warnings.py b/pypy/module/_warnings/app_warnings.py new file mode 100644 --- /dev/null +++ b/pypy/module/_warnings/app_warnings.py @@ -0,0 +1,15 @@ +def _warn_unawaited_coroutine(coro): + from _warnings import warn + msg_lines = [ + f"coroutine '{coro.__qualname__}' was never awaited\n" + ] + if coro.cr_origin is not None: + import linecache, traceback + def extract(): + for filename, lineno, funcname in reversed(coro.cr_origin): + line = linecache.getline(filename, lineno) + yield (filename, lineno, funcname, line) + msg_lines.append("Coroutine created at (most recent call last)\n") + msg_lines += traceback.format_list(list(extract())) + msg = "".join(msg_lines).rstrip("\n") + warn(msg, category=RuntimeWarning, stacklevel=2, source=coro) diff --git a/pypy/module/_warnings/moduledef.py b/pypy/module/_warnings/moduledef.py --- a/pypy/module/_warnings/moduledef.py +++ b/pypy/module/_warnings/moduledef.py @@ -11,6 +11,7 @@ } appleveldefs = { + '_warn_unawaited_coroutine' : 'app_warnings._warn_unawaited_coroutine', } def setup_after_space_initialization(self): diff --git a/pypy/module/sys/moduledef.py b/pypy/module/sys/moduledef.py --- a/pypy/module/sys/moduledef.py +++ b/pypy/module/sys/moduledef.py @@ -100,6 +100,9 @@ 'set_asyncgen_hooks' : 'vm.set_asyncgen_hooks', 'is_finalizing' : 'vm.is_finalizing', + + 'get_coroutine_origin_tracking_depth': 'vm.get_coroutine_origin_tracking_depth', + 'set_coroutine_origin_tracking_depth': 'vm.set_coroutine_origin_tracking_depth', } if sys.platform == 'win32': diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py --- a/pypy/module/sys/test/test_sysmodule.py +++ b/pypy/module/sys/test/test_sysmodule.py @@ -812,6 +812,20 @@ assert cur.firstiter is None assert cur.finalizer is None + def test_coroutine_origin_tracking_depth(self): + import sys + depth = sys.get_coroutine_origin_tracking_depth() + assert depth == 0 + try: + sys.set_coroutine_origin_tracking_depth(6) + depth = sys.get_coroutine_origin_tracking_depth() + assert depth == 6 + with raises(ValueError): + sys.set_coroutine_origin_tracking_depth(-5) + finally: + sys.set_coroutine_origin_tracking_depth(0) + + class AppTestSysSettracePortedFromCpython(object): def test_sys_settrace(self): diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -402,3 +402,26 @@ def is_finalizing(space): return space.newbool(space.sys.finalizing) + +def get_coroutine_origin_tracking_depth(space): + """get_coroutine_origin_tracking_depth() + Check status of origin tracking for coroutine objects in this thread. + """ + ec = space.getexecutioncontext() + return space.newint(ec.coroutine_origin_tracking_depth) + + at unwrap_spec(depth=int) +def set_coroutine_origin_tracking_depth(space, depth): + """set_coroutine_origin_tracking_depth(depth) + Enable or disable origin tracking for coroutine objects in this thread. + + Coroutine objects will track 'depth' frames of traceback information + about where they came from, available in their cr_origin attribute. + + Set a depth of 0 to disable. + """ + if depth < 0: + raise oefmt(space.w_ValueError, + "depth must be >= 0") + ec = space.getexecutioncontext() + ec.coroutine_origin_tracking_depth = depth From pypy.commits at gmail.com Fri Jan 31 16:48:43 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 13:48:43 -0800 (PST) Subject: [pypy-commit] pypy py3.7: fix error msg Message-ID: <5e34a0bb.1c69fb81.e756c.0e75@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98619:4e018a19da74 Date: 2020-01-31 22:31 +0100 http://bitbucket.org/pypy/pypy/changeset/4e018a19da74/ Log: fix error msg diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -598,6 +598,8 @@ left, right = specialnames op = getattr(operator, left) def comparison_impl(space, w_obj1, w_obj2): + w_orig_obj1 = w_obj1 + w_orig_obj2 = w_obj2 w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) @@ -637,7 +639,7 @@ # if we arrived here, they are unorderable raise oefmt(space.w_TypeError, "'%s' not supported between instances of '%T' and '%T'", - symbol, w_obj1, w_obj2) + symbol, w_orig_obj1, w_orig_obj2) return func_with_new_name(comparison_impl, 'comparison_%s_impl'%left.strip('_')) diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -343,6 +343,19 @@ raises(TypeError, "0.0 < zz()") raises(TypeError, "0j < zz()") + def test_correct_order_error_msg(self): + class A(object): + def __lt__(self, other): + return NotImplemented + __gt__ = __lt__ + + class B(A): + pass + + with raises(TypeError) as e: + A() < B() + assert str(e.value) == "'<' not supported between instances of 'A' and 'B'" + def test_equality_among_different_types(self): class A(object): pass class zz(object): pass From pypy.commits at gmail.com Fri Jan 31 16:48:12 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 13:48:12 -0800 (PST) Subject: [pypy-commit] pypy py3.7: we happily pass these... Message-ID: <5e34a09c.1c69fb81.1361c.d338@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98618:bf0519b39ac6 Date: 2020-01-31 22:11 +0100 http://bitbucket.org/pypy/pypy/changeset/bf0519b39ac6/ Log: we happily pass these... diff --git a/lib-python/3/test/test_sys_settrace.py b/lib-python/3/test/test_sys_settrace.py --- a/lib-python/3/test/test_sys_settrace.py +++ b/lib-python/3/test/test_sys_settrace.py @@ -473,7 +473,6 @@ return Tracer(trace_line_events=False) - at support.cpython_only class TraceOpcodesTestCase(TraceTestCase): """Repeat the trace tests, but with per-opcodes events enabled""" From pypy.commits at gmail.com Fri Jan 31 16:48:09 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 13:48:09 -0800 (PST) Subject: [pypy-commit] pypy py3.7: implement opcode tracing, make it possible to turn off line tracing Message-ID: <5e34a099.1c69fb81.725dc.97ef@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98617:e446a354c3d0 Date: 2020-01-31 22:04 +0100 http://bitbucket.org/pypy/pypy/changeset/e446a354c3d0/ Log: implement opcode tracing, make it possible to turn off line tracing diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -183,7 +183,8 @@ if d.instr_lb <= frame.last_instr < d.instr_ub: if frame.last_instr < d.instr_prev_plus_one: # We jumped backwards in the same line. - self._trace(frame, 'line', self.space.w_None) + if d.f_trace_lines: + self._trace(frame, 'line', self.space.w_None) else: size = len(code.co_lnotab) / 2 addr = 0 @@ -219,7 +220,10 @@ if d.instr_lb == frame.last_instr: # At start of line! d.f_lineno = line - self._trace(frame, 'line', self.space.w_None) + if d.f_trace_lines: + self._trace(frame, 'line', self.space.w_None) + if d.f_trace_opcodes: + self._trace(frame, 'opcode', self.space.w_None) d.instr_prev_plus_one = frame.last_instr + 1 diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -36,6 +36,8 @@ f_lineno = 0 # current lineno for tracing is_being_profiled = False is_in_line_tracing = False + f_trace_lines = True + f_trace_opcodes = False w_locals = None hidden_operationerr = None @@ -148,6 +150,18 @@ return None return d.w_locals + def get_f_trace_lines(self): + d = self.getdebug() + if d is None: + return True + return d.f_trace_lines + + def get_f_trace_opcodes(self): + d = self.getdebug() + if d is None: + return False + return d.f_trace_opcodes + @not_rpython def __repr__(self): # useful in tracebacks @@ -898,10 +912,17 @@ def fdel_f_trace(self, space): self.getorcreatedebug().w_f_trace = None - def fget_f_restricted(self, space): - if space.config.objspace.honor__builtins__: - return space.newbool(self.builtin is not space.builtin) - return space.w_False + def fget_f_trace_lines(self, space): + return space.newbool(self.get_f_trace_lines()) + + def fset_f_trace_lines(self, space, w_trace): + self.getorcreatedebug().f_trace_lines = space.is_true(w_trace) + + def fget_f_trace_opcodes(self, space): + return space.newbool(self.get_f_trace_opcodes()) + + def fset_f_trace_opcodes(self, space, w_trace): + self.getorcreatedebug().f_trace_opcodes = space.is_true(w_trace) def get_generator(self): if self.space.config.translation.rweakref: diff --git a/pypy/interpreter/test/apptest_pyframe.py b/pypy/interpreter/test/apptest_pyframe.py --- a/pypy/interpreter/test/apptest_pyframe.py +++ b/pypy/interpreter/test/apptest_pyframe.py @@ -584,6 +584,63 @@ sys.settrace(None) assert res == 10 +def test_disable_line_tracing(): + import sys + assert sys._getframe().f_trace_lines + + l = [] + def trace(frame, event, arg): + l.append((frame.f_code.co_name, event, arg, frame.f_lineno - frame.f_code.co_firstlineno)) + frame.f_trace_lines = False + return trace + def g(n): + return n + 2 + def f(n): + n = g(n) + return n * 7 + sys.settrace(trace) + x = f(4) + sys.settrace(None) + print(l) + assert l == [('f', 'call', None, 0), ('g', 'call', None, 0), ('g', 'return', 6, 1), ('f', 'return', 42, 2)] + +test_disable_line_tracing() + +def test_opcode_tracing(): + import sys + assert not sys._getframe().f_trace_opcodes + + l = [] + def trace(frame, event, arg): + l.append((frame.f_code.co_name, event, arg, frame.f_lasti, frame.f_lineno - frame.f_code.co_firstlineno)) + frame.f_trace_opcodes = True + return trace + def g(n): + return n + 2 + def f(n): + return g(n) + sys.settrace(trace) + x = f(4) + sys.settrace(None) + print(l) + assert l == [ + ('f', 'call', None, -1, 0), + ('f', 'line', None, 0, 1), + ('f', 'opcode', None, 0, 1), + ('f', 'opcode', None, 2, 1), + ('f', 'opcode', None, 4, 1), + ('g', 'call', None, -1, 0), + ('g', 'line', None, 0, 1), + ('g', 'opcode', None, 0, 1), + ('g', 'opcode', None, 2, 1), + ('g', 'opcode', None, 4, 1), + ('g', 'opcode', None, 6, 1), + ('g', 'return', 6, 6, 1), + ('f', 'opcode', None, 6, 1), + ('f', 'return', 6, 6, 1)] + +test_opcode_tracing() + def test_preserve_exc_state_in_generators(): import sys def yield_raise(): diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -654,7 +654,8 @@ f_lasti = GetSetProperty(PyFrame.fget_f_lasti), f_trace = GetSetProperty(PyFrame.fget_f_trace, PyFrame.fset_f_trace, PyFrame.fdel_f_trace), - f_restricted = GetSetProperty(PyFrame.fget_f_restricted), + f_trace_lines = GetSetProperty(PyFrame.fget_f_trace_lines, PyFrame.fset_f_trace_lines), + f_trace_opcodes = GetSetProperty(PyFrame.fget_f_trace_opcodes, PyFrame.fset_f_trace_opcodes), f_code = GetSetProperty(PyFrame.fget_code), f_locals = GetSetProperty(PyFrame.fget_getdictscope), f_globals = GetSetProperty(PyFrame.fget_w_globals), From pypy.commits at gmail.com Fri Jan 31 16:48:46 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 13:48:46 -0800 (PST) Subject: [pypy-commit] pypy py3.7: slight variant in error msg Message-ID: <5e34a0be.1c69fb81.1cea4.e491@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98620:8d3b5e787554 Date: 2020-01-31 22:33 +0100 http://bitbucket.org/pypy/pypy/changeset/8d3b5e787554/ Log: slight variant in error msg diff --git a/lib-python/3/test/test_dataclasses.py b/lib-python/3/test/test_dataclasses.py --- a/lib-python/3/test/test_dataclasses.py +++ b/lib-python/3/test/test_dataclasses.py @@ -3015,7 +3015,7 @@ lambda x:x, ]: with self.subTest(bad_field=bad_field): - with self.assertRaisesRegex(TypeError, r'has no len\(\)'): + with self.assertRaisesRegex(TypeError, r'has no len.*'): make_dataclass('C', ['a', bad_field]) def test_duplicate_field_names(self): From pypy.commits at gmail.com Fri Jan 31 16:48:06 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 13:48:06 -0800 (PST) Subject: [pypy-commit] pypy py3.7: skip cpython only test Message-ID: <5e34a096.1c69fb81.f2543.a7d3@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98616:98cbf9a6e204 Date: 2020-01-31 21:22 +0100 http://bitbucket.org/pypy/pypy/changeset/98cbf9a6e204/ Log: skip cpython only test diff --git a/lib-python/3/test/test_coroutines.py b/lib-python/3/test/test_coroutines.py --- a/lib-python/3/test/test_coroutines.py +++ b/lib-python/3/test/test_coroutines.py @@ -2276,6 +2276,7 @@ finally: sys.set_coroutine_origin_tracking_depth(orig_depth) + @support.cpython_only # pypy has this function in _warnings def test_unawaited_warning_when_module_broken(self): # Make sure we don't blow up too bad if # warnings._warn_unawaited_coroutine is broken somehow (e.g. because From pypy.commits at gmail.com Fri Jan 31 17:02:21 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 14:02:21 -0800 (PST) Subject: [pypy-commit] pypy py3.7: skip an implementation detail Message-ID: <5e34a3ed.1c69fb81.ccdc8.87d7@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98621:cd4e6f012629 Date: 2020-01-31 22:52 +0100 http://bitbucket.org/pypy/pypy/changeset/cd4e6f012629/ Log: skip an implementation detail diff --git a/lib-python/3/test/test_types.py b/lib-python/3/test/test_types.py --- a/lib-python/3/test/test_types.py +++ b/lib-python/3/test/test_types.py @@ -590,6 +590,7 @@ self.assertIsInstance(object().__lt__, types.MethodWrapperType) self.assertIsInstance((42).__lt__, types.MethodWrapperType) + @impl_detail def test_method_descriptor_types(self): self.assertIsInstance(str.join, types.MethodDescriptorType) self.assertIsInstance(list.append, types.MethodDescriptorType) From pypy.commits at gmail.com Fri Jan 31 17:02:23 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 14:02:23 -0800 (PST) Subject: [pypy-commit] pypy py3.7: gah! turning StopIteration to RuntimeError in generators broke the applevel Message-ID: <5e34a3ef.1c69fb81.d8ebe.cc77@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98622:7a0cdcf24b94 Date: 2020-01-31 23:01 +0100 http://bitbucket.org/pypy/pypy/changeset/7a0cdcf24b94/ Log: gah! turning StopIteration to RuntimeError in generators broke the applevel implementation of iter with sentinel! diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -163,6 +163,7 @@ self.frame.w_yielding_from = w_delegate def _leak_stopiteration(self, e): + import pdb; pdb.set_trace() # turn a leaking StopIteration into RuntimeError (with its cause set # appropriately). space = self.space diff --git a/pypy/interpreter/test/apptest_generator.py b/pypy/interpreter/test/apptest_generator.py --- a/pypy/interpreter/test/apptest_generator.py +++ b/pypy/interpreter/test/apptest_generator.py @@ -803,6 +803,21 @@ with raises(RuntimeError): next(badgenerator(5)) +def test_stopiteration_can_be_caught(): + def g(): + raise StopIteration + def finegenerator(x): + yield x + if x == 5: + try: + g() + except StopIteration: + pass + yield x + gen = finegenerator(5) + next(gen) # fine + next(gen) # fine + def test_generator_stop_cause(): def gen1(): yield 42 diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -126,7 +126,10 @@ def iter_generator(callable_, sentinel): while 1: - result = callable_() + try: + result = callable_() + except StopIteration: + return if result == sentinel: return yield result diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py --- a/pypy/module/__builtin__/test/test_builtin.py +++ b/pypy/module/__builtin__/test/test_builtin.py @@ -286,17 +286,20 @@ self.value = 0 def __call__(self): self.value += 1 + if self.value > 10: + raise StopIteration return self.value - # XXX Raising errors is quite slow -- - # uncomment these lines when fixed - #self.assertRaises(TypeError,iter,3,5) - #self.assertRaises(TypeError,iter,[],5) - #self.assertRaises(TypeError,iter,{},5) + with raises(TypeError): + iter(3, 5) + x = iter(count(),3) assert next(x) ==1 assert next(x) ==2 raises(StopIteration, next, x) + # a case that runs till the end + assert list(iter(count(), 100)) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + def test_enumerate(self): import sys seq = range(2,4) From pypy.commits at gmail.com Fri Jan 31 17:30:16 2020 From: pypy.commits at gmail.com (cfbolz) Date: Fri, 31 Jan 2020 14:30:16 -0800 (PST) Subject: [pypy-commit] pypy py3.7: make putenv complain about bad names (test already existed) Message-ID: <5e34aa78.1c69fb81.fc43d.cb31@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98624:89255ed57e9f Date: 2020-01-31 23:29 +0100 http://bitbucket.org/pypy/pypy/changeset/89255ed57e9f/ Log: make putenv complain about bad names (test already existed) diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -935,9 +935,21 @@ def putenv(space, w_name, w_value): """Change or add an environment variable.""" try: - dispatch_filename_2(rposix.putenv)(space, w_name, w_value) + dispatch_filename_2(putenv_impl)(space, w_name, w_value) except OSError as e: raise wrap_oserror(space, e, eintr_retry=False) + except ValueError: + raise oefmt(space.w_ValueError, + "illegal environment variable name") + + @specialize.argtype(0, 1) + def putenv_impl(name, value): + from rpython.rlib.rposix import _as_bytes + name = _as_bytes(name) + value = _as_bytes(value) + if "=" in name: + raise ValueError + return rposix.putenv(name, value) def unsetenv(space, w_name): """Delete an environment variable."""