Cygwin: tzcode resync: details

Add tz_posixrules.h with data generated from most recent Cygwin tzdata
package.  Establish localtime.cc as primarily a wrapper around a patched
copy of localtime.c.  See README for more information.
This commit is contained in:
Mark Geisert 2020-05-22 02:32:53 -07:00 committed by Corinna Vinschen
parent 2452e0b806
commit 63ff2b84ff
4 changed files with 486 additions and 0 deletions

View File

@ -0,0 +1,37 @@
/*
How the code in this directory is supposed to work...
2020/05/22 Mark Geisert <mark@maxrnd.com>
localtime.cc is the Cygwin-specific module that is compiled into
the Cygwin DLL when the latter is built. It's just a wrapper that
#defines a bunch of stuff then #includes localtime.c.
localtime.c, at any point in time, is a reasonably recent version
of /src/lib/libc/time/localtime.c from NetBSD. The same goes for
private.h and tzfile.h. An empty namespace.h suffices for Cygwin.
The idea is that in the future, one just needs to bring over newer
versions of localtime.c, private.h, and/or tzfile.h from NetBSD as
they become available.
With luck, you can drop those files into this directory and they
can be immediately used to build a newer Cygwin DLL that has the
newer NetBSD functionality. Without luck, you'll have to tweak the
wrapper localtime.cc. In the worst case, some other strategy will
need to be figured out, such as manually pulling out the parts of
the NetBSD code Cygwin needs to build a stand-alone localtime.cc.
Re tz_posixrules.h: The data elements can be generated from
/usr/share/zoneinfo/posixrules in any version of Cygwin's tzdata
package. Instructions are in the comment leading tz_posixrules.h.
Addendum:
Implementation of the strategy above has uncovered a small number
of NetBSD-isms in localtime.c that cannot be worked around with
preprocessor tricks. So there is another file localtime.c.patched
that holds just these adjustments for Cygwin, and it's this file
that localtime.cc #includes. localtime.c.patched is generated by
winsup/cygwin/Makefile[.in] operating with localtime.c.patch.
..mark
*/

View File

@ -0,0 +1,59 @@
--- localtime.c 2020-05-16 21:54:00.533111800 -0700
+++ localtime.c.patched 2020-05-22 00:03:30.826646000 -0700
@@ -413,7 +413,7 @@
};
/* TZDIR with a trailing '/' rather than a trailing '\0'. */
-static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
+static char const tzdirslash[sizeof TZDIR + 1] = TZDIR "/";
/* Local storage needed for 'tzloadbody'. */
union local_storage {
@@ -473,7 +473,7 @@
would pull in stdio (and would fail if the
resulting string length exceeded INT_MAX!). */
memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
- strcpy(lsp->fullname + sizeof tzdirslash, name);
+ strcpy(lsp->fullname + sizeof tzdirslash - 1, name);
/* Set doaccess if NAME contains a ".." file name
component, as such a name could read a file outside
@@ -488,11 +488,11 @@
name = lsp->fullname;
}
if (doaccess && access(name, R_OK) != 0)
- return errno;
+ goto trydefrules;
fid = open(name, OPEN_MODE);
if (fid < 0)
- return errno;
+ goto trydefrules;
nread = read(fid, up->buf, sizeof up->buf);
if (nread < (ssize_t)tzheadsize) {
int err = nread < 0 ? errno : EINVAL;
@@ -501,6 +501,15 @@
}
if (close(fid) < 0)
return errno;
+ if (0) {
+trydefrules:
+ const char *base = strrchr(name, '/');
+ base = base ? base + 1 : name;
+ if (strcmp(base, TZDEFRULES))
+ return errno;
+ nread = sizeof _posixrules_data;
+ memcpy(up->buf, _posixrules_data, nread);
+ }
for (stored = 4; stored <= 8; stored *= 2) {
int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
@@ -1417,6 +1426,8 @@
tzsetlcl(char const *name)
{
struct state *sp = __lclptr;
+ if (! name)
+ name = tzgetwintzi(__UNCONST(wildabbr), (char *) alloca (512));
int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
if (lcl < 0 ? lcl_is_set < 0
: 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)

View File

@ -0,0 +1,159 @@
/* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "../winsup.h"
#include "../sync.h"
#include "../include/cygwin/version.h"
#include "tz_posixrules.h"
static NO_COPY muto tzset_guard;
// Convert these NetBSD rwlock ops into Cygwin muto ops
#define rwlock_wrlock(X) tzset_guard.init("tzset_guard")->acquire()
#define rwlock_unlock(X) tzset_guard.release()
// Set these NetBSD-related option #defines appropriately for Cygwin
//#define STD_INSPIRED // early-include private.h below does this
#define lint
#define HAVE_POSIX_DECLS 0
#define USG_COMPAT 1
#define NO_ERROR_IN_DST_GAP
#define state __state
// Turn a specific known kind of const parameter into non-const
#define __UNCONST(X) ((char *) (X))
// Turn off these NetBSD audit-related definitions
#define __aconst
#define _DIAGASSERT(X)
// Supply this Cygwin-specific function in advance of its use in localtime.c
static char *
tzgetwintzi (char *wildabbr, char *outbuf)
{
TIME_ZONE_INFORMATION tzi;
char *cp, *dst;
wchar_t *wsrc;
div_t d;
GetTimeZoneInformation (&tzi);
dst = cp = outbuf;
for (wsrc = tzi.StandardName; *wsrc; wsrc++)
if (*wsrc >= L'A' && *wsrc <= L'Z')
*dst++ = *wsrc;
if ((dst - cp) < 3)
{
/* In non-english Windows, converted tz.StandardName
may not contain a valid standard timezone name. */
strcpy (cp, wildabbr);
cp += strlen (wildabbr);
}
else
cp = dst;
d = div (tzi.Bias + tzi.StandardBias, 60);
__small_sprintf (cp, "%d", d.quot);
if (d.rem)
__small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
if (tzi.StandardDate.wMonth)
{
cp = strchr (cp, 0);
dst = cp;
for (wsrc = tzi.DaylightName; *wsrc; wsrc++)
if (*wsrc >= L'A' && *wsrc <= L'Z')
*dst++ = *wsrc;
if ((dst - cp) < 3)
{
/* In non-english Windows, converted tz.DaylightName
may not contain a valid daylight timezone name. */
strcpy (cp, wildabbr);
cp += strlen (wildabbr);
}
else
cp = dst;
d = div (tzi.Bias + tzi.DaylightBias, 60);
__small_sprintf (cp, "%d", d.quot);
if (d.rem)
__small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
cp = strchr (cp, 0);
__small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
tzi.DaylightDate.wMonth,
tzi.DaylightDate.wDay,
tzi.DaylightDate.wDayOfWeek,
tzi.DaylightDate.wHour);
if (tzi.DaylightDate.wMinute || tzi.DaylightDate.wSecond)
__small_sprintf (cp = strchr (cp, 0), ":%d",
tzi.DaylightDate.wMinute);
if (tzi.DaylightDate.wSecond)
__small_sprintf (cp = strchr (cp, 0), ":%d",
tzi.DaylightDate.wSecond);
cp = strchr (cp, 0);
__small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
tzi.StandardDate.wMonth,
tzi.StandardDate.wDay,
tzi.StandardDate.wDayOfWeek,
tzi.StandardDate.wHour);
if (tzi.StandardDate.wMinute || tzi.StandardDate.wSecond)
__small_sprintf (cp = strchr (cp, 0), ":%d",
tzi.StandardDate.wMinute);
if (tzi.StandardDate.wSecond)
__small_sprintf (cp = strchr (cp, 0), ":%d",
tzi.StandardDate.wSecond);
}
/* __small_printf ("TZ deduced as `%s'\n", outbuf); */
return outbuf;
}
// Get ready to wrap NetBSD's localtime.c
#ifdef __cplusplus
extern "C" {
#endif
// Pull these in early to catch any small issues before the real test
#include "private.h"
#include "tzfile.h"
/* Some NetBSD differences were too difficult to work around..
so #include a patched copy of localtime.c rather than the NetBSD original.
Here is a list of the patches...
(1) fix an erroneous decl of tzdirslash size (flagged by g++)
(2) add conditional call to Cygwin's tzgetwintzi() from tzsetlcl()
(3) add Cygwin's historical "posixrules" support to tzloadbody()
*/
#include "localtime.c.patched"
#ifdef __cplusplus
}
#endif
// Don't forget these Cygwin-specific additions from this point to EOF
EXPORT_ALIAS (tzset_unlocked, _tzset_unlocked)
extern "C" long
__cygwin_gettzoffset (const struct tm *tmp)
{
#ifdef TM_GMTOFF
if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
return tmp->TM_GMTOFF;
#endif /* defined TM_GMTOFF */
__tzinfo_type *tz = __gettzinfo ();
/* The sign of this is exactly opposite the envvar TZ. We
could directly use the global _timezone for tm_isdst==0,
but have to use __tzrule for daylight savings. */
long offset = -tz->__tzrule[tmp->tm_isdst > 0].offset;
return offset;
}
extern "C" const char *
__cygwin_gettzname (const struct tm *tmp)
{
#ifdef TM_ZONE
if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
return tmp->TM_ZONE;
#endif
return _tzname[tmp->tm_isdst > 0];
}

View File

@ -0,0 +1,231 @@
/* tz_posixrules.h
*
* The data elements were generated with...
* od -vt u1 -A n /usr/share/zoneinfo/posixrules |
* sed 's/$/,/;s/^ //;s/[0-9] /&,/g;s/ ,/, /g' > elements_file
*
* The source posixrules file is from the Cygwin tzdata 2020a-1 package.
*/
static NO_COPY unsigned char _posixrules_data[] = {
84, 90, 105, 102, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0,
0, 0, 0, 236, 0, 0, 0, 5, 0, 0, 0, 20, 128, 0, 0, 0,
158, 166, 30, 112, 159, 186, 235, 96, 160, 134, 0, 112, 161, 154, 205, 96,
162, 101, 226, 112, 163, 131, 233, 224, 164, 106, 174, 112, 165, 53, 167, 96,
166, 83, 202, 240, 167, 21, 137, 96, 168, 51, 172, 240, 168, 254, 165, 224,
170, 19, 142, 240, 170, 222, 135, 224, 171, 243, 112, 240, 172, 190, 105, 224,
173, 211, 82, 240, 174, 158, 75, 224, 175, 179, 52, 240, 176, 126, 45, 224,
177, 156, 81, 112, 178, 103, 74, 96, 179, 124, 51, 112, 180, 71, 44, 96,
181, 92, 21, 112, 182, 39, 14, 96, 183, 59, 247, 112, 184, 6, 240, 96,
185, 27, 217, 112, 185, 230, 210, 96, 187, 4, 245, 240, 187, 198, 180, 96,
188, 228, 215, 240, 189, 175, 208, 224, 190, 196, 185, 240, 191, 143, 178, 224,
192, 164, 155, 240, 193, 111, 148, 224, 194, 132, 125, 240, 195, 79, 118, 224,
196, 100, 95, 240, 197, 47, 88, 224, 198, 77, 124, 112, 199, 15, 58, 224,
200, 45, 94, 112, 200, 248, 87, 96, 202, 13, 64, 112, 202, 216, 57, 96,
203, 136, 240, 112, 210, 35, 244, 112, 210, 96, 251, 224, 211, 117, 228, 240,
212, 64, 221, 224, 213, 85, 198, 240, 214, 32, 191, 224, 215, 53, 168, 240,
216, 0, 161, 224, 217, 21, 138, 240, 217, 224, 131, 224, 218, 254, 167, 112,
219, 192, 101, 224, 220, 222, 137, 112, 221, 169, 130, 96, 222, 190, 107, 112,
223, 137, 100, 96, 224, 158, 77, 112, 225, 105, 70, 96, 226, 126, 47, 112,
227, 73, 40, 96, 228, 94, 17, 112, 229, 87, 46, 224, 230, 71, 45, 240,
231, 55, 16, 224, 232, 39, 15, 240, 233, 22, 242, 224, 234, 6, 241, 240,
234, 246, 212, 224, 235, 230, 211, 240, 236, 214, 182, 224, 237, 198, 181, 240,
238, 191, 211, 96, 239, 175, 210, 112, 240, 159, 181, 96, 241, 143, 180, 112,
242, 127, 151, 96, 243, 111, 150, 112, 244, 95, 121, 96, 245, 79, 120, 112,
246, 63, 91, 96, 247, 47, 90, 112, 248, 40, 119, 224, 249, 15, 60, 112,
250, 8, 89, 224, 250, 248, 88, 240, 251, 232, 59, 224, 252, 216, 58, 240,
253, 200, 29, 224, 254, 184, 28, 240, 255, 167, 255, 224, 0, 151, 254, 240,
1, 135, 225, 224, 2, 119, 224, 240, 3, 112, 254, 96, 4, 96, 253, 112,
5, 80, 224, 96, 6, 64, 223, 112, 7, 48, 194, 96, 7, 141, 25, 112,
9, 16, 164, 96, 9, 173, 148, 240, 10, 240, 134, 96, 11, 224, 133, 112,
12, 217, 162, 224, 13, 192, 103, 112, 14, 185, 132, 224, 15, 169, 131, 240,
16, 153, 102, 224, 17, 137, 101, 240, 18, 121, 72, 224, 19, 105, 71, 240,
20, 89, 42, 224, 21, 73, 41, 240, 22, 57, 12, 224, 23, 41, 11, 240,
24, 34, 41, 96, 25, 8, 237, 240, 26, 2, 11, 96, 26, 242, 10, 112,
27, 225, 237, 96, 28, 209, 236, 112, 29, 193, 207, 96, 30, 177, 206, 112,
31, 161, 177, 96, 32, 118, 0, 240, 33, 129, 147, 96, 34, 85, 226, 240,
35, 106, 175, 224, 36, 53, 196, 240, 37, 74, 145, 224, 38, 21, 166, 240,
39, 42, 115, 224, 39, 254, 195, 112, 41, 10, 85, 224, 41, 222, 165, 112,
42, 234, 55, 224, 43, 190, 135, 112, 44, 211, 84, 96, 45, 158, 105, 112,
46, 179, 54, 96, 47, 126, 75, 112, 48, 147, 24, 96, 49, 103, 103, 240,
50, 114, 250, 96, 51, 71, 73, 240, 52, 82, 220, 96, 53, 39, 43, 240,
54, 50, 190, 96, 55, 7, 13, 240, 56, 27, 218, 224, 56, 230, 239, 240,
57, 251, 188, 224, 58, 198, 209, 240, 59, 219, 158, 224, 60, 175, 238, 112,
61, 187, 128, 224, 62, 143, 208, 112, 63, 155, 98, 224, 64, 111, 178, 112,
65, 132, 127, 96, 66, 79, 148, 112, 67, 100, 97, 96, 68, 47, 118, 112,
69, 68, 67, 96, 69, 243, 168, 240, 71, 45, 95, 224, 71, 211, 138, 240,
73, 13, 65, 224, 73, 179, 108, 240, 74, 237, 35, 224, 75, 156, 137, 112,
76, 214, 64, 96, 77, 124, 107, 112, 78, 182, 34, 96, 79, 92, 77, 112,
80, 150, 4, 96, 81, 60, 47, 112, 82, 117, 230, 96, 83, 28, 17, 112,
84, 85, 200, 96, 84, 251, 243, 112, 86, 53, 170, 96, 86, 229, 15, 240,
88, 30, 198, 224, 88, 196, 241, 240, 89, 254, 168, 224, 90, 164, 211, 240,
91, 222, 138, 224, 92, 132, 181, 240, 93, 190, 108, 224, 94, 100, 151, 240,
95, 158, 78, 224, 96, 77, 180, 112, 97, 135, 107, 96, 98, 45, 150, 112,
99, 103, 77, 96, 100, 13, 120, 112, 101, 71, 47, 96, 101, 237, 90, 112,
103, 39, 17, 96, 103, 205, 60, 112, 105, 6, 243, 96, 105, 173, 30, 112,
106, 230, 213, 96, 107, 150, 58, 240, 108, 207, 241, 224, 109, 118, 28, 240,
110, 175, 211, 224, 111, 85, 254, 240, 112, 143, 181, 224, 113, 53, 224, 240,
114, 111, 151, 224, 115, 21, 194, 240, 116, 79, 121, 224, 116, 254, 223, 112,
118, 56, 150, 96, 118, 222, 193, 112, 120, 24, 120, 96, 120, 190, 163, 112,
121, 248, 90, 96, 122, 158, 133, 112, 123, 216, 60, 96, 124, 126, 103, 112,
125, 184, 30, 96, 126, 94, 73, 112, 127, 152, 0, 96, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 255, 255, 186, 158, 0, 0, 255, 255,
199, 192, 1, 4, 255, 255, 185, 176, 0, 8, 255, 255, 199, 192, 1, 12,
255, 255, 199, 192, 1, 16, 76, 77, 84, 0, 69, 68, 84, 0, 69, 83,
84, 0, 69, 87, 84, 0, 69, 80, 84, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 84, 90, 105, 102, 50, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5,
0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 5, 0, 0, 0, 20,
255, 255, 255, 255, 94, 3, 240, 144, 255, 255, 255, 255, 158, 166, 30, 112,
255, 255, 255, 255, 159, 186, 235, 96, 255, 255, 255, 255, 160, 134, 0, 112,
255, 255, 255, 255, 161, 154, 205, 96, 255, 255, 255, 255, 162, 101, 226, 112,
255, 255, 255, 255, 163, 131, 233, 224, 255, 255, 255, 255, 164, 106, 174, 112,
255, 255, 255, 255, 165, 53, 167, 96, 255, 255, 255, 255, 166, 83, 202, 240,
255, 255, 255, 255, 167, 21, 137, 96, 255, 255, 255, 255, 168, 51, 172, 240,
255, 255, 255, 255, 168, 254, 165, 224, 255, 255, 255, 255, 170, 19, 142, 240,
255, 255, 255, 255, 170, 222, 135, 224, 255, 255, 255, 255, 171, 243, 112, 240,
255, 255, 255, 255, 172, 190, 105, 224, 255, 255, 255, 255, 173, 211, 82, 240,
255, 255, 255, 255, 174, 158, 75, 224, 255, 255, 255, 255, 175, 179, 52, 240,
255, 255, 255, 255, 176, 126, 45, 224, 255, 255, 255, 255, 177, 156, 81, 112,
255, 255, 255, 255, 178, 103, 74, 96, 255, 255, 255, 255, 179, 124, 51, 112,
255, 255, 255, 255, 180, 71, 44, 96, 255, 255, 255, 255, 181, 92, 21, 112,
255, 255, 255, 255, 182, 39, 14, 96, 255, 255, 255, 255, 183, 59, 247, 112,
255, 255, 255, 255, 184, 6, 240, 96, 255, 255, 255, 255, 185, 27, 217, 112,
255, 255, 255, 255, 185, 230, 210, 96, 255, 255, 255, 255, 187, 4, 245, 240,
255, 255, 255, 255, 187, 198, 180, 96, 255, 255, 255, 255, 188, 228, 215, 240,
255, 255, 255, 255, 189, 175, 208, 224, 255, 255, 255, 255, 190, 196, 185, 240,
255, 255, 255, 255, 191, 143, 178, 224, 255, 255, 255, 255, 192, 164, 155, 240,
255, 255, 255, 255, 193, 111, 148, 224, 255, 255, 255, 255, 194, 132, 125, 240,
255, 255, 255, 255, 195, 79, 118, 224, 255, 255, 255, 255, 196, 100, 95, 240,
255, 255, 255, 255, 197, 47, 88, 224, 255, 255, 255, 255, 198, 77, 124, 112,
255, 255, 255, 255, 199, 15, 58, 224, 255, 255, 255, 255, 200, 45, 94, 112,
255, 255, 255, 255, 200, 248, 87, 96, 255, 255, 255, 255, 202, 13, 64, 112,
255, 255, 255, 255, 202, 216, 57, 96, 255, 255, 255, 255, 203, 136, 240, 112,
255, 255, 255, 255, 210, 35, 244, 112, 255, 255, 255, 255, 210, 96, 251, 224,
255, 255, 255, 255, 211, 117, 228, 240, 255, 255, 255, 255, 212, 64, 221, 224,
255, 255, 255, 255, 213, 85, 198, 240, 255, 255, 255, 255, 214, 32, 191, 224,
255, 255, 255, 255, 215, 53, 168, 240, 255, 255, 255, 255, 216, 0, 161, 224,
255, 255, 255, 255, 217, 21, 138, 240, 255, 255, 255, 255, 217, 224, 131, 224,
255, 255, 255, 255, 218, 254, 167, 112, 255, 255, 255, 255, 219, 192, 101, 224,
255, 255, 255, 255, 220, 222, 137, 112, 255, 255, 255, 255, 221, 169, 130, 96,
255, 255, 255, 255, 222, 190, 107, 112, 255, 255, 255, 255, 223, 137, 100, 96,
255, 255, 255, 255, 224, 158, 77, 112, 255, 255, 255, 255, 225, 105, 70, 96,
255, 255, 255, 255, 226, 126, 47, 112, 255, 255, 255, 255, 227, 73, 40, 96,
255, 255, 255, 255, 228, 94, 17, 112, 255, 255, 255, 255, 229, 87, 46, 224,
255, 255, 255, 255, 230, 71, 45, 240, 255, 255, 255, 255, 231, 55, 16, 224,
255, 255, 255, 255, 232, 39, 15, 240, 255, 255, 255, 255, 233, 22, 242, 224,
255, 255, 255, 255, 234, 6, 241, 240, 255, 255, 255, 255, 234, 246, 212, 224,
255, 255, 255, 255, 235, 230, 211, 240, 255, 255, 255, 255, 236, 214, 182, 224,
255, 255, 255, 255, 237, 198, 181, 240, 255, 255, 255, 255, 238, 191, 211, 96,
255, 255, 255, 255, 239, 175, 210, 112, 255, 255, 255, 255, 240, 159, 181, 96,
255, 255, 255, 255, 241, 143, 180, 112, 255, 255, 255, 255, 242, 127, 151, 96,
255, 255, 255, 255, 243, 111, 150, 112, 255, 255, 255, 255, 244, 95, 121, 96,
255, 255, 255, 255, 245, 79, 120, 112, 255, 255, 255, 255, 246, 63, 91, 96,
255, 255, 255, 255, 247, 47, 90, 112, 255, 255, 255, 255, 248, 40, 119, 224,
255, 255, 255, 255, 249, 15, 60, 112, 255, 255, 255, 255, 250, 8, 89, 224,
255, 255, 255, 255, 250, 248, 88, 240, 255, 255, 255, 255, 251, 232, 59, 224,
255, 255, 255, 255, 252, 216, 58, 240, 255, 255, 255, 255, 253, 200, 29, 224,
255, 255, 255, 255, 254, 184, 28, 240, 255, 255, 255, 255, 255, 167, 255, 224,
0, 0, 0, 0, 0, 151, 254, 240, 0, 0, 0, 0, 1, 135, 225, 224,
0, 0, 0, 0, 2, 119, 224, 240, 0, 0, 0, 0, 3, 112, 254, 96,
0, 0, 0, 0, 4, 96, 253, 112, 0, 0, 0, 0, 5, 80, 224, 96,
0, 0, 0, 0, 6, 64, 223, 112, 0, 0, 0, 0, 7, 48, 194, 96,
0, 0, 0, 0, 7, 141, 25, 112, 0, 0, 0, 0, 9, 16, 164, 96,
0, 0, 0, 0, 9, 173, 148, 240, 0, 0, 0, 0, 10, 240, 134, 96,
0, 0, 0, 0, 11, 224, 133, 112, 0, 0, 0, 0, 12, 217, 162, 224,
0, 0, 0, 0, 13, 192, 103, 112, 0, 0, 0, 0, 14, 185, 132, 224,
0, 0, 0, 0, 15, 169, 131, 240, 0, 0, 0, 0, 16, 153, 102, 224,
0, 0, 0, 0, 17, 137, 101, 240, 0, 0, 0, 0, 18, 121, 72, 224,
0, 0, 0, 0, 19, 105, 71, 240, 0, 0, 0, 0, 20, 89, 42, 224,
0, 0, 0, 0, 21, 73, 41, 240, 0, 0, 0, 0, 22, 57, 12, 224,
0, 0, 0, 0, 23, 41, 11, 240, 0, 0, 0, 0, 24, 34, 41, 96,
0, 0, 0, 0, 25, 8, 237, 240, 0, 0, 0, 0, 26, 2, 11, 96,
0, 0, 0, 0, 26, 242, 10, 112, 0, 0, 0, 0, 27, 225, 237, 96,
0, 0, 0, 0, 28, 209, 236, 112, 0, 0, 0, 0, 29, 193, 207, 96,
0, 0, 0, 0, 30, 177, 206, 112, 0, 0, 0, 0, 31, 161, 177, 96,
0, 0, 0, 0, 32, 118, 0, 240, 0, 0, 0, 0, 33, 129, 147, 96,
0, 0, 0, 0, 34, 85, 226, 240, 0, 0, 0, 0, 35, 106, 175, 224,
0, 0, 0, 0, 36, 53, 196, 240, 0, 0, 0, 0, 37, 74, 145, 224,
0, 0, 0, 0, 38, 21, 166, 240, 0, 0, 0, 0, 39, 42, 115, 224,
0, 0, 0, 0, 39, 254, 195, 112, 0, 0, 0, 0, 41, 10, 85, 224,
0, 0, 0, 0, 41, 222, 165, 112, 0, 0, 0, 0, 42, 234, 55, 224,
0, 0, 0, 0, 43, 190, 135, 112, 0, 0, 0, 0, 44, 211, 84, 96,
0, 0, 0, 0, 45, 158, 105, 112, 0, 0, 0, 0, 46, 179, 54, 96,
0, 0, 0, 0, 47, 126, 75, 112, 0, 0, 0, 0, 48, 147, 24, 96,
0, 0, 0, 0, 49, 103, 103, 240, 0, 0, 0, 0, 50, 114, 250, 96,
0, 0, 0, 0, 51, 71, 73, 240, 0, 0, 0, 0, 52, 82, 220, 96,
0, 0, 0, 0, 53, 39, 43, 240, 0, 0, 0, 0, 54, 50, 190, 96,
0, 0, 0, 0, 55, 7, 13, 240, 0, 0, 0, 0, 56, 27, 218, 224,
0, 0, 0, 0, 56, 230, 239, 240, 0, 0, 0, 0, 57, 251, 188, 224,
0, 0, 0, 0, 58, 198, 209, 240, 0, 0, 0, 0, 59, 219, 158, 224,
0, 0, 0, 0, 60, 175, 238, 112, 0, 0, 0, 0, 61, 187, 128, 224,
0, 0, 0, 0, 62, 143, 208, 112, 0, 0, 0, 0, 63, 155, 98, 224,
0, 0, 0, 0, 64, 111, 178, 112, 0, 0, 0, 0, 65, 132, 127, 96,
0, 0, 0, 0, 66, 79, 148, 112, 0, 0, 0, 0, 67, 100, 97, 96,
0, 0, 0, 0, 68, 47, 118, 112, 0, 0, 0, 0, 69, 68, 67, 96,
0, 0, 0, 0, 69, 243, 168, 240, 0, 0, 0, 0, 71, 45, 95, 224,
0, 0, 0, 0, 71, 211, 138, 240, 0, 0, 0, 0, 73, 13, 65, 224,
0, 0, 0, 0, 73, 179, 108, 240, 0, 0, 0, 0, 74, 237, 35, 224,
0, 0, 0, 0, 75, 156, 137, 112, 0, 0, 0, 0, 76, 214, 64, 96,
0, 0, 0, 0, 77, 124, 107, 112, 0, 0, 0, 0, 78, 182, 34, 96,
0, 0, 0, 0, 79, 92, 77, 112, 0, 0, 0, 0, 80, 150, 4, 96,
0, 0, 0, 0, 81, 60, 47, 112, 0, 0, 0, 0, 82, 117, 230, 96,
0, 0, 0, 0, 83, 28, 17, 112, 0, 0, 0, 0, 84, 85, 200, 96,
0, 0, 0, 0, 84, 251, 243, 112, 0, 0, 0, 0, 86, 53, 170, 96,
0, 0, 0, 0, 86, 229, 15, 240, 0, 0, 0, 0, 88, 30, 198, 224,
0, 0, 0, 0, 88, 196, 241, 240, 0, 0, 0, 0, 89, 254, 168, 224,
0, 0, 0, 0, 90, 164, 211, 240, 0, 0, 0, 0, 91, 222, 138, 224,
0, 0, 0, 0, 92, 132, 181, 240, 0, 0, 0, 0, 93, 190, 108, 224,
0, 0, 0, 0, 94, 100, 151, 240, 0, 0, 0, 0, 95, 158, 78, 224,
0, 0, 0, 0, 96, 77, 180, 112, 0, 0, 0, 0, 97, 135, 107, 96,
0, 0, 0, 0, 98, 45, 150, 112, 0, 0, 0, 0, 99, 103, 77, 96,
0, 0, 0, 0, 100, 13, 120, 112, 0, 0, 0, 0, 101, 71, 47, 96,
0, 0, 0, 0, 101, 237, 90, 112, 0, 0, 0, 0, 103, 39, 17, 96,
0, 0, 0, 0, 103, 205, 60, 112, 0, 0, 0, 0, 105, 6, 243, 96,
0, 0, 0, 0, 105, 173, 30, 112, 0, 0, 0, 0, 106, 230, 213, 96,
0, 0, 0, 0, 107, 150, 58, 240, 0, 0, 0, 0, 108, 207, 241, 224,
0, 0, 0, 0, 109, 118, 28, 240, 0, 0, 0, 0, 110, 175, 211, 224,
0, 0, 0, 0, 111, 85, 254, 240, 0, 0, 0, 0, 112, 143, 181, 224,
0, 0, 0, 0, 113, 53, 224, 240, 0, 0, 0, 0, 114, 111, 151, 224,
0, 0, 0, 0, 115, 21, 194, 240, 0, 0, 0, 0, 116, 79, 121, 224,
0, 0, 0, 0, 116, 254, 223, 112, 0, 0, 0, 0, 118, 56, 150, 96,
0, 0, 0, 0, 118, 222, 193, 112, 0, 0, 0, 0, 120, 24, 120, 96,
0, 0, 0, 0, 120, 190, 163, 112, 0, 0, 0, 0, 121, 248, 90, 96,
0, 0, 0, 0, 122, 158, 133, 112, 0, 0, 0, 0, 123, 216, 60, 96,
0, 0, 0, 0, 124, 126, 103, 112, 0, 0, 0, 0, 125, 184, 30, 96,
0, 0, 0, 0, 126, 94, 73, 112, 0, 0, 0, 0, 127, 152, 0, 96,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 3, 4, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 255, 255, 186, 158,
0, 0, 255, 255, 199, 192, 1, 4, 255, 255, 185, 176, 0, 8, 255, 255,
199, 192, 1, 12, 255, 255, 199, 192, 1, 16, 76, 77, 84, 0, 69, 68,
84, 0, 69, 83, 84, 0, 69, 87, 84, 0, 69, 80, 84, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 10, 69, 83, 84, 53, 69, 68, 84,
44, 77, 51, 46, 50, 46, 48, 44, 77, 49, 49, 46, 49, 46, 48, 10,
};